]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/kmod-setup.c
update TODO
[thirdparty/systemd.git] / src / core / kmod-setup.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
11c3a4ee 2
6c1f72f6 3#include <ftw.h>
cf0fbc49 4#include <unistd.h>
f84f9974 5
6c1f72f6 6#include "alloc-util.h"
d79acc30 7#include "bus-util.h"
cf0fbc49 8#include "capability-util.h"
6c1f72f6 9#include "fileio.h"
11c3a4ee 10#include "kmod-setup.h"
cf0fbc49 11#include "macro.h"
6c1f72f6 12#include "string-util.h"
11c3a4ee 13
349cc4a5 14#if HAVE_KMOD
8a8a4b6e
ZJS
15#include "module-util.h"
16
b4b87964
LP
17static void systemd_kmod_log(
18 void *data,
19 int priority,
20 const char *file, int line,
21 const char *fn,
22 const char *format,
23 va_list args) {
24
10223732 25 /* library logging is enabled at debug only */
bcfce235 26 DISABLE_WARNING_FORMAT_NONLITERAL;
79008bdd 27 log_internalv(LOG_DEBUG, 0, file, line, fn, format, args);
bcfce235 28 REENABLE_WARNING;
728beb28 29}
b4b87964 30
6c1f72f6
HH
31static int has_virtio_rng_nftw_cb(
32 const char *fpath,
33 const struct stat *sb,
34 int tflag,
35 struct FTW *ftwbuf) {
36
37 _cleanup_free_ char *alias = NULL;
38 int r;
39
40 if ((FTW_D == tflag) && (ftwbuf->level > 2))
41 return FTW_SKIP_SUBTREE;
42
43 if (FTW_F != tflag)
44 return FTW_CONTINUE;
45
46 if (!endswith(fpath, "/modalias"))
47 return FTW_CONTINUE;
48
49 r = read_one_line_file(fpath, &alias);
50 if (r < 0)
51 return FTW_SKIP_SIBLINGS;
52
53 if (startswith(alias, "pci:v00001AF4d00001005"))
54 return FTW_STOP;
55
56 if (startswith(alias, "pci:v00001AF4d00001044"))
57 return FTW_STOP;
58
59 return FTW_SKIP_SIBLINGS;
60}
61
62static bool has_virtio_rng(void) {
63 return (nftw("/sys/devices/pci0000:00", has_virtio_rng_nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL) == FTW_STOP);
64}
95441cf2 65#endif
6c1f72f6 66
7491e6e7 67int kmod_setup(void) {
349cc4a5 68#if HAVE_KMOD
c47fc1f0 69
7491e6e7
KS
70 static const struct {
71 const char *module;
72 const char *path;
85c67553
DM
73 bool warn_if_unavailable:1;
74 bool warn_if_module:1;
7491e6e7
KS
75 bool (*condition_fn)(void);
76 } kmod_table[] = {
6755bb55
ZJS
77 /* This one we need to load explicitly, since auto-loading on use doesn't work
78 * before udev created the ghost device nodes, and we need it earlier than that. */
85c67553 79 { "autofs4", "/sys/class/misc/autofs", true, false, NULL },
7491e6e7 80
6755bb55
ZJS
81 /* This one we need to load explicitly, since auto-loading of IPv6 is not done when
82 * we try to configure ::1 on the loopback device. */
85c67553 83 { "ipv6", "/sys/module/ipv6", false, true, NULL },
7491e6e7 84
6755bb55 85 /* This should never be a module */
85c67553 86 { "unix", "/proc/net/unix", true, true, NULL },
7491e6e7 87
349cc4a5 88#if HAVE_LIBIPTC
1d308797 89 /* netfilter is needed by networkd, nspawn among others, and cannot be autoloaded */
85c67553 90 { "ip_tables", "/proc/net/ip_tables_names", false, false, NULL },
a363680f 91#endif
6c1f72f6
HH
92 /* virtio_rng would be loaded by udev later, but real entropy might be needed very early */
93 { "virtio_rng", NULL, false, false, has_virtio_rng },
7491e6e7 94 };
232ac0d6 95 _cleanup_(kmod_unrefp) struct kmod_ctx *ctx = NULL;
14cb109d 96 unsigned i;
11c3a4ee 97
c47fc1f0
LP
98 if (have_effective_cap(CAP_SYS_MODULE) == 0)
99 return 0;
100
7491e6e7 101 for (i = 0; i < ELEMENTSOF(kmod_table); i++) {
b43b8f7a 102 if (kmod_table[i].path && access(kmod_table[i].path, F_OK) >= 0)
7491e6e7
KS
103 continue;
104
b43b8f7a 105 if (kmod_table[i].condition_fn && !kmod_table[i].condition_fn())
11c3a4ee
LP
106 continue;
107
85c67553 108 if (kmod_table[i].warn_if_module)
7491e6e7
KS
109 log_debug("Your kernel apparently lacks built-in %s support. Might be "
110 "a good idea to compile it in. We'll now try to work around "
111 "this by loading the module...", kmod_table[i].module);
11c3a4ee 112
728beb28
TG
113 if (!ctx) {
114 ctx = kmod_new(NULL, NULL);
b4b87964
LP
115 if (!ctx)
116 return log_oom();
11c3a4ee 117
728beb28 118 kmod_set_log_fn(ctx, systemd_kmod_log, NULL);
728beb28
TG
119 kmod_load_resources(ctx);
120 }
11c3a4ee 121
81d7c696 122 (void) module_load_and_warn(ctx, kmod_table[i].module, kmod_table[i].warn_if_unavailable);
11c3a4ee
LP
123 }
124
f84f9974 125#endif
728beb28 126 return 0;
11c3a4ee 127}