2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
27 #include "conf-files.h"
32 #include "module-util.h"
33 #include "proc-cmdline.h"
34 #include "string-util.h"
38 static char **arg_proc_cmdline_modules
= NULL
;
40 static const char conf_file_dirs
[] = CONF_PATHS_NULSTR("modules-load.d");
42 static void systemd_kmod_log(void *data
, int priority
, const char *file
, int line
,
43 const char *fn
, const char *format
, va_list args
) {
45 DISABLE_WARNING_FORMAT_NONLITERAL
;
46 log_internalv(priority
, 0, file
, line
, fn
, format
, args
);
50 static int add_modules(const char *p
) {
51 _cleanup_strv_free_
char **k
= NULL
;
53 k
= strv_split(p
, ",");
57 if (strv_extend_strv(&arg_proc_cmdline_modules
, k
, true) < 0)
63 static int parse_proc_cmdline_item(const char *key
, const char *value
, void *data
) {
66 if (proc_cmdline_key_streq(key
, "modules_load")) {
68 if (proc_cmdline_value_missing(key
, value
))
71 r
= add_modules(value
);
79 static int load_module(struct kmod_ctx
*ctx
, const char *m
) {
80 const int probe_flags
= KMOD_PROBE_APPLY_BLACKLIST
;
81 struct kmod_list
*itr
;
82 _cleanup_(kmod_module_unref_listp
) struct kmod_list
*modlist
= NULL
;
85 log_debug("load: %s", m
);
87 r
= kmod_module_new_from_lookup(ctx
, m
, &modlist
);
89 return log_error_errno(r
, "Failed to lookup alias '%s': %m", m
);
92 log_error("Failed to find module '%s'", m
);
96 kmod_list_foreach(itr
, modlist
) {
97 _cleanup_(kmod_module_unrefp
) struct kmod_module
*mod
= NULL
;
100 mod
= kmod_module_get_module(itr
);
101 state
= kmod_module_get_initstate(mod
);
104 case KMOD_MODULE_BUILTIN
:
105 log_info("Module '%s' is builtin", kmod_module_get_name(mod
));
108 case KMOD_MODULE_LIVE
:
109 log_debug("Module '%s' is already loaded", kmod_module_get_name(mod
));
113 err
= kmod_module_probe_insert_module(mod
, probe_flags
,
114 NULL
, NULL
, NULL
, NULL
);
117 log_info("Inserted module '%s'", kmod_module_get_name(mod
));
118 else if (err
== KMOD_PROBE_APPLY_BLACKLIST
)
119 log_info("Module '%s' is blacklisted", kmod_module_get_name(mod
));
122 r
= log_error_errno(err
, "Failed to insert '%s': %m",
123 kmod_module_get_name(mod
));
131 static int apply_file(struct kmod_ctx
*ctx
, const char *path
, bool ignore_enoent
) {
132 _cleanup_fclose_
FILE *f
= NULL
;
138 r
= search_and_fopen_nulstr(path
, "re", NULL
, conf_file_dirs
, &f
);
140 if (ignore_enoent
&& r
== -ENOENT
)
143 return log_error_errno(r
, "Failed to open %s, ignoring: %m", path
);
146 log_debug("apply: %s", path
);
148 char line
[LINE_MAX
], *l
;
151 if (!fgets(line
, sizeof(line
), f
)) {
155 return log_error_errno(errno
, "Failed to read file '%s', ignoring: %m", path
);
161 if (strchr(COMMENTS
"\n", *l
))
164 k
= load_module(ctx
, l
);
172 static void help(void) {
173 printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
174 "Loads statically configured kernel modules.\n\n"
175 " -h --help Show this help\n"
176 " --version Show package version\n",
177 program_invocation_short_name
);
180 static int parse_argv(int argc
, char *argv
[]) {
186 static const struct option options
[] = {
187 { "help", no_argument
, NULL
, 'h' },
188 { "version", no_argument
, NULL
, ARG_VERSION
},
197 while ((c
= getopt_long(argc
, argv
, "h", options
, NULL
)) >= 0)
212 assert_not_reached("Unhandled option");
218 int main(int argc
, char *argv
[]) {
220 _cleanup_(kmod_unrefp
) struct kmod_ctx
*ctx
= NULL
;
222 r
= parse_argv(argc
, argv
);
224 return r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;
226 log_set_target(LOG_TARGET_AUTO
);
227 log_parse_environment();
232 r
= proc_cmdline_parse(parse_proc_cmdline_item
, NULL
, PROC_CMDLINE_STRIP_RD_PREFIX
);
234 log_warning_errno(r
, "Failed to parse kernel command line, ignoring: %m");
236 ctx
= kmod_new(NULL
, NULL
);
238 log_error("Failed to allocate memory for kmod.");
242 kmod_load_resources(ctx
);
243 kmod_set_log_fn(ctx
, systemd_kmod_log
, NULL
);
250 for (i
= optind
; i
< argc
; i
++) {
251 k
= apply_file(ctx
, argv
[i
], false);
257 _cleanup_strv_free_
char **files
= NULL
;
260 STRV_FOREACH(i
, arg_proc_cmdline_modules
) {
261 k
= load_module(ctx
, *i
);
266 k
= conf_files_list_nulstr(&files
, ".conf", NULL
, 0, conf_file_dirs
);
268 log_error_errno(k
, "Failed to enumerate modules-load.d files: %m");
274 STRV_FOREACH(fn
, files
) {
275 k
= apply_file(ctx
, *fn
, true);
282 strv_free(arg_proc_cmdline_modules
);
284 return r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;