#include "kmod-setup.h"
-static const char * const kmod_table[] = {
- "autofs4", "/sys/class/misc/autofs",
- "ipv6", "/sys/module/ipv6",
- "efivarfs", "/sys/firmware/efi/efivars",
- "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_metav(priority, file, line, fn, format, args);
+
+static void systemd_kmod_log(
+ void *data,
+ int priority,
+ const char *file, int line,
+ const char *fn,
+ const char *format,
+ va_list args) {
+
+ /* library logging is enabled at debug only */
+ log_metav(LOG_DEBUG, file, line, fn, format, args);
}
+
#pragma GCC diagnostic pop
+static bool cmdline_check_kdbus(void) {
+ _cleanup_free_ char *line = NULL;
+
+ if (proc_cmdline(&line) <= 0)
+ return false;
+
+ return strstr(line, "kdbus") != NULL;
+}
+
int kmod_setup(void) {
- unsigned i;
+ static const struct {
+ const char *module;
+ const char *path;
+ bool warn;
+ bool (*condition_fn)(void);
+ } kmod_table[] = {
+ /* auto-loading on use doesn't work before udev is up */
+ { "autofs4", "/sys/class/misc/autofs", true, NULL },
+
+ /* early configure of ::1 on the loopback device */
+ { "ipv6", "/sys/module/ipv6", true, NULL },
+
+ /* this should never be a module */
+ { "unix", "/proc/net/unix", true, NULL },
+
+ /* IPC is needed before we bring up any other services */
+ { "kdbus", "/sys/bus/kdbus", false, cmdline_check_kdbus },
+ };
struct kmod_ctx *ctx = NULL;
- struct kmod_module *mod;
- int err;
+ unsigned int i;
+ int r;
- for (i = 0; i < ELEMENTSOF(kmod_table); i += 2) {
+ for (i = 0; i < ELEMENTSOF(kmod_table); i++) {
+ struct kmod_module *mod;
- if (access(kmod_table[i+1], F_OK) >= 0)
+ if (kmod_table[i].path && access(kmod_table[i].path, F_OK) >= 0)
continue;
- 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]);
+ if (kmod_table[i].condition_fn && !kmod_table[i].condition_fn())
+ continue;
+
+ if (kmod_table[i].warn)
+ 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].module);
if (!ctx) {
ctx = kmod_new(NULL, NULL);
- if (!ctx) {
- log_error("Failed to allocate memory for kmod");
- return -ENOMEM;
- }
+ if (!ctx)
+ return log_oom();
kmod_set_log_fn(ctx, systemd_kmod_log, NULL);
-
kmod_load_resources(ctx);
}
- err = kmod_module_new_from_name(ctx, kmod_table[i], &mod);
- if (err < 0) {
- log_error("Failed to load module '%s'", kmod_table[i]);
+ r = kmod_module_new_from_name(ctx, kmod_table[i].module, &mod);
+ if (r < 0) {
+ log_error("Failed to lookup module '%s'", kmod_table[i].module);
continue;
}
- err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL);
- if (err == 0)
+ r = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL);
+ if (r == 0)
log_info("Inserted module '%s'", kmod_module_get_name(mod));
- else if (err == KMOD_PROBE_APPLY_BLACKLIST)
+ else if (r == 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));
+ else if (kmod_table[i].warn)
+ log_error("Failed to insert module '%s'", kmod_module_get_name(mod));
kmod_module_unref(mod);
}