]>
Commit | Line | Data |
---|---|---|
e7145211 | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
81dadce5 | 2 | /* |
aa29418a | 3 | * load kernel modules |
81dadce5 | 4 | * |
1298001e | 5 | * Copyright (C) 2011-2012 Kay Sievers <kay@vrfy.org> |
779f4de1 | 6 | * Copyright (C) 2011 ProFUSION embedded systems |
81dadce5 KS |
7 | * |
8 | * This program is free software: you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License as published by | |
10 | * the Free Software Foundation, either version 2 of the License, or | |
11 | * (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20 | */ | |
21 | ||
81dadce5 | 22 | #include <errno.h> |
b45ce692 | 23 | #include <libkmod.h> |
07630cea LP |
24 | #include <stdarg.h> |
25 | #include <stdio.h> | |
26 | #include <stdlib.h> | |
81dadce5 | 27 | |
232ac0d6 | 28 | #include "module-util.h" |
07630cea | 29 | #include "string-util.h" |
81dadce5 KS |
30 | #include "udev.h" |
31 | ||
086891e5 | 32 | static struct kmod_ctx *ctx = NULL; |
b45ce692 | 33 | |
9ec6e95b | 34 | static int load_module(struct udev *udev, const char *alias) { |
232ac0d6 | 35 | _cleanup_(kmod_module_unref_listp) struct kmod_list *list = NULL; |
912541b0 KS |
36 | struct kmod_list *l; |
37 | int err; | |
38 | ||
39 | err = kmod_module_new_from_lookup(ctx, alias, &list); | |
40 | if (err < 0) | |
41 | return err; | |
42 | ||
912541b0 | 43 | if (list == NULL) |
086891e5 | 44 | log_debug("No module matches '%s'", alias); |
912541b0 | 45 | |
96b2eef2 | 46 | kmod_list_foreach(l, list) { |
232ac0d6 ZJS |
47 | _cleanup_(kmod_module_unrefp) struct kmod_module *mod = NULL; |
48 | ||
49 | mod = kmod_module_get_module(l); | |
912541b0 | 50 | |
96b2eef2 LDM |
51 | err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL); |
52 | if (err == KMOD_PROBE_APPLY_BLACKLIST) | |
086891e5 | 53 | log_debug("Module '%s' is blacklisted", kmod_module_get_name(mod)); |
96b2eef2 | 54 | else if (err == 0) |
086891e5 | 55 | log_debug("Inserted '%s'", kmod_module_get_name(mod)); |
912541b0 | 56 | else |
086891e5 | 57 | log_debug("Failed to insert '%s'", kmod_module_get_name(mod)); |
912541b0 KS |
58 | } |
59 | ||
912541b0 | 60 | return err; |
b45ce692 KS |
61 | } |
62 | ||
086891e5 | 63 | _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) { |
79008bdd | 64 | log_internalv(priority, 0, file, line, fn, format, args); |
80df994c KS |
65 | } |
66 | ||
9ec6e95b | 67 | static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test) { |
912541b0 KS |
68 | struct udev *udev = udev_device_get_udev(dev); |
69 | int i; | |
70 | ||
a9f4815d | 71 | if (!ctx) |
5b4d50ef KS |
72 | return 0; |
73 | ||
090be865 | 74 | if (argc < 3 || !streq(argv[1], "load")) { |
9f6445e3 | 75 | log_error("expect: %s load <module>", argv[0]); |
912541b0 KS |
76 | return EXIT_FAILURE; |
77 | } | |
78 | ||
79 | for (i = 2; argv[i]; i++) { | |
086891e5 | 80 | log_debug("Execute '%s' '%s'", argv[1], argv[i]); |
912541b0 KS |
81 | load_module(udev, argv[i]); |
82 | } | |
83 | ||
84 | return EXIT_SUCCESS; | |
81dadce5 KS |
85 | } |
86 | ||
7781e063 | 87 | /* called at udev startup and reload */ |
9ec6e95b | 88 | static int builtin_kmod_init(struct udev *udev) { |
912541b0 KS |
89 | if (ctx) |
90 | return 0; | |
7c85d636 | 91 | |
912541b0 KS |
92 | ctx = kmod_new(NULL, NULL); |
93 | if (!ctx) | |
94 | return -ENOMEM; | |
b45ce692 | 95 | |
086891e5 | 96 | log_debug("Load module index"); |
912541b0 KS |
97 | kmod_set_log_fn(ctx, udev_kmod_log, udev); |
98 | kmod_load_resources(ctx); | |
99 | return 0; | |
aa29418a KS |
100 | } |
101 | ||
4f1795cc | 102 | /* called on udev shutdown and reload request */ |
9ec6e95b | 103 | static void builtin_kmod_exit(struct udev *udev) { |
086891e5 | 104 | log_debug("Unload module index"); |
912541b0 | 105 | ctx = kmod_unref(ctx); |
4f1795cc KS |
106 | } |
107 | ||
108 | /* called every couple of seconds during event activity; 'true' if config has changed */ | |
9ec6e95b | 109 | static bool builtin_kmod_validate(struct udev *udev) { |
086891e5 | 110 | log_debug("Validate module index"); |
7781e063 KS |
111 | if (!ctx) |
112 | return false; | |
113 | return (kmod_validate_resources(ctx) != KMOD_RESOURCES_OK); | |
aa29418a KS |
114 | } |
115 | ||
81dadce5 | 116 | const struct udev_builtin udev_builtin_kmod = { |
912541b0 KS |
117 | .name = "kmod", |
118 | .cmd = builtin_kmod, | |
119 | .init = builtin_kmod_init, | |
120 | .exit = builtin_kmod_exit, | |
121 | .validate = builtin_kmod_validate, | |
5ac0162c | 122 | .help = "Kernel module loader", |
912541b0 | 123 | .run_once = false, |
81dadce5 | 124 | }; |