From: Lennart Poettering Date: Tue, 30 Jan 2024 13:50:35 +0000 (+0100) Subject: libkmod: turn into dlopen() dependency X-Git-Tag: v256-rc1~289^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1d98716ef7fef3abc078a2cee3156985b8562383;p=thirdparty%2Fsystemd.git libkmod: turn into dlopen() dependency As it turns out libkmod has quite a bunch of deps, including various compressing libs and similar. By turning this into a dlopen() dependency, we can make our depchain during install time quite a bit smaller. In particular as inside of containers kmod doesn't help anyway as CAP_SYS_MODULE is not available anyway. While we are at it, also share the code that sets up logging/kmod context. After: $ lddtree ./build/systemd systemd => ./build/systemd (interpreter => /lib64/ld-linux-x86-64.so.2) libsystemd-core-255.so => ./build/src/core/libsystemd-core-255.so libaudit.so.1 => /lib64/libaudit.so.1 libcap-ng.so.0 => /lib64/libcap-ng.so.0 ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 libm.so.6 => /lib64/libm.so.6 libmount.so.1 => /lib64/libmount.so.1 libblkid.so.1 => /lib64/libblkid.so.1 libseccomp.so.2 => /lib64/libseccomp.so.2 libselinux.so.1 => /lib64/libselinux.so.1 libpcre2-8.so.0 => /lib64/libpcre2-8.so.0 libsystemd-shared-255.so => /home/lennart/projects/systemd/build/src/shared/libsystemd-shared-255.so libacl.so.1 => /lib64/libacl.so.1 libattr.so.1 => /lib64/libattr.so.1 libcap.so.2 => /lib64/libcap.so.2 libcrypt.so.2 => /lib64/libcrypt.so.2 libgcrypt.so.20 => /lib64/libgcrypt.so.20 libgpg-error.so.0 => /lib64/libgpg-error.so.0 liblz4.so.1 => /lib64/liblz4.so.1 libcrypto.so.3 => /lib64/libcrypto.so.3 libz.so.1 => /lib64/libz.so.1 libpam.so.0 => /lib64/libpam.so.0 libeconf.so.0 => /lib64/libeconf.so.0 liblzma.so.5 => /lib64/liblzma.so.5 libzstd.so.1 => /lib64/libzstd.so.1 libc.so.6 => /lib64/libc.so.6 Before: $ lddtree ./build/systemd systemd => ./build/systemd (interpreter => /lib64/ld-linux-x86-64.so.2) libsystemd-core-255.so => ./build/src/core/libsystemd-core-255.so libaudit.so.1 => /lib64/libaudit.so.1 libcap-ng.so.0 => /lib64/libcap-ng.so.0 ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 libkmod.so.2 => /lib64/libkmod.so.2 libzstd.so.1 => /lib64/libzstd.so.1 liblzma.so.5 => /lib64/liblzma.so.5 libz.so.1 => /lib64/libz.so.1 libcrypto.so.3 => /lib64/libcrypto.so.3 libgcc_s.so.1 => /lib64/libgcc_s.so.1 libm.so.6 => /lib64/libm.so.6 libmount.so.1 => /lib64/libmount.so.1 libblkid.so.1 => /lib64/libblkid.so.1 libseccomp.so.2 => /lib64/libseccomp.so.2 libselinux.so.1 => /lib64/libselinux.so.1 libpcre2-8.so.0 => /lib64/libpcre2-8.so.0 libsystemd-shared-255.so => /home/lennart/projects/systemd/build/src/shared/libsystemd-shared-255.so libacl.so.1 => /lib64/libacl.so.1 libattr.so.1 => /lib64/libattr.so.1 libcap.so.2 => /lib64/libcap.so.2 libcrypt.so.2 => /lib64/libcrypt.so.2 libgcrypt.so.20 => /lib64/libgcrypt.so.20 libgpg-error.so.0 => /lib64/libgpg-error.so.0 liblz4.so.1 => /lib64/liblz4.so.1 libpam.so.0 => /lib64/libpam.so.0 libeconf.so.0 => /lib64/libeconf.so.0 libc.so.6 => /lib64/libc.so.6 --- diff --git a/meson.build b/meson.build index f4b382c6023..ad0a122c8f5 100644 --- a/meson.build +++ b/meson.build @@ -1209,6 +1209,7 @@ libkmod = dependency('libkmod', version : '>= 15', required : get_option('kmod')) conf.set10('HAVE_KMOD', libkmod.found()) +libkmod_cflags = libkmod.partial_dependency(includes: true, compile_args: true) libxenctrl = dependency('xencontrol', version : '>= 4.9', diff --git a/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf b/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf index 2b14a6db0af..06f3d213656 100644 --- a/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf +++ b/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf @@ -37,7 +37,9 @@ Packages= grep gzip kernel-kvmsmall + kmod libasan8 + libkmod2 libubsan1 openssh-clients openssh-server @@ -55,4 +57,6 @@ Packages= InitrdPackages= btrfs-progs + kmod + libkmod2 tpm2.0-tools diff --git a/src/core/kmod-setup.c b/src/core/kmod-setup.c index f4801318dea..3f8f7e3bca5 100644 --- a/src/core/kmod-setup.c +++ b/src/core/kmod-setup.c @@ -9,28 +9,13 @@ #include "fileio.h" #include "kmod-setup.h" #include "macro.h" +#include "module-util.h" #include "recurse-dir.h" #include "string-util.h" #include "strv.h" #include "virt.h" #if HAVE_KMOD -#include "module-util.h" - -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 */ - DISABLE_WARNING_FORMAT_NONLITERAL; - log_internalv(LOG_DEBUG, 0, file, line, fn, format, args); - REENABLE_WARNING; -} - static int match_modalias_recurse_dir_cb( RecurseDirEvent event, const char *path, @@ -166,11 +151,12 @@ int kmod_setup(void) { #endif }; + int r; + if (have_effective_cap(CAP_SYS_MODULE) <= 0) return 0; - _cleanup_(kmod_unrefp) struct kmod_ctx *ctx = NULL; - + _cleanup_(sym_kmod_unrefp) struct kmod_ctx *ctx = NULL; FOREACH_ARRAY(kmod, kmod_table, ELEMENTSOF(kmod_table)) { if (kmod->path && access(kmod->path, F_OK) >= 0) continue; @@ -184,12 +170,9 @@ int kmod_setup(void) { "this by loading the module...", kmod->module); if (!ctx) { - ctx = kmod_new(NULL, NULL); - if (!ctx) - return log_oom(); - - kmod_set_log_fn(ctx, systemd_kmod_log, NULL); - kmod_load_resources(ctx); + r = module_setup_context(&ctx); + if (r < 0) + return log_error_errno(r, "Failed to initialize kmod context: %m"); } (void) module_load_and_warn(ctx, kmod->module, kmod->warn_if_unavailable); diff --git a/src/core/meson.build b/src/core/meson.build index bda4a3450eb..06ca1449549 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -125,7 +125,7 @@ libcore = shared_library( libaudit, libblkid, libdl, - libkmod, + libkmod_cflags, libm, libmount, libpam, diff --git a/src/modules-load/meson.build b/src/modules-load/meson.build index 2f1decc8b77..d6375a63a32 100644 --- a/src/modules-load/meson.build +++ b/src/modules-load/meson.build @@ -5,7 +5,7 @@ executables += [ 'name' : 'systemd-modules-load', 'conditions' : ['HAVE_KMOD'], 'sources' : files('modules-load.c'), - 'dependencies' : libkmod, + 'dependencies' : libkmod_cflags, }, ] diff --git a/src/modules-load/modules-load.c b/src/modules-load/modules-load.c index da7e3d89005..c1f818320ff 100644 --- a/src/modules-load/modules-load.c +++ b/src/modules-load/modules-load.c @@ -23,14 +23,6 @@ static const char conf_file_dirs[] = CONF_PATHS_NULSTR("modules-load.d"); STATIC_DESTRUCTOR_REGISTER(arg_proc_cmdline_modules, strv_freep); -static void systemd_kmod_log(void *data, int priority, const char *file, int line, - const char *fn, const char *format, va_list args) { - - DISABLE_WARNING_FORMAT_NONLITERAL; - log_internalv(priority, 0, file, line, fn, format, args); - REENABLE_WARNING; -} - static int add_modules(const char *p) { _cleanup_strv_free_ char **k = NULL; @@ -156,7 +148,7 @@ static int parse_argv(int argc, char *argv[]) { } static int run(int argc, char *argv[]) { - _cleanup_(kmod_unrefp) struct kmod_ctx *ctx = NULL; + _cleanup_(sym_kmod_unrefp) struct kmod_ctx *ctx = NULL; int r, k; r = parse_argv(argc, argv); @@ -171,12 +163,9 @@ static int run(int argc, char *argv[]) { if (r < 0) log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m"); - ctx = kmod_new(NULL, NULL); - if (!ctx) - return log_oom(); - - kmod_load_resources(ctx); - kmod_set_log_fn(ctx, systemd_kmod_log, NULL); + r = module_setup_context(&ctx); + if (r < 0) + return log_error_errno(r, "Failed to initialize libkmod context: %m"); r = 0; diff --git a/src/shared/meson.build b/src/shared/meson.build index 4c9b45434e0..71db6d8694a 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -118,6 +118,7 @@ shared_sources = files( 'macvlan-util.c', 'mkdir-label.c', 'mkfs-util.c', + 'module-util.c', 'mount-setup.c', 'mount-util.c', 'net-condition.c', @@ -236,10 +237,6 @@ if conf.get('HAVE_LIBBPF') == 1 shared_sources += files('bpf-link.c') endif -if conf.get('HAVE_KMOD') == 1 - shared_sources += files('module-util.c') -endif - if conf.get('HAVE_PAM') == 1 shared_sources += files('pam-util.c') endif @@ -324,7 +321,7 @@ libshared_deps = [threads, libdl, libgcrypt, libiptc_cflags, - libkmod, + libkmod_cflags, liblz4_cflags, libmount, libopenssl, diff --git a/src/shared/module-util.c b/src/shared/module-util.c index 907990d96e4..612ab9c9c5f 100644 --- a/src/shared/module-util.c +++ b/src/shared/module-util.c @@ -6,6 +6,44 @@ #include "proc-cmdline.h" #include "strv.h" +#if HAVE_KMOD + +static void *libkmod_dl = NULL; + +DLSYM_FUNCTION(kmod_list_next); +DLSYM_FUNCTION(kmod_load_resources); +DLSYM_FUNCTION(kmod_module_get_initstate); +DLSYM_FUNCTION(kmod_module_get_module); +DLSYM_FUNCTION(kmod_module_get_name); +DLSYM_FUNCTION(kmod_module_new_from_lookup); +DLSYM_FUNCTION(kmod_module_probe_insert_module); +DLSYM_FUNCTION(kmod_module_unref); +DLSYM_FUNCTION(kmod_module_unref_list); +DLSYM_FUNCTION(kmod_new); +DLSYM_FUNCTION(kmod_set_log_fn); +DLSYM_FUNCTION(kmod_unref); +DLSYM_FUNCTION(kmod_validate_resources); + +int dlopen_libkmod(void) { + return dlopen_many_sym_or_warn( + &libkmod_dl, + "libkmod.so.2", + LOG_DEBUG, + DLSYM_ARG(kmod_list_next), + DLSYM_ARG(kmod_load_resources), + DLSYM_ARG(kmod_module_get_initstate), + DLSYM_ARG(kmod_module_get_module), + DLSYM_ARG(kmod_module_get_name), + DLSYM_ARG(kmod_module_new_from_lookup), + DLSYM_ARG(kmod_module_probe_insert_module), + DLSYM_ARG(kmod_module_unref), + DLSYM_ARG(kmod_module_unref_list), + DLSYM_ARG(kmod_new), + DLSYM_ARG(kmod_set_log_fn), + DLSYM_ARG(kmod_unref), + DLSYM_ARG(kmod_validate_resources)); +} + static int denylist_modules(const char *p, char ***denylist) { _cleanup_strv_free_ char **k = NULL; int r; @@ -41,19 +79,21 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat } int module_load_and_warn(struct kmod_ctx *ctx, const char *module, bool verbose) { - const int probe_flags = KMOD_PROBE_APPLY_BLACKLIST; - struct kmod_list *itr; - _cleanup_(kmod_module_unref_listp) struct kmod_list *modlist = NULL; + _cleanup_(sym_kmod_module_unref_listp) struct kmod_list *modlist = NULL; _cleanup_strv_free_ char **denylist = NULL; bool denylist_parsed = false; + struct kmod_list *itr; int r; + assert(ctx); + assert(module); + /* verbose==true means we should log at non-debug level if we * fail to find or load the module. */ log_debug("Loading module: %s", module); - r = kmod_module_new_from_lookup(ctx, module, &modlist); + r = sym_kmod_module_new_from_lookup(ctx, module, &modlist); if (r < 0) return log_full_errno(verbose ? LOG_ERR : LOG_DEBUG, r, "Failed to look up module alias '%s': %m", module); @@ -63,32 +103,37 @@ int module_load_and_warn(struct kmod_ctx *ctx, const char *module, bool verbose) SYNTHETIC_ERRNO(ENOENT), "Failed to find module '%s'", module); - kmod_list_foreach(itr, modlist) { - _cleanup_(kmod_module_unrefp) struct kmod_module *mod = NULL; + sym_kmod_list_foreach(itr, modlist) { + _cleanup_(sym_kmod_module_unrefp) struct kmod_module *mod = NULL; int state, err; - mod = kmod_module_get_module(itr); - state = kmod_module_get_initstate(mod); + mod = sym_kmod_module_get_module(itr); + state = sym_kmod_module_get_initstate(mod); switch (state) { case KMOD_MODULE_BUILTIN: log_full(verbose ? LOG_INFO : LOG_DEBUG, - "Module '%s' is built in", kmod_module_get_name(mod)); + "Module '%s' is built in", sym_kmod_module_get_name(mod)); break; case KMOD_MODULE_LIVE: - log_debug("Module '%s' is already loaded", kmod_module_get_name(mod)); + log_debug("Module '%s' is already loaded", sym_kmod_module_get_name(mod)); break; default: - err = kmod_module_probe_insert_module(mod, probe_flags, - NULL, NULL, NULL, NULL); + err = sym_kmod_module_probe_insert_module( + mod, + KMOD_PROBE_APPLY_BLACKLIST, + /* extra_options= */ NULL, + /* run_install= */ NULL, + /* data= */ NULL, + /* print_action= */ NULL); if (err == 0) log_full(verbose ? LOG_INFO : LOG_DEBUG, - "Inserted module '%s'", kmod_module_get_name(mod)); + "Inserted module '%s'", sym_kmod_module_get_name(mod)); else if (err == KMOD_PROBE_APPLY_BLACKLIST) log_full(verbose ? LOG_INFO : LOG_DEBUG, - "Module '%s' is deny-listed (by kmod)", kmod_module_get_name(mod)); + "Module '%s' is deny-listed (by kmod)", sym_kmod_module_get_name(mod)); else { assert(err < 0); @@ -102,9 +147,9 @@ int module_load_and_warn(struct kmod_ctx *ctx, const char *module, bool verbose) denylist_parsed = true; } - if (strv_contains(denylist, kmod_module_get_name(mod))) { + if (strv_contains(denylist, sym_kmod_module_get_name(mod))) { log_full(verbose ? LOG_INFO : LOG_DEBUG, - "Module '%s' is deny-listed (by kernel)", kmod_module_get_name(mod)); + "Module '%s' is deny-listed (by kernel)", sym_kmod_module_get_name(mod)); continue; } } @@ -115,7 +160,7 @@ int module_load_and_warn(struct kmod_ctx *ctx, const char *module, bool verbose) LOG_ERR, err, "Failed to insert module '%s': %m", - kmod_module_get_name(mod)); + sym_kmod_module_get_name(mod)); if (!IN_SET(err, -ENODEV, -ENOENT)) r = err; } @@ -124,3 +169,38 @@ int module_load_and_warn(struct kmod_ctx *ctx, const char *module, bool verbose) return r; } + +_printf_(6,0) static void systemd_kmod_log( + void *data, + int priority, + const char *file, + int line, + const char *fn, + const char *format, + va_list args) { + + log_internalv(priority, 0, file, line, fn, format, args); +} + +int module_setup_context(struct kmod_ctx **ret) { + _cleanup_(sym_kmod_unrefp) struct kmod_ctx *ctx = NULL; + int r; + + assert(ret); + + r = dlopen_libkmod(); + if (r < 0) + return r; + + ctx = sym_kmod_new(NULL, NULL); + if (!ctx) + return -ENOMEM; + + (void) sym_kmod_load_resources(ctx); + sym_kmod_set_log_fn(ctx, systemd_kmod_log, NULL); + + *ret = TAKE_PTR(ctx); + return 0; +} + +#endif diff --git a/src/shared/module-util.h b/src/shared/module-util.h index 8ca6a06a070..081973802b1 100644 --- a/src/shared/module-util.h +++ b/src/shared/module-util.h @@ -1,12 +1,56 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include "dlfcn-util.h" + +#if HAVE_KMOD + #include #include "macro.h" -DEFINE_TRIVIAL_CLEANUP_FUNC(struct kmod_ctx*, kmod_unref); -DEFINE_TRIVIAL_CLEANUP_FUNC(struct kmod_module*, kmod_module_unref); -DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct kmod_list*, kmod_module_unref_list, NULL); +DLSYM_PROTOTYPE(kmod_list_next); +DLSYM_PROTOTYPE(kmod_load_resources); +DLSYM_PROTOTYPE(kmod_module_get_initstate); +DLSYM_PROTOTYPE(kmod_module_get_module); +DLSYM_PROTOTYPE(kmod_module_get_name); +DLSYM_PROTOTYPE(kmod_module_new_from_lookup); +DLSYM_PROTOTYPE(kmod_module_probe_insert_module); +DLSYM_PROTOTYPE(kmod_module_unref); +DLSYM_PROTOTYPE(kmod_module_unref_list); +DLSYM_PROTOTYPE(kmod_new); +DLSYM_PROTOTYPE(kmod_set_log_fn); +DLSYM_PROTOTYPE(kmod_unref); +DLSYM_PROTOTYPE(kmod_validate_resources); + +int dlopen_libkmod(void); + +DEFINE_TRIVIAL_CLEANUP_FUNC(struct kmod_ctx*, sym_kmod_unref); +DEFINE_TRIVIAL_CLEANUP_FUNC(struct kmod_module*, sym_kmod_module_unref); +DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct kmod_list*, sym_kmod_module_unref_list, NULL); + +#define sym_kmod_list_foreach(list_entry, first_entry) \ + for (list_entry = first_entry; \ + list_entry != NULL; \ + list_entry = sym_kmod_list_next(first_entry, list_entry)) int module_load_and_warn(struct kmod_ctx *ctx, const char *module, bool verbose); +int module_setup_context(struct kmod_ctx **ret); + +#else + +struct kmod_ctx; + +static inline int dlopen_libkmod(void) { + return -EOPNOTSUPP; +} + +static inline int module_setup_context(struct kmod_ctx **ret) { + return -EOPNOTSUPP; +} + +static inline int module_load_and_warn(struct kmod_ctx *ctx, const char *module, bool verbose) { + return -EOPNOTSUPP; +} + +#endif diff --git a/src/test/meson.build b/src/test/meson.build index 571d966ca00..6419edda490 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -265,7 +265,10 @@ executables += [ }, test_template + { 'sources' : files('test-dlopen-so.c'), - 'dependencies' : libp11kit_cflags + 'dependencies' : [ + libp11kit_cflags, + libkmod_cflags, + ], }, test_template + { # only static linking apart from libdl, to make sure that the @@ -335,7 +338,7 @@ executables += [ }, test_template + { 'sources' : files('test-netlink-manual.c'), - 'dependencies' : libkmod, + 'dependencies' : libkmod_cflags, 'conditions' : ['HAVE_KMOD'], 'type' : 'manual', }, diff --git a/src/test/test-dlopen-so.c b/src/test/test-dlopen-so.c index 00134c305e5..d38dff182af 100644 --- a/src/test/test-dlopen-so.c +++ b/src/test/test-dlopen-so.c @@ -13,6 +13,7 @@ #include "libfido2-util.h" #include "macro.h" #include "main-func.h" +#include "module-util.h" #include "password-quality-util-passwdqc.h" #include "password-quality-util-pwquality.h" #include "pcre2-util.h" @@ -93,6 +94,10 @@ static int run(int argc, char **argv) { assert_se(initialize_libgcrypt(/* secmem= */ false) >= 0); #endif +#if HAVE_KMOD + assert_se(dlopen_libkmod() >= 0); +#endif + return 0; } diff --git a/src/test/test-netlink-manual.c b/src/test/test-netlink-manual.c index 6543c617c85..73943bf428f 100644 --- a/src/test/test-netlink-manual.c +++ b/src/test/test-netlink-manual.c @@ -13,25 +13,29 @@ #include "tests.h" static int load_module(const char *mod_name) { - _cleanup_(kmod_unrefp) struct kmod_ctx *ctx = NULL; - _cleanup_(kmod_module_unref_listp) struct kmod_list *list = NULL; + _cleanup_(sym_kmod_unrefp) struct kmod_ctx *ctx = NULL; + _cleanup_(sym_kmod_module_unref_listp) struct kmod_list *list = NULL; struct kmod_list *l; int r; - ctx = kmod_new(NULL, NULL); + r = dlopen_libkmod(); + if (r < 0) + return log_error_errno(r, "Failed to load libkmod: %m"); + + ctx = sym_kmod_new(NULL, NULL); if (!ctx) return log_oom(); - r = kmod_module_new_from_lookup(ctx, mod_name, &list); + r = sym_kmod_module_new_from_lookup(ctx, mod_name, &list); if (r < 0) return r; - kmod_list_foreach(l, list) { - _cleanup_(kmod_module_unrefp) struct kmod_module *mod = NULL; + sym_kmod_list_foreach(l, list) { + _cleanup_(sym_kmod_module_unrefp) struct kmod_module *mod = NULL; - mod = kmod_module_get_module(l); + mod = sym_kmod_module_get_module(l); - r = kmod_module_probe_insert_module(mod, 0, NULL, NULL, NULL, NULL); + r = sym_kmod_module_probe_insert_module(mod, 0, NULL, NULL, NULL, NULL); if (r > 0) r = -EINVAL; } diff --git a/src/udev/meson.build b/src/udev/meson.build index e5b52ab6421..3535551e744 100644 --- a/src/udev/meson.build +++ b/src/udev/meson.build @@ -114,7 +114,7 @@ libudevd_core = static_library( include_directories : includes + include_directories('net'), link_with : udev_link_with, dependencies : [libblkid, - libkmod, + libkmod_cflags, userspace], build_by_default : false) diff --git a/src/udev/udev-builtin-kmod.c b/src/udev/udev-builtin-kmod.c index 6d37af88a3a..f4aa4802c95 100644 --- a/src/udev/udev-builtin-kmod.c +++ b/src/udev/udev-builtin-kmod.c @@ -18,10 +18,6 @@ static struct kmod_ctx *ctx = NULL; -_printf_(6,0) static void udev_kmod_log(void *data, int priority, const char *file, int line, const char *fn, const char *format, va_list args) { - log_internalv(priority, 0, file, line, fn, format, args); -} - static int builtin_kmod(UdevEvent *event, int argc, char *argv[]) { sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); int r; @@ -44,7 +40,7 @@ static int builtin_kmod(UdevEvent *event, int argc, char *argv[]) { r = sd_device_get_property_value(dev, "MODALIAS", &modalias); if (r < 0) - return log_device_warning_errno(dev, r, "Failed to read property \"MODALIAS\"."); + return log_device_warning_errno(dev, r, "Failed to read property \"MODALIAS\": %m"); (void) module_load_and_warn(ctx, modalias, /* verbose = */ false); } else @@ -56,23 +52,28 @@ static int builtin_kmod(UdevEvent *event, int argc, char *argv[]) { /* called at udev startup and reload */ static int builtin_kmod_init(void) { + int r; + if (ctx) return 0; - ctx = kmod_new(NULL, NULL); - if (!ctx) - return -ENOMEM; - log_debug("Loading kernel module index."); - kmod_set_log_fn(ctx, udev_kmod_log, NULL); - kmod_load_resources(ctx); + + r = module_setup_context(&ctx); + if (r < 0) + return log_error_errno(r, "Failed to initialize libkmod context: %m"); + return 0; } /* called on udev shutdown and reload request */ static void builtin_kmod_exit(void) { log_debug("Unload kernel module index."); - ctx = kmod_unref(ctx); + + if (!ctx) + return; + + ctx = sym_kmod_unref(ctx); } /* called every couple of seconds during event activity; 'true' if config has changed */ @@ -80,7 +81,7 @@ static bool builtin_kmod_should_reload(void) { if (!ctx) return false; - if (kmod_validate_resources(ctx) != KMOD_RESOURCES_OK) { + if (sym_kmod_validate_resources(ctx) != KMOD_RESOURCES_OK) { log_debug("Kernel module index needs reloading."); return true; } diff --git a/test/test-functions b/test/test-functions index 5d63a41d80d..a09092a5b03 100644 --- a/test/test-functions +++ b/test/test-functions @@ -1555,7 +1555,7 @@ install_missing_libraries() { local lib path # A number of dependencies is now optional via dlopen, so the install # script will not pick them up, since it looks at linkage. - for lib in libcryptsetup libidn libidn2 pwquality libqrencode tss2-esys tss2-rc tss2-mu tss2-tcti-device libfido2 libbpf libelf libdw xkbcommon p11-kit-1 libarchive libgcrypt; do + for lib in libcryptsetup libidn libidn2 pwquality libqrencode tss2-esys tss2-rc tss2-mu tss2-tcti-device libfido2 libbpf libelf libdw xkbcommon p11-kit-1 libarchive libgcrypt libkmod; do ddebug "Searching for $lib via pkg-config" if pkg-config --exists "$lib"; then path="$(pkg-config --variable=libdir "$lib")"