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