]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/kmod-setup.c
Merge pull request #170 from teg/rtnl-recv
[thirdparty/systemd.git] / src / core / kmod-setup.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
11c3a4ee
LP
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11c3a4ee
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
11c3a4ee 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
11c3a4ee
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
11c3a4ee
LP
22#include <unistd.h>
23#include <string.h>
f84f9974
LP
24
25#ifdef HAVE_KMOD
728beb28 26#include <libkmod.h>
f84f9974 27#endif
11c3a4ee
LP
28
29#include "macro.h"
c47fc1f0 30#include "capability.h"
d79acc30 31#include "bus-util.h"
11c3a4ee
LP
32#include "kmod-setup.h"
33
f84f9974 34#ifdef HAVE_KMOD
b4b87964
LP
35static void systemd_kmod_log(
36 void *data,
37 int priority,
38 const char *file, int line,
39 const char *fn,
40 const char *format,
41 va_list args) {
42
10223732 43 /* library logging is enabled at debug only */
bcfce235 44 DISABLE_WARNING_FORMAT_NONLITERAL;
79008bdd 45 log_internalv(LOG_DEBUG, 0, file, line, fn, format, args);
bcfce235 46 REENABLE_WARNING;
728beb28 47}
f84f9974 48#endif
b4b87964 49
7491e6e7 50int kmod_setup(void) {
f84f9974 51#ifdef HAVE_KMOD
c47fc1f0 52
7491e6e7
KS
53 static const struct {
54 const char *module;
55 const char *path;
85c67553
DM
56 bool warn_if_unavailable:1;
57 bool warn_if_module:1;
7491e6e7
KS
58 bool (*condition_fn)(void);
59 } kmod_table[] = {
60 /* auto-loading on use doesn't work before udev is up */
85c67553 61 { "autofs4", "/sys/class/misc/autofs", true, false, NULL },
7491e6e7
KS
62
63 /* early configure of ::1 on the loopback device */
85c67553 64 { "ipv6", "/sys/module/ipv6", false, true, NULL },
7491e6e7
KS
65
66 /* this should never be a module */
85c67553 67 { "unix", "/proc/net/unix", true, true, NULL },
7491e6e7 68
a363680f 69#ifdef ENABLE_KDBUS
7491e6e7 70 /* IPC is needed before we bring up any other services */
85c67553 71 { "kdbus", "/sys/fs/kdbus", false, false, is_kdbus_wanted },
a363680f 72#endif
1d308797 73
a363680f 74#ifdef HAVE_LIBIPTC
1d308797 75 /* netfilter is needed by networkd, nspawn among others, and cannot be autoloaded */
85c67553 76 { "ip_tables", "/proc/net/ip_tables_names", false, false, NULL },
a363680f 77#endif
7491e6e7 78 };
728beb28 79 struct kmod_ctx *ctx = NULL;
7491e6e7 80 unsigned int i;
b4b87964 81 int r;
11c3a4ee 82
c47fc1f0
LP
83 if (have_effective_cap(CAP_SYS_MODULE) == 0)
84 return 0;
85
7491e6e7 86 for (i = 0; i < ELEMENTSOF(kmod_table); i++) {
b4b87964 87 struct kmod_module *mod;
11c3a4ee 88
b43b8f7a 89 if (kmod_table[i].path && access(kmod_table[i].path, F_OK) >= 0)
7491e6e7
KS
90 continue;
91
b43b8f7a 92 if (kmod_table[i].condition_fn && !kmod_table[i].condition_fn())
11c3a4ee
LP
93 continue;
94
85c67553 95 if (kmod_table[i].warn_if_module)
7491e6e7
KS
96 log_debug("Your kernel apparently lacks built-in %s support. Might be "
97 "a good idea to compile it in. We'll now try to work around "
98 "this by loading the module...", kmod_table[i].module);
11c3a4ee 99
728beb28
TG
100 if (!ctx) {
101 ctx = kmod_new(NULL, NULL);
b4b87964
LP
102 if (!ctx)
103 return log_oom();
11c3a4ee 104
728beb28 105 kmod_set_log_fn(ctx, systemd_kmod_log, NULL);
728beb28
TG
106 kmod_load_resources(ctx);
107 }
11c3a4ee 108
7491e6e7 109 r = kmod_module_new_from_name(ctx, kmod_table[i].module, &mod);
b4b87964 110 if (r < 0) {
7491e6e7 111 log_error("Failed to lookup module '%s'", kmod_table[i].module);
728beb28
TG
112 continue;
113 }
11c3a4ee 114
b4b87964
LP
115 r = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL);
116 if (r == 0)
728beb28 117 log_info("Inserted module '%s'", kmod_module_get_name(mod));
b4b87964 118 else if (r == KMOD_PROBE_APPLY_BLACKLIST)
728beb28 119 log_info("Module '%s' is blacklisted", kmod_module_get_name(mod));
85c67553 120 else
d814f990
LP
121 log_full_errno((kmod_table[i].warn_if_unavailable || (r < 0 && r != -ENOENT)) ? LOG_WARNING : LOG_DEBUG,
122 r,
123 "Failed to insert module '%s': %m", kmod_module_get_name(mod));
11c3a4ee 124
728beb28 125 kmod_module_unref(mod);
11c3a4ee
LP
126 }
127
728beb28 128 if (ctx)
34a35ece 129 kmod_unref(ctx);
728beb28 130
f84f9974 131#endif
728beb28 132 return 0;
11c3a4ee 133}