]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/modules-load/modules-load.c
log: be a bit less wasteful when allocating buffers
[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
22#include <unistd.h>
23#include <fcntl.h>
24#include <errno.h>
25#include <string.h>
26#include <sys/stat.h>
27#include <limits.h>
28#include <dirent.h>
fabe5c0e 29#include <getopt.h>
83684a35 30#include <libkmod.h>
b2423f1f
LP
31
32#include "log.h"
33#include "util.h"
34#include "strv.h"
2c21044f 35#include "conf-files.h"
a5c32cff 36#include "fileio.h"
eb9da376 37#include "build.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;
086891e5 47 log_metav(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
e3e45d4f 58 if (strv_extend_strv(&arg_proc_cmdline_modules, k) < 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);
84 if (r < 0) {
85 log_error("Failed to lookup alias '%s': %s", m, strerror(-r));
86 return r;
87 }
88
27fda47f
MS
89 if (!modlist) {
90 log_error("Failed to find module '%s'", m);
8f9c0b4c 91 return -ENOENT;
27fda47f
MS
92 }
93
03658d4f
LP
94 kmod_list_foreach(itr, modlist) {
95 struct kmod_module *mod;
27fda47f 96 int state, err;
03658d4f
LP
97
98 mod = kmod_module_get_module(itr);
27fda47f
MS
99 state = kmod_module_get_initstate(mod);
100
101 switch (state) {
102 case KMOD_MODULE_BUILTIN:
103 log_info("Module '%s' is builtin", kmod_module_get_name(mod));
104 break;
105
106 case KMOD_MODULE_LIVE:
b56c267f 107 log_debug("Module '%s' is already loaded", kmod_module_get_name(mod));
27fda47f
MS
108 break;
109
110 default:
111 err = kmod_module_probe_insert_module(mod, probe_flags,
112 NULL, NULL, NULL, NULL);
113
114 if (err == 0)
115 log_info("Inserted module '%s'", kmod_module_get_name(mod));
116 else if (err == KMOD_PROBE_APPLY_BLACKLIST)
117 log_info("Module '%s' is blacklisted", kmod_module_get_name(mod));
118 else {
119 log_error("Failed to insert '%s': %s", kmod_module_get_name(mod),
120 strerror(-err));
121 r = err;
122 }
03658d4f
LP
123 }
124
125 kmod_module_unref(mod);
126 }
127
128 kmod_module_unref_list(modlist);
129
130 return r;
131}
132
fabe5c0e
LP
133static int apply_file(struct kmod_ctx *ctx, const char *path, bool ignore_enoent) {
134 _cleanup_fclose_ FILE *f = NULL;
135 int r;
136
137 assert(ctx);
138 assert(path);
139
4cf7ea55 140 r = search_and_fopen_nulstr(path, "re", NULL, conf_file_dirs, &f);
fabe5c0e
LP
141 if (r < 0) {
142 if (ignore_enoent && r == -ENOENT)
143 return 0;
144
145 log_error("Failed to open %s, ignoring: %s", path, strerror(-r));
146 return r;
147 }
148
9f6445e3 149 log_debug("apply: %s", path);
fabe5c0e
LP
150 for (;;) {
151 char line[LINE_MAX], *l;
152 int k;
153
154 if (!fgets(line, sizeof(line), f)) {
155 if (feof(f))
156 break;
157
158 log_error("Failed to read file '%s', ignoring: %m", path);
159 return -errno;
160 }
161
162 l = strstrip(line);
163 if (!*l)
164 continue;
d3b6d0c2 165 if (strchr(COMMENTS "\n", *l))
fabe5c0e
LP
166 continue;
167
168 k = load_module(ctx, l);
169 if (k < 0 && r == 0)
170 r = k;
171 }
172
173 return r;
174}
175
601185b4 176static void help(void) {
fabe5c0e
LP
177 printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
178 "Loads statically configured kernel modules.\n\n"
eb9da376
LP
179 " -h --help Show this help\n"
180 " --version Show package version\n",
fabe5c0e 181 program_invocation_short_name);
fabe5c0e
LP
182}
183
184static int parse_argv(int argc, char *argv[]) {
185
eb9da376
LP
186 enum {
187 ARG_VERSION = 0x100,
188 };
189
fabe5c0e
LP
190 static const struct option options[] = {
191 { "help", no_argument, NULL, 'h' },
eb9da376
LP
192 { "version", no_argument, NULL, ARG_VERSION },
193 {}
fabe5c0e
LP
194 };
195
196 int c;
197
198 assert(argc >= 0);
199 assert(argv);
200
601185b4 201 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
fabe5c0e
LP
202
203 switch (c) {
204
205 case 'h':
601185b4
ZJS
206 help();
207 return 0;
eb9da376
LP
208
209 case ARG_VERSION:
210 puts(PACKAGE_STRING);
211 puts(SYSTEMD_FEATURES);
fabe5c0e
LP
212 return 0;
213
214 case '?':
215 return -EINVAL;
216
217 default:
eb9da376 218 assert_not_reached("Unhandled option");
fabe5c0e 219 }
fabe5c0e
LP
220
221 return 1;
222}
223
b2423f1f 224int main(int argc, char *argv[]) {
fabe5c0e 225 int r, k;
83684a35 226 struct kmod_ctx *ctx;
b2423f1f 227
fabe5c0e
LP
228 r = parse_argv(argc, argv);
229 if (r <= 0)
230 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
b2423f1f 231
4cfa2c99 232 log_set_target(LOG_TARGET_AUTO);
b2423f1f
LP
233 log_parse_environment();
234 log_open();
235
4c12626c
LP
236 umask(0022);
237
b5884878
LP
238 r = parse_proc_cmdline(parse_proc_cmdline_item);
239 if (r < 0)
240 log_warning("Failed to parse kernel command line, ignoring: %s", strerror(-r));
03658d4f 241
4e2075ce
LP
242 ctx = kmod_new(NULL, NULL);
243 if (!ctx) {
83684a35 244 log_error("Failed to allocate memory for kmod.");
b2423f1f
LP
245 goto finish;
246 }
247
83684a35 248 kmod_load_resources(ctx);
83684a35 249 kmod_set_log_fn(ctx, systemd_kmod_log, NULL);
b2423f1f 250
fabe5c0e 251 r = 0;
03658d4f 252
fabe5c0e
LP
253 if (argc > optind) {
254 int i;
b2423f1f 255
fabe5c0e
LP
256 for (i = optind; i < argc; i++) {
257 k = apply_file(ctx, argv[i], false);
258 if (k < 0 && r == 0)
259 r = k;
b2423f1f
LP
260 }
261
fabe5c0e
LP
262 } else {
263 _cleanup_free_ char **files = NULL;
264 char **fn, **i;
b2423f1f 265
fabe5c0e
LP
266 STRV_FOREACH(i, arg_proc_cmdline_modules) {
267 k = load_module(ctx, *i);
b857193b
LP
268 if (k < 0 && r == 0)
269 r = k;
b2423f1f
LP
270 }
271
4b462d1a
LP
272 k = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs);
273 if (k < 0) {
274 log_error("Failed to enumerate modules-load.d files: %s", strerror(-k));
275 if (r == 0)
276 r = k;
fabe5c0e 277 goto finish;
b2423f1f
LP
278 }
279
fabe5c0e
LP
280 STRV_FOREACH(fn, files) {
281 k = apply_file(ctx, *fn, true);
282 if (k < 0 && r == 0)
283 r = k;
284 }
b2423f1f
LP
285 }
286
b2423f1f 287finish:
83684a35 288 kmod_unref(ctx);
03658d4f 289 strv_free(arg_proc_cmdline_modules);
b2423f1f 290
fabe5c0e 291 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
b2423f1f 292}