X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fkmod-setup.c;h=debf87130db4c1a877797944292a120b6d2cff9d;hp=fa856c9a6ccc6ceb4447958a85bb2444a2ebe24a;hb=b47ffcfdfd46de119e0fe8d1c48105bd7c21ddd4;hpb=11c3a4eeb7e65eccd6fc0870bb1cda315fa33ba5 diff --git a/src/kmod-setup.c b/src/kmod-setup.c index fa856c9a6..debf87130 100644 --- a/src/kmod-setup.c +++ b/src/kmod-setup.c @@ -1,4 +1,4 @@ -/*-*- Mode: C; c-basic-offset: 8 -*-*/ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ /*** This file is part of systemd. @@ -23,6 +23,7 @@ #include #include #include +#include #include "macro.h" #include "execute.h" @@ -31,77 +32,65 @@ static const char * const kmod_table[] = { "autofs4", "/sys/class/misc/autofs", - "ipv6", "/sys/module/ipv6" + "ipv6", "/sys/module/ipv6", + "unix", "/proc/net/unix" }; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +static void systemd_kmod_log(void *data, int priority, const char *file, int line, + const char *fn, const char *format, va_list args) +{ + log_meta(priority, file, line, fn, format, args); +} +#pragma GCC diagnostic pop + int kmod_setup(void) { - unsigned i, n = 0; - const char * cmdline[3 + ELEMENTSOF(kmod_table) + 1]; - ExecCommand command; - ExecContext context; - pid_t pid; - int status, r; + unsigned i; + struct kmod_ctx *ctx = NULL; + struct kmod_module *mod; + int err; for (i = 0; i < ELEMENTSOF(kmod_table); i += 2) { if (access(kmod_table[i+1], F_OK) >= 0) continue; - log_info("Your kernel apparently lacks built-in %s support. Please fix that. " - "We'll now try to work around this by calling '/sbin/modprobe %s'...", - kmod_table[i], kmod_table[i]); - - cmdline[3 + n++] = kmod_table[i]; - } - - if (n <= 0) - return 0; - - cmdline[0] = "/sbin/modprobe"; - cmdline[1] = "-qab"; - cmdline[2] = "--"; - cmdline[3 + n] = NULL; - - zero(command); - zero(context); - - command.path = (char*) cmdline[0]; - command.argv = (char**) cmdline; + log_debug("Your kernel apparently lacks built-in %s support. Might be a good idea to compile it in. " + "We'll now try to work around this by loading the module...", + kmod_table[i]); - exec_context_init(&context); - r = exec_spawn(&command, NULL, &context, NULL, 0, NULL, false, false, false, NULL, &pid); - exec_context_done(&context); + if (!ctx) { + ctx = kmod_new(NULL, NULL); + if (!ctx) { + log_error("Failed to allocate memory for kmod"); + return -ENOMEM; + } - if (r < 0) - return r; + kmod_set_log_fn(ctx, systemd_kmod_log, NULL); - for (;;) { - if (waitpid(pid, &status, 0) < 0) { - - if (errno == EINTR) - continue; - - return -errno; + kmod_load_resources(ctx); } - break; - } - - if (WIFEXITED(status)) { - if (WEXITSTATUS(status) != 0) { - log_warning("/sbin/modprobe failed with error code %i.", WEXITSTATUS(status)); - return -EPROTO; + err = kmod_module_new_from_name(ctx, kmod_table[i], &mod); + if (err < 0) { + log_error("Failed to load module '%s'", kmod_table[i]); + continue; } - log_debug("/sbin/modprobe succeeded."); - return 0; - } + err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL); + if (err == 0) + log_info("Inserted module '%s'", kmod_module_get_name(mod)); + else if (err == KMOD_PROBE_APPLY_BLACKLIST) + log_info("Module '%s' is blacklisted", kmod_module_get_name(mod)); + else + log_error("Failed to insert '%s'", kmod_module_get_name(mod)); - if (WIFSIGNALED(status)) { - log_warning("/sbin/modprobe terminated by signal %s.", strsignal(WTERMSIG(status))); - return -EPROTO; + kmod_module_unref(mod); } - log_warning("/sbin/modprobe failed due to unknown reason."); - return -EPROTO; + if (ctx) + kmod_unref(ctx); + + return 0; }