udev-builtin-kmod: support to run without arguments

If no module name is provided, then try to load modules based on the
device modealias.

Previously, MODALIAS property is passed as an argument, but it may
contain quotation. Hence, unfortunately the modalias may be modified
and cannot load expected modules.

Fixes #24715.
This commit is contained in:
Yu Watanabe 2022-10-14 16:18:35 +09:00
parent 4554c178bf
commit 2ce39d78b8
2 changed files with 22 additions and 6 deletions

View File

@ -2,7 +2,7 @@
ACTION!="add", GOTO="drivers_end"
ENV{MODALIAS}=="?*", RUN{builtin}+="kmod load '$env{MODALIAS}'"
ENV{MODALIAS}=="?*", RUN{builtin}+="kmod load"
SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="SD", RUN{builtin}+="kmod load tifm_sd"
SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="MS", RUN{builtin}+="kmod load tifm_ms"
SUBSYSTEM=="memstick", RUN{builtin}+="kmod load ms_block mspro_block"

View File

@ -10,8 +10,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "device-util.h"
#include "module-util.h"
#include "string-util.h"
#include "strv.h"
#include "udev-builtin.h"
static struct kmod_ctx *ctx = NULL;
@ -21,15 +23,29 @@ _printf_(6,0) static void udev_kmod_log(void *data, int priority, const char *fi
}
static int builtin_kmod(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
int r;
assert(dev);
if (!ctx)
return 0;
if (argc < 3 || !streq(argv[1], "load"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: expected: load <module>…", argv[0]);
if (argc < 2 || !streq(argv[1], "load"))
return log_device_warning_errno(dev, SYNTHETIC_ERRNO(EINVAL),
"%s: expected: load [module…]", argv[0]);
for (int i = 2; argv[i]; i++)
(void) module_load_and_warn(ctx, argv[i], false);
char **modules = strv_skip(argv, 2);
if (strv_isempty(modules)) {
const char *modalias;
r = sd_device_get_property_value(dev, "MODALIAS", &modalias);
if (r < 0)
return log_device_warning_errno(dev, r, "Failed to read property \"MODALIAS\".");
(void) module_load_and_warn(ctx, modalias, /* verbose = */ false);
} else
STRV_FOREACH(module, modules)
(void) module_load_and_warn(ctx, *module, /* verbose = */ false);
return 0;
}