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