]>
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 | ||
81dadce5 | 21 | #include <errno.h> |
b45ce692 | 22 | #include <libkmod.h> |
07630cea LP |
23 | #include <stdarg.h> |
24 | #include <stdio.h> | |
25 | #include <stdlib.h> | |
81dadce5 | 26 | |
07630cea | 27 | #include "string-util.h" |
81dadce5 KS |
28 | #include "udev.h" |
29 | ||
086891e5 | 30 | static struct kmod_ctx *ctx = NULL; |
b45ce692 | 31 | |
9ec6e95b | 32 | static int load_module(struct udev *udev, const char *alias) { |
912541b0 | 33 | struct kmod_list *list = NULL; |
912541b0 KS |
34 | struct kmod_list *l; |
35 | int err; | |
36 | ||
37 | err = kmod_module_new_from_lookup(ctx, alias, &list); | |
38 | if (err < 0) | |
39 | return err; | |
40 | ||
912541b0 | 41 | if (list == NULL) |
086891e5 | 42 | log_debug("No module matches '%s'", alias); |
912541b0 | 43 | |
96b2eef2 | 44 | kmod_list_foreach(l, list) { |
912541b0 KS |
45 | struct kmod_module *mod = kmod_module_get_module(l); |
46 | ||
96b2eef2 LDM |
47 | err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL); |
48 | if (err == KMOD_PROBE_APPLY_BLACKLIST) | |
086891e5 | 49 | log_debug("Module '%s' is blacklisted", kmod_module_get_name(mod)); |
96b2eef2 | 50 | else if (err == 0) |
086891e5 | 51 | log_debug("Inserted '%s'", kmod_module_get_name(mod)); |
912541b0 | 52 | else |
086891e5 | 53 | log_debug("Failed to insert '%s'", kmod_module_get_name(mod)); |
912541b0 KS |
54 | |
55 | kmod_module_unref(mod); | |
56 | } | |
57 | ||
58 | kmod_module_unref_list(list); | |
912541b0 | 59 | return err; |
b45ce692 KS |
60 | } |
61 | ||
086891e5 | 62 | _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 | 63 | log_internalv(priority, 0, file, line, fn, format, args); |
80df994c KS |
64 | } |
65 | ||
9ec6e95b | 66 | static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test) { |
912541b0 KS |
67 | struct udev *udev = udev_device_get_udev(dev); |
68 | int i; | |
69 | ||
a9f4815d | 70 | if (!ctx) |
5b4d50ef KS |
71 | return 0; |
72 | ||
090be865 | 73 | if (argc < 3 || !streq(argv[1], "load")) { |
9f6445e3 | 74 | log_error("expect: %s load <module>", argv[0]); |
912541b0 KS |
75 | return EXIT_FAILURE; |
76 | } | |
77 | ||
78 | for (i = 2; argv[i]; i++) { | |
086891e5 | 79 | log_debug("Execute '%s' '%s'", argv[1], argv[i]); |
912541b0 KS |
80 | load_module(udev, argv[i]); |
81 | } | |
82 | ||
83 | return EXIT_SUCCESS; | |
81dadce5 KS |
84 | } |
85 | ||
7781e063 | 86 | /* called at udev startup and reload */ |
9ec6e95b | 87 | static int builtin_kmod_init(struct udev *udev) { |
912541b0 KS |
88 | if (ctx) |
89 | return 0; | |
7c85d636 | 90 | |
912541b0 KS |
91 | ctx = kmod_new(NULL, NULL); |
92 | if (!ctx) | |
93 | return -ENOMEM; | |
b45ce692 | 94 | |
086891e5 | 95 | log_debug("Load module index"); |
912541b0 KS |
96 | kmod_set_log_fn(ctx, udev_kmod_log, udev); |
97 | kmod_load_resources(ctx); | |
98 | return 0; | |
aa29418a KS |
99 | } |
100 | ||
4f1795cc | 101 | /* called on udev shutdown and reload request */ |
9ec6e95b | 102 | static void builtin_kmod_exit(struct udev *udev) { |
086891e5 | 103 | log_debug("Unload module index"); |
912541b0 | 104 | ctx = kmod_unref(ctx); |
4f1795cc KS |
105 | } |
106 | ||
107 | /* called every couple of seconds during event activity; 'true' if config has changed */ | |
9ec6e95b | 108 | static bool builtin_kmod_validate(struct udev *udev) { |
086891e5 | 109 | log_debug("Validate module index"); |
7781e063 KS |
110 | if (!ctx) |
111 | return false; | |
112 | return (kmod_validate_resources(ctx) != KMOD_RESOURCES_OK); | |
aa29418a KS |
113 | } |
114 | ||
81dadce5 | 115 | const struct udev_builtin udev_builtin_kmod = { |
912541b0 KS |
116 | .name = "kmod", |
117 | .cmd = builtin_kmod, | |
118 | .init = builtin_kmod_init, | |
119 | .exit = builtin_kmod_exit, | |
120 | .validate = builtin_kmod_validate, | |
5ac0162c | 121 | .help = "Kernel module loader", |
912541b0 | 122 | .run_once = false, |
81dadce5 | 123 | }; |