]>
Commit | Line | Data |
---|---|---|
81dadce5 | 1 | /* |
aa29418a | 2 | * load kernel modules |
81dadce5 | 3 | * |
238b53a0 | 4 | * Copyright (C) 2011-2012 Kay Sievers <kay.sievers@vrfy.org> |
779f4de1 | 5 | * Copyright (C) 2011 ProFUSION embedded systems |
81dadce5 KS |
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> | |
06316d9f | 29 | #include <sys/wait.h> |
b45ce692 | 30 | #include <libkmod.h> |
81dadce5 KS |
31 | |
32 | #include "udev.h" | |
33 | ||
b45ce692 KS |
34 | static struct kmod_ctx *ctx; |
35 | ||
fe6784cf | 36 | static int load_module(struct udev *udev, const char *alias) |
b45ce692 | 37 | { |
912541b0 | 38 | struct kmod_list *list = NULL; |
912541b0 KS |
39 | struct kmod_list *l; |
40 | int err; | |
41 | ||
42 | err = kmod_module_new_from_lookup(ctx, alias, &list); | |
43 | if (err < 0) | |
44 | return err; | |
45 | ||
912541b0 | 46 | if (list == NULL) |
baa30fbc | 47 | log_debug("no module matches '%s'\n", alias); |
912541b0 | 48 | |
96b2eef2 | 49 | kmod_list_foreach(l, list) { |
912541b0 KS |
50 | struct kmod_module *mod = kmod_module_get_module(l); |
51 | ||
96b2eef2 LDM |
52 | err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL); |
53 | if (err == KMOD_PROBE_APPLY_BLACKLIST) | |
baa30fbc | 54 | log_debug("module '%s' is blacklisted\n", kmod_module_get_name(mod)); |
96b2eef2 | 55 | else if (err == 0) |
baa30fbc | 56 | log_debug("inserted '%s'\n", kmod_module_get_name(mod)); |
912541b0 | 57 | else |
baa30fbc | 58 | log_debug("failed to insert '%s'\n", kmod_module_get_name(mod)); |
912541b0 KS |
59 | |
60 | kmod_module_unref(mod); | |
61 | } | |
62 | ||
63 | kmod_module_unref_list(list); | |
912541b0 | 64 | return err; |
b45ce692 KS |
65 | } |
66 | ||
80df994c | 67 | static void udev_kmod_log(void *data, int priority, const char *file, int line, |
912541b0 | 68 | const char *fn, const char *format, va_list args) |
80df994c | 69 | { |
912541b0 | 70 | udev_main_log(data, priority, file, line, fn, format, args); |
80df994c KS |
71 | } |
72 | ||
e216e514 | 73 | static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test) |
81dadce5 | 74 | { |
912541b0 KS |
75 | struct udev *udev = udev_device_get_udev(dev); |
76 | int i; | |
77 | ||
5b4d50ef KS |
78 | if (ctx) |
79 | return 0; | |
80 | ||
912541b0 | 81 | if (argc < 3 || strcmp(argv[1], "load")) { |
baa30fbc | 82 | log_error("expect: %s load <module>\n", argv[0]); |
912541b0 KS |
83 | return EXIT_FAILURE; |
84 | } | |
85 | ||
86 | for (i = 2; argv[i]; i++) { | |
baa30fbc | 87 | log_debug("execute '%s' '%s'\n", argv[1], argv[i]); |
912541b0 KS |
88 | load_module(udev, argv[i]); |
89 | } | |
90 | ||
91 | return EXIT_SUCCESS; | |
81dadce5 KS |
92 | } |
93 | ||
7781e063 | 94 | /* called at udev startup and reload */ |
779f4de1 | 95 | static int builtin_kmod_init(struct udev *udev) |
aa29418a | 96 | { |
912541b0 KS |
97 | if (ctx) |
98 | return 0; | |
7c85d636 | 99 | |
912541b0 KS |
100 | ctx = kmod_new(NULL, NULL); |
101 | if (!ctx) | |
102 | return -ENOMEM; | |
b45ce692 | 103 | |
baa30fbc | 104 | log_debug("load module index\n"); |
912541b0 KS |
105 | kmod_set_log_fn(ctx, udev_kmod_log, udev); |
106 | kmod_load_resources(ctx); | |
107 | return 0; | |
aa29418a KS |
108 | } |
109 | ||
4f1795cc KS |
110 | /* called on udev shutdown and reload request */ |
111 | static void builtin_kmod_exit(struct udev *udev) | |
aa29418a | 112 | { |
baa30fbc | 113 | log_debug("unload module index\n"); |
912541b0 | 114 | ctx = kmod_unref(ctx); |
4f1795cc KS |
115 | } |
116 | ||
117 | /* called every couple of seconds during event activity; 'true' if config has changed */ | |
118 | static bool builtin_kmod_validate(struct udev *udev) | |
119 | { | |
baa30fbc | 120 | log_debug("validate module index\n"); |
7781e063 KS |
121 | if (!ctx) |
122 | return false; | |
123 | return (kmod_validate_resources(ctx) != KMOD_RESOURCES_OK); | |
aa29418a KS |
124 | } |
125 | ||
81dadce5 | 126 | const struct udev_builtin udev_builtin_kmod = { |
912541b0 KS |
127 | .name = "kmod", |
128 | .cmd = builtin_kmod, | |
129 | .init = builtin_kmod_init, | |
130 | .exit = builtin_kmod_exit, | |
131 | .validate = builtin_kmod_validate, | |
132 | .help = "kernel module loader", | |
133 | .run_once = false, | |
81dadce5 | 134 | }; |