Merge pull request #9516 from keszybz/module-load-unification

Module load unification
This commit is contained in:
Lennart Poettering 2018-07-20 13:55:56 +02:00 committed by GitHub
commit 496a6ba40e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 89 additions and 121 deletions

View File

@ -234,7 +234,7 @@
if there is any. This is primarily intended for operating
systems that rely on community QA.
<varname>PRIVACY_POLICY_URL=</varname> should refer to the
main privacy policy page for the operation system, if there is
main privacy policy page for the operating system, if there is
any. These settings are optional, and providing only some of
these settings is common. These URLs are intended to be
exposed in "About this system" UIs behind links with captions

View File

@ -121,7 +121,6 @@ basic_sources = files('''
mkdir-label.c
mkdir.c
mkdir.h
module-util.h
mount-util.c
mount-util.h
nss-util.h

View File

@ -76,13 +76,15 @@ int kmod_setup(void) {
bool warn_if_module:1;
bool (*condition_fn)(void);
} kmod_table[] = {
/* auto-loading on use doesn't work before udev is up */
/* This one we need to load explicitly, since auto-loading on use doesn't work
* before udev created the ghost device nodes, and we need it earlier than that. */
{ "autofs4", "/sys/class/misc/autofs", true, false, NULL },
/* early configure of ::1 on the loopback device */
/* This one we need to load explicitly, since auto-loading of IPv6 is not done when
* we try to configure ::1 on the loopback device. */
{ "ipv6", "/sys/module/ipv6", false, true, NULL },
/* this should never be a module */
/* This should never be a module */
{ "unix", "/proc/net/unix", true, true, NULL },
#if HAVE_LIBIPTC
@ -94,14 +96,11 @@ int kmod_setup(void) {
};
_cleanup_(kmod_unrefp) struct kmod_ctx *ctx = NULL;
unsigned int i;
int r;
if (have_effective_cap(CAP_SYS_MODULE) == 0)
return 0;
for (i = 0; i < ELEMENTSOF(kmod_table); i++) {
_cleanup_(kmod_module_unrefp) struct kmod_module *mod = NULL;
if (kmod_table[i].path && access(kmod_table[i].path, F_OK) >= 0)
continue;
@ -122,23 +121,7 @@ int kmod_setup(void) {
kmod_load_resources(ctx);
}
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;
}
r = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL);
if (r == 0)
log_debug("Inserted module '%s'", kmod_module_get_name(mod));
else if (r == KMOD_PROBE_APPLY_BLACKLIST)
log_info("Module '%s' is blacklisted", kmod_module_get_name(mod));
else {
bool print_warning = kmod_table[i].warn_if_unavailable || (r < 0 && r != -ENOENT);
log_full_errno(print_warning ? LOG_WARNING : LOG_DEBUG, r,
"Failed to insert module '%s': %m", kmod_module_get_name(mod));
}
(void) module_load_and_warn(ctx, kmod_table[i].module, kmod_table[i].warn_if_unavailable);
}
#endif

View File

@ -59,65 +59,6 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
return 0;
}
static int load_module(struct kmod_ctx *ctx, const char *m) {
const int probe_flags = KMOD_PROBE_APPLY_BLACKLIST;
struct kmod_list *itr;
_cleanup_(kmod_module_unref_listp) struct kmod_list *modlist = NULL;
int r = 0;
log_debug("load: %s", m);
r = kmod_module_new_from_lookup(ctx, m, &modlist);
if (r < 0)
return log_error_errno(r, "Failed to lookup alias '%s': %m", m);
if (!modlist) {
log_error("Failed to find module '%s'", m);
return -ENOENT;
}
kmod_list_foreach(itr, modlist) {
_cleanup_(kmod_module_unrefp) struct kmod_module *mod = NULL;
int state, err;
mod = kmod_module_get_module(itr);
state = kmod_module_get_initstate(mod);
switch (state) {
case KMOD_MODULE_BUILTIN:
log_info("Module '%s' is builtin", kmod_module_get_name(mod));
break;
case KMOD_MODULE_LIVE:
log_debug("Module '%s' is already loaded", kmod_module_get_name(mod));
break;
default:
err = kmod_module_probe_insert_module(mod, probe_flags,
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 {
assert(err < 0);
log_full_errno(err == ENODEV ? LOG_NOTICE :
err == ENOENT ? LOG_WARNING :
LOG_ERR,
err,
"Failed to insert '%s': %m",
kmod_module_get_name(mod));
if (!IN_SET(err, ENODEV, ENOENT))
r = err;
}
}
}
return r;
}
static int apply_file(struct kmod_ctx *ctx, const char *path, bool ignore_enoent) {
_cleanup_fclose_ FILE *f = NULL;
int r;
@ -151,7 +92,7 @@ static int apply_file(struct kmod_ctx *ctx, const char *path, bool ignore_enoent
if (strchr(COMMENTS "\n", *l))
continue;
k = load_module(ctx, l);
k = module_load_and_warn(ctx, l, true);
if (k < 0 && r == 0)
r = k;
}
@ -248,7 +189,7 @@ int main(int argc, char *argv[]) {
char **fn, **i;
STRV_FOREACH(i, arg_proc_cmdline_modules) {
k = load_module(ctx, *i);
k = module_load_and_warn(ctx, *i, true);
if (k < 0 && r == 0)
r = k;
}

View File

@ -63,6 +63,8 @@ shared_sources = files('''
machine-image.h
machine-pool.c
machine-pool.h
module-util.h
module-util.c
nsflags.c
nsflags.h
output-mode.c
@ -132,6 +134,7 @@ libshared_deps = [threads,
libcryptsetup,
libgcrypt,
libiptc,
libkmod,
libseccomp,
libselinux,
libidn,

72
src/shared/module-util.c Normal file
View File

@ -0,0 +1,72 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include <errno.h>
#include "module-util.h"
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;
int r = 0;
/* 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);
if (r < 0)
return log_full_errno(verbose ? LOG_ERR : LOG_DEBUG, r,
"Failed to lookup module alias '%s': %m", module);
if (!modlist) {
log_full_errno(verbose ? LOG_ERR : LOG_DEBUG, r,
"Failed to find module '%s'", module);
return -ENOENT;
}
kmod_list_foreach(itr, modlist) {
_cleanup_(kmod_module_unrefp) struct kmod_module *mod = NULL;
int state, err;
mod = kmod_module_get_module(itr);
state = kmod_module_get_initstate(mod);
switch (state) {
case KMOD_MODULE_BUILTIN:
log_full(verbose ? LOG_INFO : LOG_DEBUG,
"Module '%s' is builtin", kmod_module_get_name(mod));
break;
case KMOD_MODULE_LIVE:
log_debug("Module '%s' is already loaded", kmod_module_get_name(mod));
break;
default:
err = kmod_module_probe_insert_module(mod, probe_flags,
NULL, NULL, NULL, NULL);
if (err == 0)
log_full(verbose ? LOG_INFO : LOG_DEBUG,
"Inserted module '%s'", kmod_module_get_name(mod));
else if (err == KMOD_PROBE_APPLY_BLACKLIST)
log_full(verbose ? LOG_INFO : LOG_DEBUG,
"Module '%s' is blacklisted", kmod_module_get_name(mod));
else {
assert(err < 0);
log_full_errno(!verbose ? LOG_DEBUG :
err == -ENODEV ? LOG_NOTICE :
err == -ENOENT ? LOG_WARNING :
LOG_ERR,
err,
"Failed to insert module '%s': %m",
kmod_module_get_name(mod));
if (!IN_SET(err, -ENODEV, -ENOENT))
r = err;
}
}
}
return r;
}

View File

@ -8,3 +8,5 @@
DEFINE_TRIVIAL_CLEANUP_FUNC(struct kmod_ctx*, kmod_unref);
DEFINE_TRIVIAL_CLEANUP_FUNC(struct kmod_module*, kmod_module_unref);
DEFINE_TRIVIAL_CLEANUP_FUNC(struct kmod_list*, kmod_module_unref_list);
int module_load_and_warn(struct kmod_ctx *ctx, const char *module, bool verbose);

View File

@ -18,55 +18,23 @@
static struct kmod_ctx *ctx = NULL;
static int load_module(struct udev *udev, const char *alias) {
_cleanup_(kmod_module_unref_listp) struct kmod_list *list = NULL;
struct kmod_list *l;
int err;
err = kmod_module_new_from_lookup(ctx, alias, &list);
if (err < 0)
return err;
if (list == NULL)
log_debug("No module matches '%s'", alias);
kmod_list_foreach(l, list) {
_cleanup_(kmod_module_unrefp) struct kmod_module *mod = NULL;
mod = kmod_module_get_module(l);
err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL);
if (err == KMOD_PROBE_APPLY_BLACKLIST)
log_debug("Module '%s' is blacklisted", kmod_module_get_name(mod));
else if (err == 0)
log_debug("Inserted '%s'", kmod_module_get_name(mod));
else
log_debug("Failed to insert '%s'", kmod_module_get_name(mod));
}
return err;
}
_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(struct udev_device *dev, int argc, char *argv[], bool test) {
struct udev *udev = udev_device_get_udev(dev);
int i;
if (!ctx)
return 0;
if (argc < 3 || !streq(argv[1], "load")) {
log_error("expect: %s load <module>", argv[0]);
log_error("%s: expected: load <module>", argv[0]);
return EXIT_FAILURE;
}
for (i = 2; argv[i]; i++) {
log_debug("Execute '%s' '%s'", argv[1], argv[i]);
load_module(udev, argv[i]);
}
for (i = 2; argv[i]; i++)
(void) module_load_and_warn(ctx, argv[i], false);
return EXIT_SUCCESS;
}