source: MondoRescue/branches/3.3/mindi-busybox/modutils/modprobe.c@ 3865

Last change on this file since 3865 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

File size: 18.9 KB
RevLine 
[821]1/* vi: set sw=4 ts=4: */
2/*
3 * Modprobe written from scratch for BusyBox
4 *
[2725]5 * Copyright (c) 2008 Timo Teras <timo.teras@iki.fi>
6 * Copyright (c) 2008 Vladimir Dronnikov
[821]7 *
[2725]8 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
9 */
[821]10
[3232]11//applet:IF_MODPROBE(APPLET(modprobe, BB_DIR_SBIN, BB_SUID_DROP))
[2725]12
[3232]13#include "libbb.h"
14#include "modutils.h"
15#include <sys/utsname.h>
16#include <fnmatch.h>
17
[3621]18#if 1
[3232]19#define DBG(...) ((void)0)
[3621]20#else
21#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__)
22#endif
[3232]23
24/* Note that unlike older versions of modules.dep/depmod (busybox and m-i-t),
25 * we expect the full dependency list to be specified in modules.dep.
26 * Older versions would only export the direct dependency list.
27 */
28
29
[2725]30//usage:#if !ENABLE_MODPROBE_SMALL
31//usage:#define modprobe_notes_usage
32//usage: "modprobe can (un)load a stack of modules, passing each module options (when\n"
33//usage: "loading). modprobe uses a configuration file to determine what option(s) to\n"
34//usage: "pass each module it loads.\n"
35//usage: "\n"
36//usage: "The configuration file is searched (in this order):\n"
37//usage: "\n"
38//usage: " /etc/modprobe.conf (2.6 only)\n"
39//usage: " /etc/modules.conf\n"
40//usage: " /etc/conf.modules (deprecated)\n"
41//usage: "\n"
42//usage: "They all have the same syntax (see below). If none is present, it is\n"
43//usage: "_not_ an error; each loaded module is then expected to load without\n"
44//usage: "options. Once a file is found, the others are tested for.\n"
45//usage: "\n"
46//usage: "/etc/modules.conf entry format:\n"
47//usage: "\n"
48//usage: " alias <alias_name> <mod_name>\n"
49//usage: " Makes it possible to modprobe alias_name, when there is no such module.\n"
50//usage: " It makes sense if your mod_name is long, or you want a more representative\n"
51//usage: " name for that module (eg. 'scsi' in place of 'aha7xxx').\n"
52//usage: " This makes it also possible to use a different set of options (below) for\n"
53//usage: " the module and the alias.\n"
54//usage: " A module can be aliased more than once.\n"
55//usage: "\n"
56//usage: " options <mod_name|alias_name> <symbol=value...>\n"
57//usage: " When loading module mod_name (or the module aliased by alias_name), pass\n"
58//usage: " the \"symbol=value\" pairs as option to that module.\n"
59//usage: "\n"
60//usage: "Sample /etc/modules.conf file:\n"
61//usage: "\n"
62//usage: " options tulip irq=3\n"
63//usage: " alias tulip tulip2\n"
64//usage: " options tulip2 irq=4 io=0x308\n"
65//usage: "\n"
66//usage: "Other functionality offered by 'classic' modprobe is not available in\n"
67//usage: "this implementation.\n"
68//usage: "\n"
69//usage: "If module options are present both in the config file, and on the command line,\n"
70//usage: "then the options from the command line will be passed to the module _after_\n"
71//usage: "the options from the config file. That way, you can have defaults in the config\n"
72//usage: "file, and override them for a specific usage from the command line.\n"
73//usage:#define modprobe_example_usage
74//usage: "(with the above /etc/modules.conf):\n\n"
75//usage: "$ modprobe tulip\n"
76//usage: " will load the module 'tulip' with default option 'irq=3'\n\n"
77//usage: "$ modprobe tulip irq=5\n"
78//usage: " will load the module 'tulip' with option 'irq=5', thus overriding the default\n\n"
79//usage: "$ modprobe tulip2\n"
80//usage: " will load the module 'tulip' with default options 'irq=4 io=0x308',\n"
81//usage: " which are the default for alias 'tulip2'\n\n"
82//usage: "$ modprobe tulip2 irq=8\n"
83//usage: " will load the module 'tulip' with default options 'irq=4 io=0x308 irq=8',\n"
84//usage: " which are the default for alias 'tulip2' overridden by the option 'irq=8'\n\n"
85//usage: " from the command line\n\n"
86//usage: "$ modprobe tulip2 irq=2 io=0x210\n"
87//usage: " will load the module 'tulip' with default options 'irq=4 io=0x308 irq=4 io=0x210',\n"
88//usage: " which are the default for alias 'tulip2' overridden by the options 'irq=2 io=0x210'\n\n"
89//usage: " from the command line\n"
90//usage:
91//usage:#define modprobe_trivial_usage
[3232]92//usage: "[-alrqvsD" IF_FEATURE_MODPROBE_BLACKLIST("b") "]"
[3621]93//usage: " MODULE [SYMBOL=VALUE]..."
[2725]94//usage:#define modprobe_full_usage "\n\n"
[3232]95//usage: " -a Load multiple MODULEs"
[2725]96//usage: "\n -l List (MODULE is a pattern)"
97//usage: "\n -r Remove MODULE (stacks) or do autoclean"
98//usage: "\n -q Quiet"
99//usage: "\n -v Verbose"
100//usage: "\n -s Log to syslog"
[3232]101//usage: "\n -D Show dependencies"
[2725]102//usage: IF_FEATURE_MODPROBE_BLACKLIST(
103//usage: "\n -b Apply blacklist to module names too"
104//usage: )
105//usage:#endif /* !ENABLE_MODPROBE_SMALL */
106
[3232]107/* Note: usage text doesn't document various 2.4 options
108 * we pull in through INSMOD_OPTS define
109 * Note2: -b is always accepted, but if !FEATURE_MODPROBE_BLACKLIST,
110 * it is a no-op.
[2725]111 */
[3232]112#define MODPROBE_OPTS "alrDb"
113/* -a and -D _are_ in fact compatible */
114#define MODPROBE_COMPLEMENTARY ("q-v:v-q:l--arD:r--alD:a--lr:D--rl")
115//#define MODPROBE_OPTS "acd:lnrt:C:b"
[2725]116//#define MODPROBE_COMPLEMENTARY "q-v:v-q:l--acr:a--lr:r--al"
117enum {
[3232]118 OPT_INSERT_ALL = (INSMOD_OPT_UNUSED << 0), /* a */
119 //OPT_DUMP_ONLY = (INSMOD_OPT_UNUSED << x), /* c */
120 //OPT_DIRNAME = (INSMOD_OPT_UNUSED << x), /* d */
121 OPT_LIST_ONLY = (INSMOD_OPT_UNUSED << 1), /* l */
122 //OPT_SHOW_ONLY = (INSMOD_OPT_UNUSED << x), /* n */
123 OPT_REMOVE = (INSMOD_OPT_UNUSED << 2), /* r */
124 //OPT_RESTRICT = (INSMOD_OPT_UNUSED << x), /* t */
125 //OPT_VERONLY = (INSMOD_OPT_UNUSED << x), /* V */
126 //OPT_CONFIGFILE = (INSMOD_OPT_UNUSED << x), /* C */
127 OPT_SHOW_DEPS = (INSMOD_OPT_UNUSED << 3), /* D */
128 OPT_BLACKLIST = (INSMOD_OPT_UNUSED << 4) * ENABLE_FEATURE_MODPROBE_BLACKLIST,
[821]129};
[3232]130#if ENABLE_LONG_OPTS
131static const char modprobe_longopts[] ALIGN1 =
132 /* nobody asked for long opts (yet) */
133 // "all\0" No_argument "a"
134 // "list\0" No_argument "l"
135 // "remove\0" No_argument "r"
136 // "quiet\0" No_argument "q"
137 // "verbose\0" No_argument "v"
138 // "syslog\0" No_argument "s"
139 /* module-init-tools 3.11.1 has only long opt --show-depends
140 * but no short -D, we provide long opt for scripts which
141 * were written for 3.11.1: */
142 "show-depends\0" No_argument "D"
143 // "use-blacklist\0" No_argument "b"
144 ;
145#endif
[821]146
[2725]147#define MODULE_FLAG_LOADED 0x0001
148#define MODULE_FLAG_NEED_DEPS 0x0002
149/* "was seen in modules.dep": */
150#define MODULE_FLAG_FOUND_IN_MODDEP 0x0004
151#define MODULE_FLAG_BLACKLISTED 0x0008
[821]152
[2725]153struct globals {
154 llist_t *probes; /* MEs of module(s) requested on cmdline */
155 char *cmdline_mopts; /* module options from cmdline */
156 int num_unresolved_deps;
157 /* bool. "Did we have 'symbol:FOO' requested on cmdline?" */
158 smallint need_symbols;
[3232]159 struct utsname uts;
[3621]160 module_db db;
[2725]161} FIX_ALIASING;
[3232]162#define G (*ptr_to_globals)
163#define INIT_G() do { \
[3621]164 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
[3232]165} while (0)
[821]166
167
[2725]168static int read_config(const char *path);
[821]169
[2725]170static char *gather_options_str(char *opts, const char *append)
[821]171{
[2725]172 /* Speed-optimized. We call gather_options_str many times. */
173 if (append) {
174 if (opts == NULL) {
175 opts = xstrdup(append);
176 } else {
177 int optlen = strlen(opts);
178 opts = xrealloc(opts, optlen + strlen(append) + 2);
179 sprintf(opts + optlen, " %s", append);
180 }
181 }
182 return opts;
[821]183}
184
[3621]185static struct module_entry *get_or_add_modentry(const char *module)
[821]186{
[3621]187 return moddb_get_or_create(&G.db, module);
[821]188}
189
[2725]190static void add_probe(const char *name)
[821]191{
[2725]192 struct module_entry *m;
[821]193
[2725]194 m = get_or_add_modentry(name);
[3232]195 if (!(option_mask32 & (OPT_REMOVE | OPT_SHOW_DEPS))
[2725]196 && (m->flags & MODULE_FLAG_LOADED)
197 ) {
198 DBG("skipping %s, it is already loaded", name);
199 return;
200 }
[821]201
[2725]202 DBG("queuing %s", name);
203 m->probed_name = name;
204 m->flags |= MODULE_FLAG_NEED_DEPS;
205 llist_add_to_end(&G.probes, m);
206 G.num_unresolved_deps++;
207 if (ENABLE_FEATURE_MODUTILS_SYMBOLS
[3621]208 && is_prefixed_with(m->modname, "symbol:")
[1765]209 ) {
[2725]210 G.need_symbols = 1;
[821]211 }
212}
213
[2725]214static int FAST_FUNC config_file_action(const char *filename,
215 struct stat *statbuf UNUSED_PARAM,
216 void *userdata UNUSED_PARAM,
[3621]217 int depth)
[821]218{
[2725]219 char *tokens[3];
220 parser_t *p;
221 struct module_entry *m;
222 int rc = TRUE;
[3621]223 const char *base, *ext;
[821]224
[3621]225 /* Skip files that begin with a "." */
226 base = bb_basename(filename);
227 if (base[0] == '.')
[2725]228 goto error;
[821]229
[3621]230 /* In dir recursion, skip files that do not end with a ".conf"
231 * depth==0: read_config("modules.{symbols,alias}") must work,
232 * "include FILE_NOT_ENDING_IN_CONF" must work too.
233 */
234 if (depth != 0) {
235 ext = strrchr(base, '.');
236 if (ext == NULL || strcmp(ext + 1, "conf"))
237 goto error;
238 }
239
[2725]240 p = config_open2(filename, fopen_for_read);
241 if (p == NULL) {
242 rc = FALSE;
243 goto error;
244 }
[821]245
[2725]246 while (config_read(p, tokens, 3, 2, "# \t", PARSE_NORMAL)) {
247//Use index_in_strings?
248 if (strcmp(tokens[0], "alias") == 0) {
249 /* alias <wildcard> <modulename> */
250 llist_t *l;
251 char wildcard[MODULE_NAME_LEN];
252 char *rmod;
[821]253
[2725]254 if (tokens[2] == NULL)
255 continue;
256 filename2modname(tokens[1], wildcard);
[821]257
[3232]258 for (l = G.probes; l; l = l->link) {
[2725]259 m = (struct module_entry *) l->data;
260 if (fnmatch(wildcard, m->modname, 0) != 0)
261 continue;
262 rmod = filename2modname(tokens[2], NULL);
263 llist_add_to(&m->realnames, rmod);
[821]264
[2725]265 if (m->flags & MODULE_FLAG_NEED_DEPS) {
266 m->flags &= ~MODULE_FLAG_NEED_DEPS;
267 G.num_unresolved_deps--;
[821]268 }
269
[2725]270 m = get_or_add_modentry(rmod);
271 if (!(m->flags & MODULE_FLAG_NEED_DEPS)) {
272 m->flags |= MODULE_FLAG_NEED_DEPS;
273 G.num_unresolved_deps++;
[821]274 }
275 }
[2725]276 } else if (strcmp(tokens[0], "options") == 0) {
277 /* options <modulename> <option...> */
278 if (tokens[2] == NULL)
279 continue;
280 m = get_or_add_modentry(tokens[1]);
281 m->options = gather_options_str(m->options, tokens[2]);
282 } else if (strcmp(tokens[0], "include") == 0) {
[3621]283 /* include <filename>/<dirname> (yes, directories also must work) */
[2725]284 read_config(tokens[1]);
285 } else if (ENABLE_FEATURE_MODPROBE_BLACKLIST
286 && strcmp(tokens[0], "blacklist") == 0
287 ) {
288 /* blacklist <modulename> */
289 get_or_add_modentry(tokens[1])->flags |= MODULE_FLAG_BLACKLISTED;
[821]290 }
291 }
[2725]292 config_close(p);
293 error:
294 return rc;
[821]295}
296
[2725]297static int read_config(const char *path)
[821]298{
[2725]299 return recursive_action(path, ACTION_RECURSE | ACTION_QUIET,
[3621]300 config_file_action, NULL, NULL,
301 /*depth:*/ 0);
[2725]302}
[821]303
[2725]304static const char *humanly_readable_name(struct module_entry *m)
305{
306 /* probed_name may be NULL. modname always exists. */
307 return m->probed_name ? m->probed_name : m->modname;
308}
[821]309
[3621]310/* Like strsep(&stringp, "\n\t ") but quoted text goes to single token
311 * even if it contains whitespace.
312 */
313static char *strsep_quotes(char **stringp)
314{
315 char *s, *start = *stringp;
316
317 if (!start)
318 return NULL;
319
320 for (s = start; ; s++) {
321 switch (*s) {
322 case '"':
323 s = strchrnul(s + 1, '"'); /* find trailing quote */
324 if (*s != '\0')
325 s++; /* skip trailing quote */
326 /* fall through */
327 case '\0':
328 case '\n':
329 case '\t':
330 case ' ':
331 if (*s != '\0') {
332 *s = '\0';
333 *stringp = s + 1;
334 } else {
335 *stringp = NULL;
336 }
337 return start;
338 }
339 }
340}
341
[2725]342static char *parse_and_add_kcmdline_module_options(char *options, const char *modulename)
343{
344 char *kcmdline_buf;
345 char *kcmdline;
346 char *kptr;
[821]347
[2725]348 kcmdline_buf = xmalloc_open_read_close("/proc/cmdline", NULL);
349 if (!kcmdline_buf)
350 return options;
[821]351
[2725]352 kcmdline = kcmdline_buf;
[3621]353 while ((kptr = strsep_quotes(&kcmdline)) != NULL) {
354 char *after_modulename = is_prefixed_with(kptr, modulename);
355 if (!after_modulename || *after_modulename != '.')
[821]356 continue;
[2725]357 /* It is "modulename.xxxx" */
[3621]358 kptr = after_modulename + 1;
[2725]359 if (strchr(kptr, '=') != NULL) {
360 /* It is "modulename.opt=[val]" */
361 options = gather_options_str(options, kptr);
[821]362 }
363 }
[2725]364 free(kcmdline_buf);
[821]365
[2725]366 return options;
[821]367}
368
[2725]369/* Return: similar to bb_init_module:
370 * 0 on success,
371 * -errno on open/read error,
372 * errno on init_module() error
373 */
374/* NB: INSMOD_OPT_SILENT bit suppresses ONLY non-existent modules,
375 * not deleted ones (those are still listed in modules.dep).
376 * module-init-tools version 3.4:
377 * # modprobe bogus
378 * FATAL: Module bogus not found. [exitcode 1]
379 * # modprobe -q bogus [silent, exitcode still 1]
380 * but:
381 * # rm kernel/drivers/net/dummy.ko
382 * # modprobe -q dummy
383 * FATAL: Could not open '/lib/modules/xxx/kernel/drivers/net/dummy.ko': No such file or directory
384 * [exitcode 1]
385 */
386static int do_modprobe(struct module_entry *m)
[821]387{
[2725]388 int rc, first;
[821]389
[2725]390 if (!(m->flags & MODULE_FLAG_FOUND_IN_MODDEP)) {
391 if (!(option_mask32 & INSMOD_OPT_SILENT))
392 bb_error_msg("module %s not found in modules.dep",
393 humanly_readable_name(m));
394 return -ENOENT;
395 }
396 DBG("do_modprob'ing %s", m->modname);
[821]397
[3232]398 if (!(option_mask32 & OPT_REMOVE))
[2725]399 m->deps = llist_rev(m->deps);
[821]400
[3232]401 if (0) {
402 llist_t *l;
403 for (l = m->deps; l; l = l->link)
404 DBG("dep: %s", l->data);
405 }
[821]406
[2725]407 first = 1;
408 rc = 0;
409 while (m->deps) {
[3232]410 struct module_entry *m2;
411 char *fn, *options;
412
[2725]413 rc = 0;
414 fn = llist_pop(&m->deps); /* we leak it */
[3621]415 m2 = get_or_add_modentry(bb_get_last_path_component_nostrip(fn));
[821]416
[3232]417 if (option_mask32 & OPT_REMOVE) {
[2725]418 /* modprobe -r */
419 if (m2->flags & MODULE_FLAG_LOADED) {
420 rc = bb_delete_module(m2->modname, O_EXCL);
421 if (rc) {
422 if (first) {
[3621]423 bb_perror_msg("can't unload module '%s'",
424 humanly_readable_name(m2));
[2725]425 break;
426 }
427 } else {
428 m2->flags &= ~MODULE_FLAG_LOADED;
[821]429 }
430 }
[2725]431 /* do not error out if *deps* fail to unload */
432 first = 0;
433 continue;
[821]434 }
435
[3232]436 options = m2->options;
437 m2->options = NULL;
438 options = parse_and_add_kcmdline_module_options(options, m2->modname);
439 if (m == m2)
440 options = gather_options_str(options, G.cmdline_mopts);
441
442 if (option_mask32 & OPT_SHOW_DEPS) {
443 printf(options ? "insmod %s/%s/%s %s\n"
444 : "insmod %s/%s/%s\n",
445 CONFIG_DEFAULT_MODULES_DIR, G.uts.release, fn,
446 options);
447 free(options);
448 continue;
449 }
450
[2725]451 if (m2->flags & MODULE_FLAG_LOADED) {
452 DBG("%s is already loaded, skipping", fn);
[3232]453 free(options);
[2725]454 continue;
[821]455 }
456
[2725]457 rc = bb_init_module(fn, options);
458 DBG("loaded %s '%s', rc:%d", fn, options, rc);
459 if (rc == EEXIST)
460 rc = 0;
461 free(options);
462 if (rc) {
463 bb_error_msg("can't load module %s (%s): %s",
464 humanly_readable_name(m2),
465 fn,
466 moderror(rc)
467 );
468 break;
[821]469 }
[2725]470 m2->flags |= MODULE_FLAG_LOADED;
[821]471 }
[2725]472
473 return rc;
[821]474}
475
[2725]476static void load_modules_dep(void)
[1765]477{
[2725]478 struct module_entry *m;
479 char *colon, *tokens[2];
480 parser_t *p;
[1765]481
[2725]482 /* Modprobe does not work at all without modules.dep,
483 * even if the full module name is given. Returning error here
484 * was making us later confuse user with this message:
485 * "module /full/path/to/existing/file/module.ko not found".
486 * It's better to die immediately, with good message.
487 * xfopen_for_read provides that. */
488 p = config_open2(CONFIG_DEFAULT_DEPMOD_FILE, xfopen_for_read);
[1765]489
[2725]490 while (G.num_unresolved_deps
491 && config_read(p, tokens, 2, 1, "# \t", PARSE_NORMAL)
492 ) {
493 colon = last_char_is(tokens[0], ':');
494 if (colon == NULL)
495 continue;
[3621]496 *colon = '\0';
[1765]497
[3621]498 m = moddb_get(&G.db, bb_get_last_path_component_nostrip(tokens[0]));
[2725]499 if (m == NULL)
500 continue;
[1765]501
[2725]502 /* Optimization... */
503 if ((m->flags & MODULE_FLAG_LOADED)
[3232]504 && !(option_mask32 & (OPT_REMOVE | OPT_SHOW_DEPS))
[2725]505 ) {
506 DBG("skip deps of %s, it's already loaded", tokens[0]);
507 continue;
[1765]508 }
509
[2725]510 m->flags |= MODULE_FLAG_FOUND_IN_MODDEP;
511 if ((m->flags & MODULE_FLAG_NEED_DEPS) && (m->deps == NULL)) {
512 G.num_unresolved_deps--;
513 llist_add_to(&m->deps, xstrdup(tokens[0]));
514 if (tokens[1])
515 string_to_llist(tokens[1], &m->deps, " \t");
516 } else
517 DBG("skipping dep line");
[1765]518 }
[2725]519 config_close(p);
[1765]520}
521
[2725]522int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
523int modprobe_main(int argc UNUSED_PARAM, char **argv)
[821]524{
[2725]525 int rc;
526 unsigned opt;
527 struct module_entry *me;
[821]528
[3232]529 INIT_G();
530
531 IF_LONG_OPTS(applet_long_options = modprobe_longopts;)
[2725]532 opt_complementary = MODPROBE_COMPLEMENTARY;
533 opt = getopt32(argv, INSMOD_OPTS MODPROBE_OPTS INSMOD_ARGS);
534 argv += optind;
[821]535
[2725]536 /* Goto modules location */
537 xchdir(CONFIG_DEFAULT_MODULES_DIR);
[3232]538 uname(&G.uts);
539 xchdir(G.uts.release);
[821]540
[3232]541 if (opt & OPT_LIST_ONLY) {
542 int i;
[2725]543 char *colon, *tokens[2];
544 parser_t *p = config_open2(CONFIG_DEFAULT_DEPMOD_FILE, xfopen_for_read);
[821]545
[3232]546 for (i = 0; argv[i]; i++)
547 replace(argv[i], '-', '_');
548
[2725]549 while (config_read(p, tokens, 2, 1, "# \t", PARSE_NORMAL)) {
550 colon = last_char_is(tokens[0], ':');
551 if (!colon)
552 continue;
553 *colon = '\0';
554 if (!argv[0])
555 puts(tokens[0]);
556 else {
[3621]557 char name[MODULE_NAME_LEN];
558 filename2modname(
559 bb_get_last_path_component_nostrip(tokens[0]),
560 name
561 );
[2725]562 for (i = 0; argv[i]; i++) {
563 if (fnmatch(argv[i], name, 0) == 0) {
564 puts(tokens[0]);
565 }
[821]566 }
567 }
568 }
[2725]569 return EXIT_SUCCESS;
[821]570 }
571
[2725]572 /* Yes, for some reason -l ignores -s... */
573 if (opt & INSMOD_OPT_SYSLOG)
574 logmode = LOGMODE_SYSLOG;
[821]575
[2725]576 if (!argv[0]) {
[3232]577 if (opt & OPT_REMOVE) {
[2725]578 /* "modprobe -r" (w/o params).
579 * "If name is NULL, all unused modules marked
580 * autoclean will be removed".
581 */
582 if (bb_delete_module(NULL, O_NONBLOCK | O_EXCL) != 0)
[3621]583 bb_perror_nomsg_and_die();
[821]584 }
[2725]585 return EXIT_SUCCESS;
[821]586 }
587
[2725]588 /* Retrieve module names of already loaded modules */
589 {
590 char *s;
591 parser_t *parser = config_open2("/proc/modules", fopen_for_read);
592 while (config_read(parser, &s, 1, 1, "# \t", PARSE_NORMAL & ~PARSE_GREEDY))
593 get_or_add_modentry(s)->flags |= MODULE_FLAG_LOADED;
594 config_close(parser);
[821]595 }
596
[3232]597 if (opt & (OPT_INSERT_ALL | OPT_REMOVE)) {
[2725]598 /* Each argument is a module name */
599 do {
600 DBG("adding module %s", *argv);
601 add_probe(*argv++);
602 } while (*argv);
603 } else {
604 /* First argument is module name, rest are parameters */
605 DBG("probing just module %s", *argv);
606 add_probe(argv[0]);
[3232]607 G.cmdline_mopts = parse_cmdline_module_options(argv, /*quote_spaces:*/ 1);
[2725]608 }
[821]609
[2725]610 /* Happens if all requested modules are already loaded */
611 if (G.probes == NULL)
612 return EXIT_SUCCESS;
[821]613
[2725]614 read_config("/etc/modprobe.conf");
615 read_config("/etc/modprobe.d");
616 if (ENABLE_FEATURE_MODUTILS_SYMBOLS && G.need_symbols)
617 read_config("modules.symbols");
618 load_modules_dep();
619 if (ENABLE_FEATURE_MODUTILS_ALIAS && G.num_unresolved_deps) {
620 read_config("modules.alias");
621 load_modules_dep();
[821]622 }
623
[2725]624 rc = 0;
625 while ((me = llist_pop(&G.probes)) != NULL) {
626 if (me->realnames == NULL) {
627 DBG("probing by module name");
628 /* This is not an alias. Literal names are blacklisted
629 * only if '-b' is given.
[902]630 */
[3232]631 if (!(opt & OPT_BLACKLIST)
[2725]632 || !(me->flags & MODULE_FLAG_BLACKLISTED)
633 ) {
634 rc |= do_modprobe(me);
635 }
636 continue;
[902]637 }
[821]638
[2725]639 /* Probe all real names for the alias */
640 do {
641 char *realname = llist_pop(&me->realnames);
642 struct module_entry *m2;
[821]643
[2725]644 DBG("probing alias %s by realname %s", me->modname, realname);
645 m2 = get_or_add_modentry(realname);
646 if (!(m2->flags & MODULE_FLAG_BLACKLISTED)
647 && (!(m2->flags & MODULE_FLAG_LOADED)
[3232]648 || (opt & (OPT_REMOVE | OPT_SHOW_DEPS)))
[2725]649 ) {
650//TODO: we can pass "me" as 2nd param to do_modprobe,
651//and make do_modprobe emit more meaningful error messages
652//with alias name included, not just module name alias resolves to.
653 rc |= do_modprobe(m2);
[821]654 }
[2725]655 free(realname);
656 } while (me->realnames != NULL);
[821]657 }
658
[3621]659 if (ENABLE_FEATURE_CLEAN_UP)
660 moddb_free(&G.db);
661
[2725]662 return (rc != 0);
[821]663}
Note: See TracBrowser for help on using the repository browser.