]>
Commit | Line | Data |
---|---|---|
81dadce5 | 1 | /* |
aa29418a | 2 | * load kernel modules |
81dadce5 | 3 | * |
1298001e | 4 | * Copyright (C) 2011-2012 Kay Sievers <kay@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 | ||
086891e5 | 34 | static struct kmod_ctx *ctx = NULL; |
b45ce692 | 35 | |
9ec6e95b | 36 | static int load_module(struct udev *udev, const char *alias) { |
912541b0 | 37 | struct kmod_list *list = NULL; |
912541b0 KS |
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 | ||
912541b0 | 45 | if (list == NULL) |
086891e5 | 46 | log_debug("No module matches '%s'", alias); |
912541b0 | 47 | |
96b2eef2 | 48 | kmod_list_foreach(l, list) { |
912541b0 KS |
49 | struct kmod_module *mod = kmod_module_get_module(l); |
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 | kmod_module_unref(mod); | |
60 | } | |
61 | ||
62 | kmod_module_unref_list(list); | |
912541b0 | 63 | return err; |
b45ce692 KS |
64 | } |
65 | ||
086891e5 LP |
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_metav(priority, 0, file, line, fn, format, args); | |
80df994c KS |
68 | } |
69 | ||
9ec6e95b | 70 | static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test) { |
912541b0 KS |
71 | struct udev *udev = udev_device_get_udev(dev); |
72 | int i; | |
73 | ||
a9f4815d | 74 | if (!ctx) |
5b4d50ef KS |
75 | return 0; |
76 | ||
090be865 | 77 | if (argc < 3 || !streq(argv[1], "load")) { |
9f6445e3 | 78 | log_error("expect: %s load <module>", argv[0]); |
912541b0 KS |
79 | return EXIT_FAILURE; |
80 | } | |
81 | ||
82 | for (i = 2; argv[i]; i++) { | |
086891e5 | 83 | log_debug("Execute '%s' '%s'", argv[1], argv[i]); |
912541b0 KS |
84 | load_module(udev, argv[i]); |
85 | } | |
86 | ||
87 | return EXIT_SUCCESS; | |
81dadce5 KS |
88 | } |
89 | ||
7781e063 | 90 | /* called at udev startup and reload */ |
9ec6e95b | 91 | static int builtin_kmod_init(struct udev *udev) { |
912541b0 KS |
92 | if (ctx) |
93 | return 0; | |
7c85d636 | 94 | |
912541b0 KS |
95 | ctx = kmod_new(NULL, NULL); |
96 | if (!ctx) | |
97 | return -ENOMEM; | |
b45ce692 | 98 | |
086891e5 | 99 | log_debug("Load module index"); |
912541b0 KS |
100 | kmod_set_log_fn(ctx, udev_kmod_log, udev); |
101 | kmod_load_resources(ctx); | |
102 | return 0; | |
aa29418a KS |
103 | } |
104 | ||
4f1795cc | 105 | /* called on udev shutdown and reload request */ |
9ec6e95b | 106 | static void builtin_kmod_exit(struct udev *udev) { |
086891e5 | 107 | log_debug("Unload module index"); |
912541b0 | 108 | ctx = kmod_unref(ctx); |
4f1795cc KS |
109 | } |
110 | ||
111 | /* called every couple of seconds during event activity; 'true' if config has changed */ | |
9ec6e95b | 112 | static bool builtin_kmod_validate(struct udev *udev) { |
086891e5 | 113 | log_debug("Validate module index"); |
7781e063 KS |
114 | if (!ctx) |
115 | return false; | |
116 | return (kmod_validate_resources(ctx) != KMOD_RESOURCES_OK); | |
aa29418a KS |
117 | } |
118 | ||
81dadce5 | 119 | const struct udev_builtin udev_builtin_kmod = { |
912541b0 KS |
120 | .name = "kmod", |
121 | .cmd = builtin_kmod, | |
122 | .init = builtin_kmod_init, | |
123 | .exit = builtin_kmod_exit, | |
124 | .validate = builtin_kmod_validate, | |
125 | .help = "kernel module loader", | |
126 | .run_once = false, | |
81dadce5 | 127 | }; |