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