]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/kmod-setup.c
log: be a bit less wasteful when allocating buffers
[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
22#include <sys/wait.h>
23#include <unistd.h>
24#include <string.h>
25#include <errno.h>
f84f9974
LP
26
27#ifdef HAVE_KMOD
728beb28 28#include <libkmod.h>
f84f9974 29#endif
11c3a4ee
LP
30
31#include "macro.h"
32#include "execute.h"
c47fc1f0 33#include "capability.h"
11c3a4ee
LP
34#include "kmod-setup.h"
35
f84f9974 36#ifdef HAVE_KMOD
b4b87964
LP
37static void systemd_kmod_log(
38 void *data,
39 int priority,
40 const char *file, int line,
41 const char *fn,
42 const char *format,
43 va_list args) {
44
10223732 45 /* library logging is enabled at debug only */
bcfce235 46 DISABLE_WARNING_FORMAT_NONLITERAL;
086891e5 47 log_metav(LOG_DEBUG, 0, file, line, fn, format, args);
bcfce235 48 REENABLE_WARNING;
728beb28 49}
b4b87964 50
b43b8f7a 51static bool cmdline_check_kdbus(void) {
7491e6e7 52 _cleanup_free_ char *line = NULL;
5f68e74b
LP
53 const char *p;
54 int r;
b4b87964 55
5f68e74b
LP
56 r = proc_cmdline(&line);
57 if (r < 0)
7491e6e7 58 return false;
b4b87964 59
5f68e74b
LP
60 p = line;
61 for (;;) {
62 _cleanup_free_ char *word = NULL;
63
64 r = unquote_first_word(&p, &word, true);
65 if (r <= 0)
66 return false;
67
68 if (streq(word, "kdbus"))
69 return true;
70 }
7491e6e7 71}
f84f9974 72#endif
b4b87964 73
7491e6e7 74int kmod_setup(void) {
f84f9974 75#ifdef HAVE_KMOD
c47fc1f0 76
7491e6e7
KS
77 static const struct {
78 const char *module;
79 const char *path;
80 bool warn;
81 bool (*condition_fn)(void);
82 } kmod_table[] = {
83 /* auto-loading on use doesn't work before udev is up */
68d4c452 84 { "autofs4", "/sys/class/misc/autofs", true, NULL },
7491e6e7
KS
85
86 /* early configure of ::1 on the loopback device */
68d4c452 87 { "ipv6", "/sys/module/ipv6", true, NULL },
7491e6e7
KS
88
89 /* this should never be a module */
68d4c452 90 { "unix", "/proc/net/unix", true, NULL },
7491e6e7
KS
91
92 /* IPC is needed before we bring up any other services */
63cc4c31 93 { "kdbus", "/sys/fs/kdbus", false, cmdline_check_kdbus },
7491e6e7 94 };
728beb28 95 struct kmod_ctx *ctx = NULL;
7491e6e7 96 unsigned int i;
b4b87964 97 int r;
11c3a4ee 98
c47fc1f0
LP
99 if (have_effective_cap(CAP_SYS_MODULE) == 0)
100 return 0;
101
7491e6e7 102 for (i = 0; i < ELEMENTSOF(kmod_table); i++) {
b4b87964 103 struct kmod_module *mod;
11c3a4ee 104
b43b8f7a 105 if (kmod_table[i].path && access(kmod_table[i].path, F_OK) >= 0)
7491e6e7
KS
106 continue;
107
b43b8f7a 108 if (kmod_table[i].condition_fn && !kmod_table[i].condition_fn())
11c3a4ee
LP
109 continue;
110
7491e6e7
KS
111 if (kmod_table[i].warn)
112 log_debug("Your kernel apparently lacks built-in %s support. Might be "
113 "a good idea to compile it in. We'll now try to work around "
114 "this by loading the module...", kmod_table[i].module);
11c3a4ee 115
728beb28
TG
116 if (!ctx) {
117 ctx = kmod_new(NULL, NULL);
b4b87964
LP
118 if (!ctx)
119 return log_oom();
11c3a4ee 120
728beb28 121 kmod_set_log_fn(ctx, systemd_kmod_log, NULL);
728beb28
TG
122 kmod_load_resources(ctx);
123 }
11c3a4ee 124
7491e6e7 125 r = kmod_module_new_from_name(ctx, kmod_table[i].module, &mod);
b4b87964 126 if (r < 0) {
7491e6e7 127 log_error("Failed to lookup module '%s'", kmod_table[i].module);
728beb28
TG
128 continue;
129 }
11c3a4ee 130
b4b87964
LP
131 r = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL);
132 if (r == 0)
728beb28 133 log_info("Inserted module '%s'", kmod_module_get_name(mod));
b4b87964 134 else if (r == KMOD_PROBE_APPLY_BLACKLIST)
728beb28 135 log_info("Module '%s' is blacklisted", kmod_module_get_name(mod));
b43b8f7a 136 else if (kmod_table[i].warn)
10223732 137 log_error("Failed to insert module '%s'", kmod_module_get_name(mod));
11c3a4ee 138
728beb28 139 kmod_module_unref(mod);
11c3a4ee
LP
140 }
141
728beb28 142 if (ctx)
34a35ece 143 kmod_unref(ctx);
728beb28 144
f84f9974 145#endif
728beb28 146 return 0;
11c3a4ee 147}