]>
Commit | Line | Data |
---|---|---|
f13467ec | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
81dadce5 | 2 | /* |
aa29418a | 3 | * load kernel modules |
81dadce5 | 4 | * |
810adae9 | 5 | * Copyright © 2011 ProFUSION embedded systems |
81dadce5 KS |
6 | */ |
7 | ||
2ce39d78 | 8 | #include "device-util.h" |
232ac0d6 | 9 | #include "module-util.h" |
07630cea | 10 | #include "string-util.h" |
2ce39d78 | 11 | #include "strv.h" |
07a26e42 | 12 | #include "udev-builtin.h" |
81dadce5 | 13 | |
086891e5 | 14 | static struct kmod_ctx *ctx = NULL; |
b45ce692 | 15 | |
089bef66 | 16 | static int builtin_kmod(UdevEvent *event, int argc, char *argv[]) { |
5668f3a7 | 17 | sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); |
2ce39d78 YW |
18 | int r; |
19 | ||
089bef66 YW |
20 | if (event->event_mode != EVENT_UDEV_WORKER) { |
21 | log_device_debug(dev, "Running in test mode, skipping execution of 'kmod' builtin command."); | |
22 | return 0; | |
23 | } | |
24 | ||
a9f4815d | 25 | if (!ctx) |
5b4d50ef KS |
26 | return 0; |
27 | ||
2ce39d78 YW |
28 | if (argc < 2 || !streq(argv[1], "load")) |
29 | return log_device_warning_errno(dev, SYNTHETIC_ERRNO(EINVAL), | |
30 | "%s: expected: load [module…]", argv[0]); | |
31 | ||
32 | char **modules = strv_skip(argv, 2); | |
fdfa9fd8 ZJS |
33 | if (modules) |
34 | STRV_FOREACH(module, modules) | |
35 | (void) module_load_and_warn(ctx, *module, /* verbose = */ false); | |
36 | else { | |
2ce39d78 YW |
37 | const char *modalias; |
38 | ||
39 | r = sd_device_get_property_value(dev, "MODALIAS", &modalias); | |
40 | if (r < 0) | |
1d98716e | 41 | return log_device_warning_errno(dev, r, "Failed to read property \"MODALIAS\": %m"); |
912541b0 | 42 | |
2ce39d78 | 43 | (void) module_load_and_warn(ctx, modalias, /* verbose = */ false); |
fdfa9fd8 | 44 | } |
912541b0 | 45 | |
d354690e | 46 | return 0; |
81dadce5 KS |
47 | } |
48 | ||
7781e063 | 49 | /* called at udev startup and reload */ |
2024ed61 | 50 | static int builtin_kmod_init(void) { |
1d98716e LP |
51 | int r; |
52 | ||
912541b0 KS |
53 | if (ctx) |
54 | return 0; | |
7c85d636 | 55 | |
1d98716e LP |
56 | r = module_setup_context(&ctx); |
57 | if (r < 0) | |
58 | return log_error_errno(r, "Failed to initialize libkmod context: %m"); | |
59 | ||
c791f619 | 60 | log_debug("Loaded kernel module index."); |
912541b0 | 61 | return 0; |
aa29418a KS |
62 | } |
63 | ||
4f1795cc | 64 | /* called on udev shutdown and reload request */ |
2024ed61 | 65 | static void builtin_kmod_exit(void) { |
1d98716e LP |
66 | if (!ctx) |
67 | return; | |
68 | ||
69 | ctx = sym_kmod_unref(ctx); | |
c791f619 | 70 | log_debug("Unloaded kernel module index."); |
4f1795cc KS |
71 | } |
72 | ||
73 | /* called every couple of seconds during event activity; 'true' if config has changed */ | |
f9b3b990 | 74 | static bool builtin_kmod_should_reload(void) { |
7781e063 KS |
75 | if (!ctx) |
76 | return false; | |
009b2c3a | 77 | |
1d98716e | 78 | if (sym_kmod_validate_resources(ctx) != KMOD_RESOURCES_OK) { |
009b2c3a YW |
79 | log_debug("Kernel module index needs reloading."); |
80 | return true; | |
81 | } | |
82 | ||
83 | return false; | |
aa29418a KS |
84 | } |
85 | ||
25de7aa7 | 86 | const UdevBuiltin udev_builtin_kmod = { |
912541b0 KS |
87 | .name = "kmod", |
88 | .cmd = builtin_kmod, | |
89 | .init = builtin_kmod_init, | |
90 | .exit = builtin_kmod_exit, | |
f9b3b990 | 91 | .should_reload = builtin_kmod_should_reload, |
5ac0162c | 92 | .help = "Kernel module loader", |
912541b0 | 93 | .run_once = false, |
81dadce5 | 94 | }; |