X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=udev%2Fudev-builtin-kmod.c;h=a5c76fc214d21c15ece146233020dcf8b95deddf;hb=fe6784cfd49f864211bddd1ef161125122c1fb18;hp=df057735d786105b526521fc7e1b6bf92ecfe77b;hpb=81dadce58f80edae4dc45ba55a2c41cb0f26570b;p=elogind.git diff --git a/udev/udev-builtin-kmod.c b/udev/udev-builtin-kmod.c index df057735d..a5c76fc21 100644 --- a/udev/udev-builtin-kmod.c +++ b/udev/udev-builtin-kmod.c @@ -1,7 +1,8 @@ /* - * probe disks for filesystems and partitions + * load kernel modules * * Copyright (C) 2011 Kay Sievers + * Copyright (C) 2011 ProFUSION embedded systems * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,18 +26,119 @@ #include #include #include +#include +#include #include "udev.h" -static int builtin_kmod(struct udev_device *dev, const char *command, bool test) +static struct kmod_ctx *ctx; + +static int load_module(struct udev *udev, const char *alias) { - printf("soon we load a module here: '%s'\n", command); + struct kmod_list *list = NULL; + struct kmod_list *listb = NULL; + struct kmod_list *l; + int err; + + err = kmod_module_new_from_lookup(ctx, alias, &list); + if (err < 0) + return err; + + err = kmod_module_get_filtered_blacklist(ctx, list, &listb); + if (err < 0) + return err; + + if (list == NULL) + info(udev, "no module matches '%s'\n", alias); + + kmod_list_foreach(l, listb) { + struct kmod_module *mod = kmod_module_get_module(l); + + err = kmod_module_probe_insert_module(mod, 0, NULL, NULL, NULL); + if (err >=0 ) + info(udev, "inserted '%s'\n", kmod_module_get_name(mod)); + else + info(udev, "failed to insert '%s'\n", kmod_module_get_name(mod)); + + kmod_module_unref(mod); + } + + kmod_module_unref_list(list); + kmod_module_unref_list(listb); + return err; +} + +static void udev_kmod_log(void *data, int priority, const char *file, int line, + const char *fn, const char *format, va_list args) +{ + udev_main_log(data, priority, file, line, fn, format, args); +} + +/* needs to re-instantiate the context after a reload */ +static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test) +{ + struct udev *udev = udev_device_get_udev(dev); + int i; + + if (!ctx) { + ctx = kmod_new(NULL, NULL); + if (!ctx) + return -ENOMEM; + + info(udev, "load module index\n"); + kmod_set_log_fn(ctx, udev_kmod_log, udev); + kmod_load_resources(ctx); + } + + if (argc < 3 || strcmp(argv[1], "load")) { + err(udev, "expect: %s load \n", argv[0]); + return EXIT_FAILURE; + } + + for (i = 2; argv[i]; i++) { + info(udev, "execute '%s' '%s'\n", argv[1], argv[i]); + load_module(udev, argv[i]); + } + return EXIT_SUCCESS; } +/* called at udev startup */ +static int builtin_kmod_init(struct udev *udev) +{ + if (ctx) + return 0; + + ctx = kmod_new(NULL, NULL); + if (!ctx) + return -ENOMEM; + + info(udev, "load module index\n"); + kmod_set_log_fn(ctx, udev_kmod_log, udev); + kmod_load_resources(ctx); + return 0; +} + +/* called on udev shutdown and reload request */ +static void builtin_kmod_exit(struct udev *udev) +{ + ctx = kmod_unref(ctx); + info(udev, "unload module index\n"); +} + +/* called every couple of seconds during event activity; 'true' if config has changed */ +static bool builtin_kmod_validate(struct udev *udev) +{ + info(udev, "validate module index\n"); + return false; +} + const struct udev_builtin udev_builtin_kmod = { .name = "kmod", .cmd = builtin_kmod, + .init = builtin_kmod_init, + .exit = builtin_kmod_exit, + .validate = builtin_kmod_validate, .help = "kernel module loader", .run_once = false, };