]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/modules-load/modules-load.c
cgls: when showing root slice, put -.slice at top of tree
[thirdparty/systemd.git] / src / modules-load / modules-load.c
CommitLineData
b2423f1f
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
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
b2423f1f
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.
b2423f1f 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
b2423f1f
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
b2423f1f 22#include <errno.h>
3f6fd1ba 23#include <getopt.h>
07630cea 24#include <libkmod.h>
3f6fd1ba 25#include <limits.h>
b2423f1f
LP
26#include <string.h>
27#include <sys/stat.h>
b2423f1f 28
3f6fd1ba 29#include "conf-files.h"
a0f29c76 30#include "def.h"
3ffd4af2 31#include "fd-util.h"
0d39fa9c 32#include "fileio.h"
b2423f1f 33#include "log.h"
4e731273 34#include "proc-cmdline.h"
07630cea 35#include "string-util.h"
b2423f1f 36#include "strv.h"
3f6fd1ba 37#include "util.h"
03658d4f
LP
38
39static char **arg_proc_cmdline_modules = NULL;
b2423f1f 40
7f0a55d4 41static const char conf_file_dirs[] = CONF_DIRS_NULSTR("modules-load");
fabe5c0e 42
83684a35 43static void systemd_kmod_log(void *data, int priority, const char *file, int line,
f168c273 44 const char *fn, const char *format, va_list args) {
bcfce235
LP
45
46 DISABLE_WARNING_FORMAT_NONLITERAL;
79008bdd 47 log_internalv(priority, 0, file, line, fn, format, args);
bcfce235 48 REENABLE_WARNING;
83684a35
TG
49}
50
03658d4f 51static int add_modules(const char *p) {
fabe5c0e 52 _cleanup_strv_free_ char **k = NULL;
03658d4f
LP
53
54 k = strv_split(p, ",");
0d0f0c50
SL
55 if (!k)
56 return log_oom();
03658d4f 57
e287086b 58 if (strv_extend_strv(&arg_proc_cmdline_modules, k, true) < 0)
0d0f0c50 59 return log_oom();
03658d4f 60
03658d4f
LP
61 return 0;
62}
63
059cb385 64static int parse_proc_cmdline_item(const char *key, const char *value) {
74df0fca 65 int r;
03658d4f 66
059cb385
LP
67 if (STR_IN_SET(key, "modules-load", "rd.modules-load") && value) {
68 r = add_modules(value);
141a79f4
ZJS
69 if (r < 0)
70 return r;
03658d4f
LP
71 }
72
c007bb1b 73 return 0;
03658d4f
LP
74}
75
76static int load_module(struct kmod_ctx *ctx, const char *m) {
27fda47f 77 const int probe_flags = KMOD_PROBE_APPLY_BLACKLIST;
03658d4f
LP
78 struct kmod_list *itr, *modlist = NULL;
79 int r = 0;
80
9f6445e3 81 log_debug("load: %s", m);
03658d4f
LP
82
83 r = kmod_module_new_from_lookup(ctx, m, &modlist);
f647962d
MS
84 if (r < 0)
85 return log_error_errno(r, "Failed to lookup alias '%s': %m", m);
03658d4f 86
27fda47f
MS
87 if (!modlist) {
88 log_error("Failed to find module '%s'", m);
8f9c0b4c 89 return -ENOENT;
27fda47f
MS
90 }
91
03658d4f
LP
92 kmod_list_foreach(itr, modlist) {
93 struct kmod_module *mod;
27fda47f 94 int state, err;
03658d4f
LP
95
96 mod = kmod_module_get_module(itr);
27fda47f
MS
97 state = kmod_module_get_initstate(mod);
98
99 switch (state) {
100 case KMOD_MODULE_BUILTIN:
101 log_info("Module '%s' is builtin", kmod_module_get_name(mod));
102 break;
103
104 case KMOD_MODULE_LIVE:
b56c267f 105 log_debug("Module '%s' is already loaded", kmod_module_get_name(mod));
27fda47f
MS
106 break;
107
108 default:
109 err = kmod_module_probe_insert_module(mod, probe_flags,
110 NULL, NULL, NULL, NULL);
111
112 if (err == 0)
113 log_info("Inserted module '%s'", kmod_module_get_name(mod));
114 else if (err == KMOD_PROBE_APPLY_BLACKLIST)
115 log_info("Module '%s' is blacklisted", kmod_module_get_name(mod));
116 else {
c33b3297 117 log_error_errno(err, "Failed to insert '%s': %m", kmod_module_get_name(mod));
27fda47f
MS
118 r = err;
119 }
03658d4f
LP
120 }
121
122 kmod_module_unref(mod);
123 }
124
125 kmod_module_unref_list(modlist);
126
127 return r;
128}
129
fabe5c0e
LP
130static int apply_file(struct kmod_ctx *ctx, const char *path, bool ignore_enoent) {
131 _cleanup_fclose_ FILE *f = NULL;
132 int r;
133
134 assert(ctx);
135 assert(path);
136
4cf7ea55 137 r = search_and_fopen_nulstr(path, "re", NULL, conf_file_dirs, &f);
fabe5c0e
LP
138 if (r < 0) {
139 if (ignore_enoent && r == -ENOENT)
140 return 0;
141
8d3d7072 142 return log_error_errno(r, "Failed to open %s, ignoring: %m", path);
fabe5c0e
LP
143 }
144
9f6445e3 145 log_debug("apply: %s", path);
fabe5c0e
LP
146 for (;;) {
147 char line[LINE_MAX], *l;
148 int k;
149
150 if (!fgets(line, sizeof(line), f)) {
151 if (feof(f))
152 break;
153
e1427b13 154 return log_error_errno(errno, "Failed to read file '%s', ignoring: %m", path);
fabe5c0e
LP
155 }
156
157 l = strstrip(line);
158 if (!*l)
159 continue;
d3b6d0c2 160 if (strchr(COMMENTS "\n", *l))
fabe5c0e
LP
161 continue;
162
163 k = load_module(ctx, l);
164 if (k < 0 && r == 0)
165 r = k;
166 }
167
168 return r;
169}
170
601185b4 171static void help(void) {
fabe5c0e
LP
172 printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
173 "Loads statically configured kernel modules.\n\n"
eb9da376
LP
174 " -h --help Show this help\n"
175 " --version Show package version\n",
fabe5c0e 176 program_invocation_short_name);
fabe5c0e
LP
177}
178
179static int parse_argv(int argc, char *argv[]) {
180
eb9da376
LP
181 enum {
182 ARG_VERSION = 0x100,
183 };
184
fabe5c0e
LP
185 static const struct option options[] = {
186 { "help", no_argument, NULL, 'h' },
eb9da376
LP
187 { "version", no_argument, NULL, ARG_VERSION },
188 {}
fabe5c0e
LP
189 };
190
191 int c;
192
193 assert(argc >= 0);
194 assert(argv);
195
601185b4 196 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
fabe5c0e
LP
197
198 switch (c) {
199
200 case 'h':
601185b4
ZJS
201 help();
202 return 0;
eb9da376
LP
203
204 case ARG_VERSION:
3f6fd1ba 205 return version();
fabe5c0e
LP
206
207 case '?':
208 return -EINVAL;
209
210 default:
eb9da376 211 assert_not_reached("Unhandled option");
fabe5c0e 212 }
fabe5c0e
LP
213
214 return 1;
215}
216
b2423f1f 217int main(int argc, char *argv[]) {
fabe5c0e 218 int r, k;
83684a35 219 struct kmod_ctx *ctx;
b2423f1f 220
fabe5c0e
LP
221 r = parse_argv(argc, argv);
222 if (r <= 0)
223 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
b2423f1f 224
4cfa2c99 225 log_set_target(LOG_TARGET_AUTO);
b2423f1f
LP
226 log_parse_environment();
227 log_open();
228
4c12626c
LP
229 umask(0022);
230
b5884878
LP
231 r = parse_proc_cmdline(parse_proc_cmdline_item);
232 if (r < 0)
da927ba9 233 log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
03658d4f 234
4e2075ce
LP
235 ctx = kmod_new(NULL, NULL);
236 if (!ctx) {
83684a35 237 log_error("Failed to allocate memory for kmod.");
b2423f1f
LP
238 goto finish;
239 }
240
83684a35 241 kmod_load_resources(ctx);
83684a35 242 kmod_set_log_fn(ctx, systemd_kmod_log, NULL);
b2423f1f 243
fabe5c0e 244 r = 0;
03658d4f 245
fabe5c0e
LP
246 if (argc > optind) {
247 int i;
b2423f1f 248
fabe5c0e
LP
249 for (i = optind; i < argc; i++) {
250 k = apply_file(ctx, argv[i], false);
251 if (k < 0 && r == 0)
252 r = k;
b2423f1f
LP
253 }
254
fabe5c0e 255 } else {
4df32778 256 _cleanup_strv_free_ char **files = NULL;
fabe5c0e 257 char **fn, **i;
b2423f1f 258
fabe5c0e
LP
259 STRV_FOREACH(i, arg_proc_cmdline_modules) {
260 k = load_module(ctx, *i);
b857193b
LP
261 if (k < 0 && r == 0)
262 r = k;
b2423f1f
LP
263 }
264
4b462d1a
LP
265 k = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs);
266 if (k < 0) {
da927ba9 267 log_error_errno(k, "Failed to enumerate modules-load.d files: %m");
4b462d1a
LP
268 if (r == 0)
269 r = k;
fabe5c0e 270 goto finish;
b2423f1f
LP
271 }
272
fabe5c0e
LP
273 STRV_FOREACH(fn, files) {
274 k = apply_file(ctx, *fn, true);
275 if (k < 0 && r == 0)
276 r = k;
277 }
b2423f1f
LP
278 }
279
b2423f1f 280finish:
83684a35 281 kmod_unref(ctx);
03658d4f 282 strv_free(arg_proc_cmdline_modules);
b2423f1f 283
fabe5c0e 284 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
b2423f1f 285}