1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * load kernel modules
4  *
5  * Copyright © 2011 ProFUSION embedded systems
6  */
7 
8 #include <errno.h>
9 #include <stdarg.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 
13 #include "module-util.h"
14 #include "string-util.h"
15 #include "udev-builtin.h"
16 
17 static struct kmod_ctx *ctx = NULL;
18 
udev_kmod_log(void * data,int priority,const char * file,int line,const char * fn,const char * format,va_list args)19 _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) {
20         log_internalv(priority, 0, file, line, fn, format, args);
21 }
22 
builtin_kmod(sd_device * dev,sd_netlink ** rtnl,int argc,char * argv[],bool test)23 static int builtin_kmod(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
24         if (!ctx)
25                 return 0;
26 
27         if (argc < 3 || !streq(argv[1], "load"))
28                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
29                                        "%s: expected: load <module>…", argv[0]);
30 
31         for (int i = 2; argv[i]; i++)
32                 (void) module_load_and_warn(ctx, argv[i], false);
33 
34         return 0;
35 }
36 
37 /* called at udev startup and reload */
builtin_kmod_init(void)38 static int builtin_kmod_init(void) {
39         if (ctx)
40                 return 0;
41 
42         ctx = kmod_new(NULL, NULL);
43         if (!ctx)
44                 return -ENOMEM;
45 
46         log_debug("Load module index");
47         kmod_set_log_fn(ctx, udev_kmod_log, NULL);
48         kmod_load_resources(ctx);
49         return 0;
50 }
51 
52 /* called on udev shutdown and reload request */
builtin_kmod_exit(void)53 static void builtin_kmod_exit(void) {
54         log_debug("Unload module index");
55         ctx = kmod_unref(ctx);
56 }
57 
58 /* called every couple of seconds during event activity; 'true' if config has changed */
builtin_kmod_validate(void)59 static bool builtin_kmod_validate(void) {
60         log_debug("Validate module index");
61         if (!ctx)
62                 return false;
63         return (kmod_validate_resources(ctx) != KMOD_RESOURCES_OK);
64 }
65 
66 const UdevBuiltin udev_builtin_kmod = {
67         .name = "kmod",
68         .cmd = builtin_kmod,
69         .init = builtin_kmod_init,
70         .exit = builtin_kmod_exit,
71         .validate = builtin_kmod_validate,
72         .help = "Kernel module loader",
73         .run_once = false,
74 };
75