build: remove explicit call to build modules.dep.bin
[mit.git] / modprobe.c
blobd16151ae3b82996a2486e68f35955c7adbd49a81
1 /* modprobe.c: add or remove a module from the kernel, intelligently.
2 Copyright (C) 2001 Rusty Russell.
3 Copyright (C) 2002, 2003 Rusty Russell, IBM Corporation.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #define _GNU_SOURCE /* asprintf */
21 #include <sys/utsname.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <sys/mman.h>
25 #include <fcntl.h>
26 #include <stdarg.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <ctype.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <unistd.h>
33 #include <dirent.h>
34 #include <limits.h>
35 #include <elf.h>
36 #include <getopt.h>
37 #include <fnmatch.h>
38 #include <asm/unistd.h>
39 #include <sys/wait.h>
40 #include <syslog.h>
42 #include "util.h"
43 #include "elfops.h"
44 #include "zlibsupport.h"
45 #include "logging.h"
46 #include "index.h"
47 #include "list.h"
48 #include "config_filter.h"
50 #include "testing.h"
52 int use_binary_indexes = 1; /* default to enabled. */
54 /* Limit do_softdep/do_modprobe recursion.
55 * This is a simple way to handle dependency loops
56 * caused by poorly written softdep commands.
58 static int recursion_depth = 0;
59 const int MAX_RECURSION = 50; /* Arbitrary choice */
61 extern long init_module(void *, unsigned long, const char *);
62 extern long delete_module(const char *, unsigned int);
64 struct module {
65 struct list_head list;
66 char *modname;
67 char filename[0];
70 typedef enum
72 mit_remove = 1,
73 mit_dry_run = 2,
74 mit_first_time = 4,
75 mit_use_blacklist = 8,
76 mit_ignore_commands = 16,
77 mit_ignore_loaded = 32,
78 mit_quiet_inuse = 64,
79 mit_strip_vermagic = 128,
80 mit_strip_modversion = 256,
81 mit_resolve_alias = 512
83 } modprobe_flags_t;
85 #ifndef MODULE_DIR
86 #define MODULE_DIR "/lib/modules"
87 #endif
89 static void print_usage(const char *progname)
91 fprintf(stderr,
92 "Usage: %s [-v] [-V] [-C config-file] [-d <dirname> ] [-n] [-i] [-q] [-b] [-o <modname>] [ --dump-modversions ] <modname> [parameters...]\n"
93 "%s -r [-n] [-i] [-v] <modulename> ...\n"
94 "%s -l -t <dirname> [ -a <modulename> ...]\n",
95 progname, progname, progname);
96 exit(1);
99 static struct module *find_module(const char *filename, struct list_head *list)
101 struct module *i;
103 list_for_each_entry(i, list, list) {
104 if (streq(i->filename, filename))
105 return i;
107 return NULL;
110 static void add_module(char *filename, int namelen, struct list_head *list)
112 struct module *mod;
114 /* If it's a duplicate: move it to the end, so it gets
115 inserted where it is *first* required. */
116 mod = find_module(filename, list);
117 if (mod)
118 list_del(&mod->list);
119 else {
120 /* No match. Create a new module. */
121 mod = NOFAIL(malloc(sizeof(struct module) + namelen + 1));
122 memcpy(mod->filename, filename, namelen);
123 mod->filename[namelen] = '\0';
124 mod->modname = NOFAIL(malloc(namelen + 1));
125 filename2modname(mod->modname, mod->filename);
128 list_add_tail(&mod->list, list);
131 static void free_module(struct module *mod)
133 free(mod->modname);
134 free(mod);
137 /* Compare len chars of a to b, with _ and - equivalent. */
138 static int modname_equal(const char *a, const char *b, unsigned int len)
140 unsigned int i;
142 if (strlen(b) != len)
143 return 0;
145 for (i = 0; i < len; i++) {
146 if ((a[i] == '_' || a[i] == '-')
147 && (b[i] == '_' || b[i] == '-'))
148 continue;
149 if (a[i] != b[i])
150 return 0;
152 return 1;
155 /* Fills in list of modules if this is the line we want. */
156 static int add_modules_dep_line(char *line,
157 const char *name,
158 struct list_head *list,
159 const char *dirname)
161 char *ptr;
162 int len;
163 char *modname, *fullpath;
165 /* Ignore lines without : or which start with a # */
166 ptr = strchr(line, ':');
167 if (ptr == NULL || line[strspn(line, "\t ")] == '#')
168 return 0;
170 /* Is this the module we are looking for? */
171 *ptr = '\0';
172 modname = my_basename(line);
174 len = strlen(modname);
175 if (strchr(modname, '.'))
176 len = strchr(modname, '.') - modname;
177 if (!modname_equal(modname, name, len))
178 return 0;
180 /* Create the list. */
181 if ('/' == line[0]) { /* old style deps - absolute path specified */
182 add_module(line, ptr - line, list);
183 } else {
184 nofail_asprintf(&fullpath, "%s/%s", dirname, line);
185 add_module(fullpath, strlen(dirname)+1+(ptr - line), list);
186 free(fullpath);
189 ptr++;
190 for(;;) {
191 char *dep_start;
192 ptr += strspn(ptr, " \t");
193 if (*ptr == '\0')
194 break;
195 dep_start = ptr;
196 ptr += strcspn(ptr, " \t");
197 if ('/' == dep_start[0]) { /* old style deps */
198 add_module(dep_start, ptr - dep_start, list);
199 } else {
200 nofail_asprintf(&fullpath, "%s/%s", dirname, dep_start);
201 add_module(fullpath,
202 strlen(dirname)+1+(ptr - dep_start), list);
203 free(fullpath);
206 return 1;
209 static int read_depends_file(const char *dirname,
210 const char *start_name,
211 struct list_head *list)
213 char *modules_dep_name;
214 char *line;
215 struct index_file *modules_dep;
217 nofail_asprintf(&modules_dep_name, "%s/%s", dirname, "modules.dep.bin");
218 modules_dep = index_file_open(modules_dep_name);
219 if (!modules_dep) {
220 free(modules_dep_name);
221 return 0;
224 line = index_search(modules_dep, start_name);
225 if (line) {
226 /* Value is standard dependency line format */
227 if (!add_modules_dep_line(line, start_name, list, dirname))
228 fatal("Module index is inconsistent\n");
229 free(line);
232 index_file_close(modules_dep);
233 free(modules_dep_name);
235 return 1;
238 static void read_depends(const char *dirname,
239 const char *start_name,
240 struct list_head *list)
242 char *modules_dep_name;
243 char *line;
244 FILE *modules_dep;
245 int done = 0;
247 if (use_binary_indexes)
248 if (read_depends_file(dirname, start_name, list))
249 return;
251 nofail_asprintf(&modules_dep_name, "%s/%s", dirname, "modules.dep");
252 modules_dep = fopen(modules_dep_name, "r");
253 if (!modules_dep)
254 fatal("Could not load %s: %s\n",
255 modules_dep_name, strerror(errno));
257 /* Stop at first line, as we can have duplicates (eg. symlinks
258 from boot/ */
259 while (!done && (line = getline_wrapped(modules_dep, NULL)) != NULL) {
260 done = add_modules_dep_line(line, start_name, list, dirname);
261 free(line);
263 fclose(modules_dep);
264 free(modules_dep_name);
267 /* We use error numbers in a loose translation... */
268 static const char *insert_moderror(int err)
270 switch (err) {
271 case ENOEXEC:
272 return "Invalid module format";
273 case ENOENT:
274 return "Unknown symbol in module, or unknown parameter (see dmesg)";
275 case ENOSYS:
276 return "Kernel does not have module support";
277 default:
278 return strerror(err);
282 static const char *remove_moderror(int err)
284 switch (err) {
285 case ENOENT:
286 return "No such module";
287 case ENOSYS:
288 return "Kernel does not have module unloading support";
289 default:
290 return strerror(err);
294 static void replace_modname(struct elf_file *module,
295 void *mem, unsigned long len,
296 const char *oldname, const char *newname)
298 char *p;
300 /* 64 - sizeof(unsigned long) - 1 */
301 if (strlen(newname) > 55)
302 fatal("New name %s is too long\n", newname);
304 /* Find where it is in the module structure. Don't assume layout! */
305 for (p = mem; p < (char *)mem + len - strlen(oldname); p++) {
306 if (memcmp(p, oldname, strlen(oldname)) == 0) {
307 strcpy(p, newname);
308 return;
312 warn("Could not find old name in %s to replace!\n", module->pathname);
315 static void rename_module(struct elf_file *module,
316 const char *oldname,
317 const char *newname)
319 void *modstruct;
320 unsigned long len;
322 /* Old-style */
323 modstruct = module->ops->load_section(module,
324 ".gnu.linkonce.this_module", &len);
325 /* New-style */
326 if (!modstruct)
327 modstruct = module->ops->load_section(module, "__module", &len);
328 if (!modstruct)
329 warn("Could not find module name to change in %s\n",
330 module->pathname);
331 else
332 replace_modname(module, modstruct, len, oldname, newname);
335 static void clear_magic(struct elf_file *module)
337 struct string_table *tbl;
338 int j;
340 /* Old-style: __vermagic section */
341 module->ops->strip_section(module, "__vermagic");
343 /* New-style: in .modinfo section */
344 tbl = module->ops->load_strings(module, ".modinfo", NULL);
345 for (j = 0; tbl && j < tbl->cnt; j++) {
346 const char *p = tbl->str[j];
347 if (strstarts(p, "vermagic=")) {
348 memset((char *)p, 0, strlen(p));
349 return;
354 struct module_options
356 struct module_options *next;
357 char *modulename;
358 char *options;
361 struct module_command
363 struct module_command *next;
364 char *modulename;
365 char *command;
368 struct module_alias
370 struct module_alias *next;
371 char *aliasname;
372 char *module;
375 struct module_blacklist
377 struct module_blacklist *next;
378 char *modulename;
381 struct module_softdep
383 struct module_softdep *next;
384 char *buf;
385 /* The modname and string tables point to buf. */
386 char *modname;
387 struct string_table *pre;
388 struct string_table *post;
391 struct modprobe_conf
393 struct module_options *options;
394 struct module_command *commands;
395 struct module_alias *aliases;
396 struct module_blacklist *blacklist;
397 struct module_softdep *softdeps;
400 /* Link in a new option line from the config file. */
401 static struct module_options *
402 add_options(const char *modname,
403 const char *option,
404 struct module_options *options)
406 struct module_options *new;
407 char *tab;
409 new = NOFAIL(malloc(sizeof(*new)));
410 new->modulename = NOFAIL(strdup(modname));
411 new->options = NOFAIL(strdup(option));
412 /* We can handle tabs, kernel can't. */
413 for (tab = strchr(new->options, '\t'); tab; tab = strchr(tab, '\t'))
414 *tab = ' ';
415 new->next = options;
416 return new;
419 /* Link in a new install line from the config file. */
420 static struct module_command *
421 add_command(const char *modname,
422 const char *command,
423 struct module_command *commands)
425 struct module_command *new;
427 new = NOFAIL(malloc(sizeof(*new)));
428 new->modulename = NOFAIL(strdup(modname));
429 new->command = NOFAIL(strdup(command));
430 new->next = commands;
431 return new;
434 /* Link in a new alias line from the config file. */
435 static struct module_alias *
436 add_alias(const char *aliasname, const char *modname, struct module_alias *aliases)
438 struct module_alias *new;
440 new = NOFAIL(malloc(sizeof(*new)));
441 new->aliasname = NOFAIL(strdup(aliasname));
442 new->module = NOFAIL(strdup(modname));
443 new->next = aliases;
444 return new;
448 /* Return a list of matching aliases */
449 static struct module_alias *
450 find_aliases(const struct module_alias *aliases,
451 const char *name)
453 struct module_alias *result = NULL;
454 while (aliases) {
455 char *aliasname = aliases->aliasname;
456 char *modname = aliases->module;
457 if (fnmatch(aliasname, name, 0) == 0)
458 result = add_alias(aliasname, modname, result);
459 aliases = aliases->next;
461 return result;
464 static void free_aliases(struct module_alias *alias_list)
466 while (alias_list) {
467 struct module_alias *alias;
469 alias = alias_list;
470 alias_list = alias_list->next;
472 free(alias->aliasname);
473 free(alias->module);
474 free(alias);
478 /* Link in a new blacklist line from the config file. */
479 static struct module_blacklist *
480 add_blacklist(const char *modname, struct module_blacklist *blacklist)
482 struct module_blacklist *new;
484 new = NOFAIL(malloc(sizeof(*new)));
485 new->modulename = NOFAIL(strdup(modname));
486 new->next = blacklist;
487 return new;
490 /* Find blacklist commands if any. */
491 static int
492 find_blacklist(const char *modname, const struct module_blacklist *blacklist)
494 while (blacklist) {
495 if (streq(blacklist->modulename, modname))
496 return 1;
497 blacklist = blacklist->next;
499 return 0;
502 /* delete backlisted elems from a list of aliases */
503 static void
504 apply_blacklist(struct module_alias **aliases,
505 const struct module_blacklist *blacklist)
507 struct module_alias *result = NULL;
508 struct module_alias *alias = *aliases;
509 while (alias) {
510 char *modname = alias->module;
511 if (!find_blacklist(modname, blacklist))
512 result = add_alias(alias->aliasname, modname, result);
513 alias = alias->next;
515 free_aliases(*aliases);
516 *aliases = result;
519 /* Find install commands if any. */
520 static const char *find_command(const char *modname,
521 const struct module_command *commands)
523 while (commands) {
524 if (fnmatch(commands->modulename, modname, 0) == 0)
525 return commands->command;
526 commands = commands->next;
528 return NULL;
531 /* Find soft dependencies, if any. */
532 static const struct module_softdep *
533 find_softdep(const char *modname, const struct module_softdep *softdeps)
535 while (softdeps) {
536 if (fnmatch(softdeps->modname, modname, 0) == 0)
537 return softdeps;
538 softdeps = softdeps->next;
540 return NULL;
543 static char *append_option(char *options, const char *newoption)
545 options = NOFAIL(realloc(options, strlen(options) + 1
546 + strlen(newoption) + 1));
547 if (strlen(options)) strcat(options, " ");
548 strcat(options, newoption);
549 return options;
552 static char *prepend_option(char *options, const char *newoption)
554 size_t l1, l2;
555 l1 = strlen(options);
556 l2 = strlen(newoption);
557 /* the resulting string will look like
558 * newoption + ' ' + options + '\0' */
559 if (l1) {
560 options = NOFAIL(realloc(options, l2 + 1 + l1 + 1));
561 memmove(options + l2 + 1, options, l1 + 1);
562 options[l2] = ' ';
563 memcpy(options, newoption, l2);
564 } else {
565 options = NOFAIL(realloc(options, l2 + 1));
566 memcpy(options, newoption, l2);
567 options[l2] = '\0';
569 return options;
572 /* Add to options */
573 static char *add_extra_options(const char *modname,
574 const char *optstring,
575 const struct module_options *options)
577 char *opts = NOFAIL(strdup(optstring));
579 while (options) {
580 if (streq(options->modulename, modname))
581 opts = prepend_option(opts, options->options);
582 options = options->next;
584 return opts;
587 /* Is module in /proc/modules? If so, fill in usecount if not NULL.
588 0 means no, 1 means yes, -1 means unknown.
590 static int module_in_procfs(const char *modname, unsigned int *usecount)
592 FILE *proc_modules;
593 char *line;
595 again:
596 /* Might not be mounted yet. Don't fail. */
597 proc_modules = fopen("/proc/modules", "r");
598 if (!proc_modules)
599 return -1;
601 while ((line = getline_wrapped(proc_modules, NULL)) != NULL) {
602 char *entry = strtok(line, " \n");
604 if (entry && streq(entry, modname)) {
605 /* If it exists, usecount is the third entry. */
606 if (!strtok(NULL, " \n"))
607 goto out;
609 if (!(entry = strtok(NULL, " \n"))) /* usecount */
610 goto out;
611 else
612 if (usecount)
613 *usecount = atoi(entry);
615 /* Followed by - then status. */
616 if (strtok(NULL, " \n")
617 && (entry = strtok(NULL, " \n")) != NULL) {
618 /* No locking, we might hit cases
619 * where module is in flux. Spin. */
620 if (streq(entry, "Loading")
621 || streq(entry, "Unloading")) {
622 usleep(100000);
623 free(line);
624 fclose(proc_modules);
625 goto again;
629 out:
630 free(line);
631 fclose(proc_modules);
632 return 1;
634 free(line);
636 fclose(proc_modules);
637 return 0;
640 /* Read sysfs attribute into a buffer.
641 * returns: 1 = ok, 0 = attribute missing,
642 * -1 = file error (or empty file, but we don't care).
644 static int read_attribute(const char *filename, char *buf, size_t buflen)
646 FILE *file;
647 char *s;
649 file = fopen(filename, "r");
650 if (file == NULL)
651 return (errno == ENOENT) ? 0 : -1;
652 s = fgets(buf, buflen, file);
653 fclose(file);
655 return (s == NULL) ? -1 : 1;
658 /* is this a built-in module?
659 * 0: no, 1: yes, -1: don't know
661 static int module_builtin(const char *dirname, const char *modname)
663 struct index_file *index;
664 char *filename, *value;
666 nofail_asprintf(&filename, "%s/modules.builtin.bin", dirname);
667 index = index_file_open(filename);
668 free(filename);
669 if (!index)
670 return -1;
671 value = index_search(index, modname);
672 free(value);
673 return value ? 1 : 0;
676 /* Is module in /sys/module? If so, fill in usecount if not NULL.
677 0 means no, 1 means yes, -1 means unknown.
679 static int module_in_sysfs(const char *modname, unsigned int *usecount)
681 int ret;
682 char *name;
683 struct stat finfo;
685 const int ATTR_LEN = 16;
686 char attr[ATTR_LEN];
688 /* Check sysfs is mounted */
689 if (stat("/sys/module", &finfo) < 0)
690 return -1;
692 /* Find module. */
693 nofail_asprintf(&name, "/sys/module/%s", modname);
694 ret = stat(name, &finfo);
695 free(name);
696 if (ret < 0)
697 return (errno == ENOENT) ? 0 : -1; /* Not found or unknown. */
699 nofail_asprintf(&name, "/sys/module/%s/initstate", modname);
700 ret = read_attribute(name, attr, ATTR_LEN);
701 if (ret == 0) {
702 free(name);
703 nofail_asprintf(&name, "/sys/module/%s", modname);
704 if (stat(name, &finfo) < 0) {
705 /* module was removed before we could read initstate */
706 ret = 0;
707 } else {
708 /* initstate not available (2.6.19 or earlier) */
709 ret = -1;
711 free(name);
712 return ret;
715 /* Wait for the existing module to either go live or disappear. */
716 while (ret == 1 && !streq(attr, "live\n")) {
717 usleep(100000);
718 ret = read_attribute(name, attr, ATTR_LEN);
720 free(name);
722 if (ret != 1)
723 return ret;
725 /* Get reference count, if it exists. */
726 if (usecount != NULL) {
727 nofail_asprintf(&name, "/sys/module/%s/refcnt", modname);
728 ret = read_attribute(name, attr, ATTR_LEN);
729 free(name);
730 if (ret == 1)
731 *usecount = atoi(attr);
734 return 1;
737 /* Is module loaded? If so, fill in usecount if not NULL.
738 0 means no, 1 means yes, -1 means unknown.
740 static int module_in_kernel(const char *modname, unsigned int *usecount)
742 int result;
744 result = module_in_sysfs(modname, usecount);
745 if (result != -1)
746 return result;
748 /* /sys/module/%s/initstate is only available since 2.6.20,
749 fallback to /proc/modules to get module state on earlier kernels. */
750 return module_in_procfs(modname, usecount);
753 void dump_modversions(const char *filename, errfn_t error)
755 struct elf_file *module;
757 module = grab_elf_file(filename);
758 if (!module) {
759 error("%s: %s\n", filename, strerror(errno));
760 return;
762 if (module->ops->dump_modvers(module) < 0)
763 error("Wrong section size in '%s'\n", filename);
764 release_elf_file(module);
767 /* Does path contain directory(s) subpath? */
768 static int type_matches(const char *path, const char *subpath)
770 char *subpath_with_slashes;
771 int ret;
773 nofail_asprintf(&subpath_with_slashes, "/%s/", subpath);
775 ret = (strstr(path, subpath_with_slashes) != NULL);
776 free(subpath_with_slashes);
777 return ret;
781 static int do_wildcard(const char *dirname,
782 const char *type,
783 const char *wildcard)
785 char *modules_dep_name;
786 char *line, *wcard;
787 FILE *modules_dep;
789 /* Canonicalize wildcard */
790 wcard = strdup(wildcard);
791 underscores(wcard);
793 nofail_asprintf(&modules_dep_name, "%s/%s", dirname, "modules.dep");
794 modules_dep = fopen(modules_dep_name, "r");
795 if (!modules_dep)
796 fatal("Could not load %s: %s\n",
797 modules_dep_name, strerror(errno));
799 while ((line = getline_wrapped(modules_dep, NULL)) != NULL) {
800 char *ptr;
802 /* Ignore lines without : or which start with a # */
803 ptr = strchr(line, ':');
804 if (ptr == NULL || line[strspn(line, "\t ")] == '#')
805 goto next;
806 *ptr = '\0';
808 /* "type" must match complete directory component(s). */
809 if (!type || type_matches(line, type)) {
810 char modname[strlen(line)+1];
812 filename2modname(modname, line);
813 if (fnmatch(wcard, modname, 0) == 0)
814 printf("%s\n", line);
816 next:
817 free(line);
820 free(modules_dep_name);
821 free(wcard);
822 return 0;
825 static char *strsep_skipspace(char **string, char *delim)
827 if (!*string)
828 return NULL;
829 *string += strspn(*string, delim);
830 return strsep(string, delim);
833 static int parse_config_scan(const char *filename,
834 struct modprobe_conf *conf,
835 int dump_only,
836 int removing);
838 static int parse_config_file(const char *filename,
839 struct modprobe_conf *conf,
840 int dump_only,
841 int removing)
843 char *line;
844 unsigned int linenum = 0;
845 FILE *cfile;
847 struct module_options **options = &conf->options;
848 struct module_command **commands = &conf->commands;
849 struct module_alias **aliases = &conf->aliases;
850 struct module_blacklist **blacklist = &conf->blacklist;
852 cfile = fopen(filename, "r");
853 if (!cfile)
854 return 0;
856 while ((line = getline_wrapped(cfile, &linenum)) != NULL) {
857 char *ptr = line;
858 char *cmd, *modname;
860 if (dump_only)
861 printf("%s\n", line);
863 cmd = strsep_skipspace(&ptr, "\t ");
864 if (cmd == NULL || cmd[0] == '#' || cmd[0] == '\0') {
865 free(line);
866 continue;
869 if (streq(cmd, "alias")) {
870 char *wildcard = strsep_skipspace(&ptr, "\t ");
871 char *realname = strsep_skipspace(&ptr, "\t ");
872 if (!wildcard || !realname)
873 goto syntax_error;
874 *aliases = add_alias(underscores(wildcard),
875 underscores(realname),
876 *aliases);
877 } else if (streq(cmd, "include")) {
878 struct modprobe_conf newconf = *conf;
879 newconf.aliases = NULL;
880 char *newfilename;
881 newfilename = strsep_skipspace(&ptr, "\t ");
882 if (!newfilename)
883 goto syntax_error;
885 warn("\"include %s\" is deprecated, "
886 "please use /etc/modprobe.d\n", newfilename);
887 if (strstarts(newfilename, "/etc/modprobe.d")) {
888 warn("\"include /etc/modprobe.d\" is "
889 "the default, ignored\n");
890 } else {
891 if (!parse_config_scan(newfilename,
892 &newconf, dump_only,
893 removing))
894 warn("Failed to open included"
895 " config file %s: %s\n",
896 newfilename, strerror(errno));
898 /* Files included override aliases,
899 etc that was already set ... */
900 if (newconf.aliases)
901 *aliases = newconf.aliases;
903 } else if (streq(cmd, "options")) {
904 modname = strsep_skipspace(&ptr, "\t ");
905 if (!modname || !ptr)
906 goto syntax_error;
908 ptr += strspn(ptr, "\t ");
909 *options = add_options(underscores(modname),
910 ptr, *options);
912 } else if (streq(cmd, "install")) {
913 modname = strsep_skipspace(&ptr, "\t ");
914 if (!modname || !ptr)
915 goto syntax_error;
916 if (!removing) {
917 ptr += strspn(ptr, "\t ");
918 *commands = add_command(underscores(modname),
919 ptr, *commands);
921 } else if (streq(cmd, "blacklist")) {
922 modname = strsep_skipspace(&ptr, "\t ");
923 if (!modname)
924 goto syntax_error;
925 if (!removing) {
926 *blacklist = add_blacklist(underscores(modname),
927 *blacklist);
929 } else if (streq(cmd, "remove")) {
930 modname = strsep_skipspace(&ptr, "\t ");
931 if (!modname || !ptr)
932 goto syntax_error;
933 if (removing) {
934 ptr += strspn(ptr, "\t ");
935 *commands = add_command(underscores(modname),
936 ptr, *commands);
938 } else if (streq(cmd, "softdep")) {
939 char *tk;
940 int pre = 0, post = 0;
941 struct string_table *pre_modnames = NULL;
942 struct string_table *post_modnames = NULL;
943 struct module_softdep *new;
945 modname = underscores(strsep_skipspace(&ptr, "\t "));
946 if (!modname || !ptr)
947 goto syntax_error;
948 while ((tk = strsep_skipspace(&ptr, "\t ")) != NULL) {
949 if (streq(tk, "pre:")) {
950 pre = 1; post = 0;
951 } else if (streq(tk, "post:")) {
952 pre = 0; post = 1;
953 } else if (pre) {
954 pre_modnames = NOFAIL(
955 strtbl_add(tk, pre_modnames));
956 } else if (post) {
957 post_modnames = NOFAIL(
958 strtbl_add(tk, post_modnames));
959 } else {
960 strtbl_free(pre_modnames);
961 strtbl_free(post_modnames);
962 goto syntax_error;
965 new = NOFAIL(malloc(sizeof(*new)));
966 new->buf = line;
967 new->modname = modname;
968 new->pre = pre_modnames;
969 new->post = post_modnames;
970 new->next = conf->softdeps;
971 conf->softdeps = new;
973 line = NULL; /* Don't free() this line. */
975 } else if (streq(cmd, "config")) {
976 char *tmp = strsep_skipspace(&ptr, "\t ");
978 if (!tmp)
979 goto syntax_error;
980 if (streq(tmp, "binary_indexes")) {
981 tmp = strsep_skipspace(&ptr, "\t ");
982 if (streq(tmp, "yes"))
983 use_binary_indexes = 1;
984 if (streq(tmp, "no"))
985 use_binary_indexes = 0;
987 } else {
988 syntax_error:
989 grammar(cmd, filename, linenum);
992 free(line);
994 fclose(cfile);
995 return 1;
998 /* Read binary index file containing aliases only */
999 static int read_aliases_file(const char *filename,
1000 const char *name,
1001 int dump_only,
1002 struct module_alias **aliases)
1004 struct index_value *realnames;
1005 struct index_value *realname;
1006 char *binfile;
1007 struct index_file *index;
1009 nofail_asprintf(&binfile, "%s.bin", filename);
1010 index = index_file_open(binfile);
1011 if (!index) {
1012 free(binfile);
1013 return 0;
1016 if (dump_only) {
1017 index_dump(index, stdout, "alias ");
1018 free(binfile);
1019 index_file_close(index);
1020 return 1;
1023 realnames = index_searchwild(index, name);
1024 for (realname = realnames; realname; realname = realname->next)
1025 *aliases = add_alias("*", realname->value, *aliases);
1026 index_values_free(realnames);
1028 free(binfile);
1029 index_file_close(index);
1030 return 1;
1033 /* fallback to plain-text aliases file if necessary */
1034 static int read_aliases(const char *filename,
1035 const char *name,
1036 int dump_only,
1037 struct module_alias **aliases)
1039 char *line;
1040 unsigned int linenum = 0;
1041 FILE *cfile;
1043 if (use_binary_indexes)
1044 if (read_aliases_file(filename, name, dump_only, aliases))
1045 return 1;
1047 cfile = fopen(filename, "r");
1048 if (!cfile)
1049 return 0;
1051 while ((line = getline_wrapped(cfile, &linenum)) != NULL) {
1052 char *ptr = line;
1053 char *cmd;
1055 if (dump_only)
1056 printf("%s\n", line);
1058 cmd = strsep_skipspace(&ptr, "\t ");
1059 if (cmd == NULL || cmd[0] == '#' || cmd[0] == '\0') {
1060 free(line);
1061 continue;
1064 if (streq(cmd, "alias")) {
1065 char *wildcard = strsep_skipspace(&ptr, "\t ");
1066 char *realname = strsep_skipspace(&ptr, "\t ");
1067 if (!wildcard || !realname)
1068 goto syntax_error;
1069 if (fnmatch(underscores(wildcard),name,0) == 0)
1070 *aliases = add_alias(wildcard,
1071 underscores(realname),
1072 *aliases);
1073 } else {
1074 syntax_error:
1075 grammar(cmd, filename, linenum);
1078 free(line);
1080 fclose(cfile);
1081 return 1;
1084 static int parse_config_scan(const char *filename,
1085 struct modprobe_conf *conf,
1086 int dump_only,
1087 int removing)
1089 DIR *dir;
1090 int ret = 0;
1092 dir = opendir(filename);
1093 if (dir) {
1094 struct file_entry {
1095 struct list_head node;
1096 char name[];
1098 LIST_HEAD(files_list);
1099 struct file_entry *fe, *fe_tmp;
1100 struct dirent *i;
1102 /* sort files from directory into list */
1103 while ((i = readdir(dir)) != NULL) {
1104 size_t len;
1106 if (i->d_name[0] == '.')
1107 continue;
1108 if (!config_filter(i->d_name))
1109 continue;
1111 len = strlen(i->d_name);
1112 if (len < 6 ||
1113 (strcmp(&i->d_name[len-5], ".conf") != 0 &&
1114 strcmp(&i->d_name[len-6], ".alias") != 0))
1115 warn("All config files need .conf: %s/%s, "
1116 "it will be ignored in a future release.\n",
1117 filename, i->d_name);
1118 fe = malloc(sizeof(struct file_entry) + len + 1);
1119 if (fe == NULL)
1120 continue;
1121 strcpy(fe->name, i->d_name);
1122 list_for_each_entry(fe_tmp, &files_list, node)
1123 if (strcmp(fe_tmp->name, fe->name) >= 0)
1124 break;
1125 list_add_tail(&fe->node, &fe_tmp->node);
1127 closedir(dir);
1129 /* parse list of files */
1130 list_for_each_entry_safe(fe, fe_tmp, &files_list, node) {
1131 char *cfgfile;
1133 nofail_asprintf(&cfgfile, "%s/%s", filename, fe->name);
1134 if (!parse_config_file(cfgfile, conf,
1135 dump_only, removing))
1136 warn("Failed to open config file "
1137 "%s: %s\n", fe->name, strerror(errno));
1138 free(cfgfile);
1139 list_del(&fe->node);
1140 free(fe);
1143 ret = 1;
1144 } else {
1145 if (parse_config_file(filename, conf, dump_only, removing))
1146 ret = 1;
1148 return ret;
1151 static void parse_toplevel_config(const char *filename,
1152 struct modprobe_conf *conf,
1153 int dump_only,
1154 int removing)
1156 if (filename) {
1157 if (!parse_config_scan(filename, conf, dump_only, removing))
1158 fatal("Failed to open config file %s: %s\n",
1159 filename, strerror(errno));
1160 return;
1163 /* deprecated config file */
1164 if (parse_config_file("/etc/modprobe.conf", conf,
1165 dump_only, removing) > 0)
1166 warn("Deprecated config file /etc/modprobe.conf, "
1167 "all config files belong into /etc/modprobe.d/.\n");
1169 /* default config */
1170 parse_config_scan("/etc/modprobe.d", conf, dump_only, removing);
1173 /* Read possible module arguments from the kernel command line. */
1174 static int parse_kcmdline(int dump_only, struct module_options **options)
1176 char *line;
1177 unsigned int linenum = 0;
1178 FILE *kcmdline;
1180 kcmdline = fopen("/proc/cmdline", "r");
1181 if (!kcmdline)
1182 return 0;
1184 while ((line = getline_wrapped(kcmdline, &linenum)) != NULL) {
1185 char *ptr = line;
1186 char *arg;
1188 while ((arg = strsep_skipspace(&ptr, "\t ")) != NULL) {
1189 char *sep, *modname, *opt;
1191 sep = strchr(arg, '.');
1192 if (sep) {
1193 if (!strchr(sep, '='))
1194 continue;
1195 modname = arg;
1196 *sep = '\0';
1197 opt = ++sep;
1199 if (dump_only)
1200 printf("options %s %s\n", modname, opt);
1202 *options = add_options(underscores(modname),
1203 opt, *options);
1207 free(line);
1209 fclose(kcmdline);
1210 return 1;
1213 static void add_to_env_var(const char *option)
1215 const char *oldenv;
1217 if ((oldenv = getenv("MODPROBE_OPTIONS")) != NULL) {
1218 char *newenv;
1219 nofail_asprintf(&newenv, "%s %s", oldenv, option);
1220 setenv("MODPROBE_OPTIONS", newenv, 1);
1221 free(newenv);
1222 } else
1223 setenv("MODPROBE_OPTIONS", option, 1);
1226 /* Prepend options from environment. */
1227 static char **merge_args(char *args, char *argv[], int *argc)
1229 char *arg, *argstring;
1230 char **newargs = NULL;
1231 unsigned int i, num_env = 0;
1233 if (!args)
1234 return argv;
1236 argstring = NOFAIL(strdup(args));
1237 for (arg = strtok(argstring, " "); arg; arg = strtok(NULL, " ")) {
1238 num_env++;
1239 newargs = NOFAIL(realloc(newargs,
1240 sizeof(newargs[0])
1241 * (num_env + *argc + 1)));
1242 newargs[num_env] = arg;
1245 if (!newargs)
1246 return argv;
1248 /* Append commandline args */
1249 newargs[0] = argv[0];
1250 for (i = 1; i <= *argc; i++)
1251 newargs[num_env+i] = argv[i];
1253 *argc += num_env;
1254 return newargs;
1257 static char *gather_options(char *argv[])
1259 char *optstring = NOFAIL(strdup(""));
1261 /* Rest is module options */
1262 while (*argv) {
1263 /* Quote value if it contains spaces. */
1264 unsigned int eq = strcspn(*argv, "=");
1266 if (strchr(*argv+eq, ' ') && !strchr(*argv, '"')) {
1267 char quoted[strlen(*argv) + 3];
1268 (*argv)[eq] = '\0';
1269 sprintf(quoted, "%s=\"%s\"", *argv, *argv+eq+1);
1270 optstring = append_option(optstring, quoted);
1271 } else
1272 optstring = append_option(optstring, *argv);
1273 argv++;
1275 return optstring;
1278 /* Do an install/remove command: replace $CMDLINE_OPTS if it's specified. */
1279 static void do_command(const char *modname,
1280 const char *command,
1281 int dry_run,
1282 errfn_t error,
1283 const char *type,
1284 const char *cmdline_opts)
1286 int ret;
1287 char *p, *replaced_cmd = NOFAIL(strdup(command));
1289 while ((p = strstr(replaced_cmd, "$CMDLINE_OPTS")) != NULL) {
1290 char *new;
1291 nofail_asprintf(&new, "%.*s%s%s",
1292 (int)(p - replaced_cmd), replaced_cmd, cmdline_opts,
1293 p + strlen("$CMDLINE_OPTS"));
1294 free(replaced_cmd);
1295 replaced_cmd = new;
1298 info("%s %s\n", type, replaced_cmd);
1299 if (dry_run)
1300 goto out;
1302 setenv("MODPROBE_MODULE", modname, 1);
1303 ret = system(replaced_cmd);
1304 if (ret == -1 || WEXITSTATUS(ret))
1305 error("Error running %s command for %s\n", type, modname);
1307 out:
1308 free(replaced_cmd);
1311 /* Forward declaration */
1312 int do_modprobe(const char *modname,
1313 const char *newname,
1314 const char *cmdline_opts,
1315 const struct modprobe_conf *conf,
1316 const char *dirname,
1317 errfn_t error,
1318 modprobe_flags_t flags);
1320 static void do_softdep(const struct module_softdep *softdep,
1321 const char *cmdline_opts,
1322 const struct modprobe_conf *conf,
1323 const char *dirname,
1324 errfn_t error,
1325 modprobe_flags_t flags)
1327 struct string_table *pre_modnames, *post_modnames;
1328 int i, j;
1330 if (++recursion_depth >= MAX_RECURSION)
1331 fatal("modprobe: softdep dependency loop encountered %s %s\n",
1332 (flags & mit_remove) ? "removing" : "inserting",
1333 softdep->modname);
1335 if (flags & mit_remove) {
1336 /* Reverse module order if removing. */
1337 pre_modnames = softdep->post;
1338 post_modnames = softdep->pre;
1339 } else {
1340 pre_modnames = softdep->pre;
1341 post_modnames = softdep->post;
1344 /* Modprobe pre_modnames */
1346 for (i = 0; pre_modnames && i < pre_modnames->cnt; i++) {
1347 /* Reverse module order if removing. */
1348 j = (flags & mit_remove) ? pre_modnames->cnt-1 - i : i;
1350 do_modprobe(pre_modnames->str[j], NULL, "",
1351 conf, dirname, warn, flags);
1354 /* Modprobe main module, passing cmdline_opts, ignoring softdep */
1356 do_modprobe(softdep->modname, NULL, cmdline_opts,
1357 conf, dirname, warn, flags | mit_ignore_commands);
1359 /* Modprobe post_modnames */
1361 for (i = 0; post_modnames && i < post_modnames->cnt; i++) {
1362 /* Reverse module order if removing. */
1363 j = (flags & mit_remove) ? post_modnames->cnt-1 - i : i;
1365 do_modprobe(post_modnames->str[j], NULL, "", conf,
1366 dirname, warn, flags);
1370 /* Actually do the insert. */
1371 static int insmod(struct list_head *list,
1372 const char *optstring,
1373 const char *newname,
1374 const char *cmdline_opts,
1375 const struct modprobe_conf *conf,
1376 const char *dirname,
1377 errfn_t error,
1378 modprobe_flags_t flags)
1380 int ret;
1381 struct elf_file *module;
1382 const struct module_softdep *softdep;
1383 const char *command;
1384 struct module *mod = list_entry(list->next, struct module, list);
1385 int rc = 0;
1386 int already_loaded;
1387 char *opts = NULL;
1389 /* Take us off the list. */
1390 list_del(&mod->list);
1392 /* Do things we (or parent) depend on first. */
1393 if (!list_empty(list)) {
1394 modprobe_flags_t f = flags;
1395 f &= ~mit_first_time;
1396 f &= ~mit_ignore_commands;
1397 if ((rc = insmod(list, "", NULL,
1398 "", conf, dirname, warn, f)) != 0)
1400 error("Error inserting %s (%s): %s\n",
1401 mod->modname, mod->filename,
1402 insert_moderror(errno));
1403 goto out;
1407 /* Don't do ANYTHING if already in kernel. */
1408 already_loaded = module_in_kernel(newname ?: mod->modname, NULL);
1410 if (!(flags & mit_ignore_loaded) && already_loaded == 1) {
1411 if (flags & mit_first_time)
1412 error("Module %s already in kernel.\n",
1413 newname ?: mod->modname);
1414 goto out;
1417 softdep = find_softdep(mod->modname, conf->softdeps);
1418 if (softdep && !(flags & mit_ignore_commands)) {
1419 do_softdep(softdep, cmdline_opts, conf, dirname,
1420 error, flags & (mit_remove | mit_dry_run));
1421 goto out;
1424 command = find_command(mod->modname, conf->commands);
1425 if (command && !(flags & mit_ignore_commands)) {
1426 if (already_loaded == -1) {
1427 warn("/sys/module/ not present or too old,"
1428 " and /proc/modules does not exist.\n");
1429 warn("Ignoring install commands for %s"
1430 " in case it is already loaded.\n",
1431 newname ?: mod->modname);
1432 } else {
1433 do_command(mod->modname, command, flags & mit_dry_run,
1434 error, "install", cmdline_opts);
1435 goto out;
1439 module = grab_elf_file(mod->filename);
1440 if (!module) {
1441 error("Could not read '%s': %s\n", mod->filename,
1442 (errno == ENOEXEC) ? "Invalid module format" :
1443 strerror(errno));
1444 goto out;
1446 if (newname)
1447 rename_module(module, mod->modname, newname);
1448 if (flags & mit_strip_modversion)
1449 module->ops->strip_section(module, "__versions");
1450 if (flags & mit_strip_vermagic)
1451 clear_magic(module);
1453 /* Config file might have given more options */
1454 opts = add_extra_options(mod->modname, optstring, conf->options);
1456 info("insmod %s %s\n", mod->filename, opts);
1458 if (flags & mit_dry_run)
1459 goto out_elf_file;
1461 ret = init_module(module->data, module->len, opts);
1462 if (ret != 0) {
1463 if (errno == EEXIST) {
1464 if (flags & mit_first_time)
1465 error("Module %s already in kernel.\n",
1466 newname ?: mod->modname);
1467 goto out_elf_file;
1469 /* don't warn noisely if we're loading multiple aliases. */
1470 /* one of the aliases may try to use hardware we don't have. */
1471 if ((error != warn) || (verbose))
1472 error("Error inserting %s (%s): %s\n",
1473 mod->modname, mod->filename,
1474 insert_moderror(errno));
1475 rc = 1;
1477 out_elf_file:
1478 release_elf_file(module);
1479 free(opts);
1480 out:
1481 free_module(mod);
1482 return rc;
1485 /* Do recursive removal. */
1486 static void rmmod(struct list_head *list,
1487 const char *name,
1488 const char *cmdline_opts,
1489 const struct modprobe_conf *conf,
1490 const char *dirname,
1491 errfn_t error,
1492 modprobe_flags_t flags)
1494 const struct module_softdep *softdep;
1495 const char *command;
1496 unsigned int usecount = 0;
1497 struct module *mod = list_entry(list->next, struct module, list);
1498 int exists;
1500 /* Take first one off the list. */
1501 list_del(&mod->list);
1503 if (!name)
1504 name = mod->modname;
1506 /* Don't do ANYTHING if not loaded. */
1507 exists = module_in_kernel(name, &usecount);
1508 if (exists == 0)
1509 goto nonexistent_module;
1511 /* Even if renamed, find commands/softdeps to orig. name. */
1513 softdep = find_softdep(mod->modname, conf->softdeps);
1514 if (softdep && !(flags & mit_ignore_commands)) {
1515 do_softdep(softdep, cmdline_opts, conf, dirname,
1516 error, flags & (mit_remove | mit_dry_run));
1517 goto remove_rest;
1520 command = find_command(mod->modname, conf->commands);
1521 if (command && !(flags & mit_ignore_commands)) {
1522 if (exists == -1) {
1523 warn("/sys/module/ not present or too old,"
1524 " and /proc/modules does not exist.\n");
1525 warn("Ignoring remove commands for %s"
1526 " in case it is not loaded.\n",
1527 mod->modname);
1528 } else {
1529 do_command(mod->modname, command, flags & mit_dry_run,
1530 error, "remove", cmdline_opts);
1531 goto remove_rest;
1535 if (usecount != 0) {
1536 if (!(flags & mit_quiet_inuse))
1537 error("Module %s is in use.\n", name);
1538 goto remove_rest;
1541 info("rmmod %s\n", mod->filename);
1543 if (flags & mit_dry_run)
1544 goto remove_rest;
1546 if (delete_module(name, O_EXCL) != 0) {
1547 if (errno == ENOENT)
1548 goto nonexistent_module;
1549 error("Error removing %s (%s): %s\n",
1550 name, mod->filename,
1551 remove_moderror(errno));
1554 remove_rest:
1555 /* Now do things we depend. */
1556 if (!list_empty(list)) {
1557 flags &= ~mit_first_time;
1558 flags &= ~mit_ignore_commands;
1559 flags |= mit_quiet_inuse;
1561 rmmod(list, NULL, "", conf, dirname, warn, flags);
1563 free_module(mod);
1564 return;
1566 nonexistent_module:
1567 if (flags & mit_first_time)
1568 fatal("Module %s is not in kernel.\n", mod->modname);
1569 goto remove_rest;
1572 static int handle_module(const char *modname,
1573 struct list_head *todo_list,
1574 const char *newname,
1575 const char *options,
1576 const char *cmdline_opts,
1577 const struct modprobe_conf *conf,
1578 const char *dirname,
1579 errfn_t error,
1580 modprobe_flags_t flags)
1582 if (list_empty(todo_list)) {
1583 const struct module_softdep *softdep;
1584 const char *command;
1586 /* The dependencies have to be real modules, but
1587 handle case where the first is completely bogus. */
1589 softdep = find_softdep(modname, conf->softdeps);
1590 if (softdep && !(flags & mit_ignore_commands)) {
1591 do_softdep(softdep, cmdline_opts, conf, dirname,
1592 error, flags & (mit_remove | mit_dry_run));
1593 return 0;
1596 command = find_command(modname, conf->commands);
1597 if (command && !(flags & mit_ignore_commands)) {
1598 do_command(modname, command, flags & mit_dry_run, error,
1599 (flags & mit_remove) ? "remove":"install", cmdline_opts);
1600 return 0;
1603 if (!quiet)
1604 error("Module %s not found.\n", modname);
1605 return 1;
1608 if (flags & mit_remove)
1609 rmmod(todo_list, newname, cmdline_opts,
1610 conf, dirname, error, flags);
1611 else
1612 insmod(todo_list, options, newname,
1613 cmdline_opts, conf, dirname, error, flags);
1615 return 0;
1618 int handle_builtin_module(const char *modname,
1619 errfn_t error,
1620 modprobe_flags_t flags)
1622 if (flags & mit_remove) {
1623 error("Module %s is builtin\n", modname);
1624 return 1;
1625 } else if (flags & mit_first_time) {
1626 error("Module %s already in kernel (builtin).\n", modname);
1627 return 1;
1628 } else if (flags & mit_ignore_loaded) {
1629 /* --show-depends given */
1630 info("builtin %s\n", modname);
1632 return 0;
1635 int do_modprobe(const char *modulename,
1636 const char *newname,
1637 const char *cmdline_opts,
1638 const struct modprobe_conf *conf,
1639 const char *dirname,
1640 errfn_t error,
1641 modprobe_flags_t flags)
1643 char *modname;
1644 struct module_alias *matching_aliases;
1645 LIST_HEAD(list);
1646 int failed = 0;
1648 /* Convert name we are looking for */
1649 modname = underscores(NOFAIL(strdup(modulename)));
1651 matching_aliases = find_aliases(conf->aliases, modname);
1653 /* No luck? Try symbol names, if starts with symbol:. */
1654 if (!matching_aliases && strstarts(modname, "symbol:")) {
1655 char *symfilename;
1657 nofail_asprintf(&symfilename, "%s/modules.symbols", dirname);
1658 read_aliases(symfilename, modname, 0, &matching_aliases);
1659 free(symfilename);
1661 if (!matching_aliases) {
1662 if(!strchr(modname, ':'))
1663 read_depends(dirname, modname, &list);
1665 /* We only use canned aliases as last resort. */
1666 if (list_empty(&list)
1667 && !find_softdep(modname, conf->softdeps)
1668 && !find_command(modname, conf->commands))
1670 char *aliasfilename;
1672 nofail_asprintf(&aliasfilename, "%s/modules.alias",
1673 dirname);
1674 read_aliases(aliasfilename, modname, 0,
1675 &matching_aliases);
1676 free(aliasfilename);
1677 /* builtin module? */
1678 if (!matching_aliases && module_builtin(dirname, modname) > 0) {
1679 failed |= handle_builtin_module(modname, error,
1680 flags);
1681 goto out;
1686 apply_blacklist(&matching_aliases, conf->blacklist);
1687 if(flags & mit_resolve_alias) {
1688 struct module_alias *aliases = matching_aliases;
1690 for(; aliases; aliases=aliases->next)
1691 printf("%s\n", aliases->module);
1692 goto out;
1694 if (matching_aliases) {
1695 errfn_t err = error;
1696 struct module_alias *aliases = matching_aliases;
1698 /* More than one alias? Don't bail out on failure. */
1699 if (aliases->next)
1700 err = warn;
1701 while (aliases) {
1702 /* Add the options for this alias. */
1703 char *opts;
1704 opts = add_extra_options(modname,
1705 cmdline_opts, conf->options);
1707 read_depends(dirname, aliases->module, &list);
1708 failed |= handle_module(aliases->module,
1709 &list, newname, opts, cmdline_opts,
1710 conf, dirname, err, flags);
1712 aliases = aliases->next;
1713 free(opts);
1714 INIT_LIST_HEAD(&list);
1716 } else {
1717 if (flags & mit_use_blacklist
1718 && find_blacklist(modname, conf->blacklist))
1719 goto out;
1721 failed |= handle_module(modname, &list, newname, cmdline_opts,
1722 cmdline_opts, conf, dirname, error, flags);
1725 out:
1726 free(modname);
1727 free_aliases(matching_aliases);
1728 return failed;
1731 static struct option options[] = { { "version", 0, NULL, 'V' },
1732 { "verbose", 0, NULL, 'v' },
1733 { "quiet", 0, NULL, 'q' },
1734 { "syslog", 0, NULL, 's' },
1735 { "show", 0, NULL, 'n' },
1736 { "dry-run", 0, NULL, 'n' },
1737 { "show-depends", 0, NULL, 'D' },
1738 { "resolve-alias", 0, NULL, 'R' },
1739 { "dirname", 1, NULL, 'd' },
1740 { "set-version", 1, NULL, 'S' },
1741 { "config", 1, NULL, 'C' },
1742 { "name", 1, NULL, 'o' },
1743 { "remove", 0, NULL, 'r' },
1744 { "showconfig", 0, NULL, 'c' },
1745 { "list", 0, NULL, 'l' },
1746 { "type", 1, NULL, 't' },
1747 { "all", 0, NULL, 'a' },
1748 { "ignore-install", 0, NULL, 'i' },
1749 { "ignore-remove", 0, NULL, 'i' },
1750 { "use-blacklist", 0, NULL, 'b' },
1751 { "force", 0, NULL, 'f' },
1752 { "force-vermagic", 0, NULL, 1 },
1753 { "force-modversion", 0, NULL, 2 },
1754 { "first-time", 0, NULL, 3 },
1755 { "dump-modversions", 0, NULL, 4 },
1756 { NULL, 0, NULL, 0 } };
1758 int main(int argc, char *argv[])
1760 struct utsname buf;
1761 struct stat statbuf;
1762 int opt;
1763 int dump_config = 0;
1764 int list_only = 0;
1765 int all = 0;
1766 int dump_modver = 0;
1767 unsigned int i, num_modules;
1768 char *type = NULL;
1769 const char *configname = NULL;
1770 char *basedir = "";
1771 char *cmdline_opts = NULL;
1772 char *newname = NULL;
1773 char *dirname;
1774 errfn_t error = fatal;
1775 int failed = 0;
1776 modprobe_flags_t flags = 0;
1777 struct modprobe_conf conf = {};
1779 recursion_depth = 0;
1781 /* Prepend options from environment. */
1782 argv = merge_args(getenv("MODPROBE_OPTIONS"), argv, &argc);
1784 uname(&buf);
1785 while ((opt = getopt_long(argc, argv, "Vvqsnd:S:C:DRo:rclt:aibf", options, NULL)) != -1){
1786 switch (opt) {
1787 case 'V':
1788 puts(PACKAGE " version " VERSION);
1789 exit(0);
1790 case 'v':
1791 add_to_env_var("-v");
1792 verbose = 1;
1793 break;
1794 case 'q':
1795 quiet = 1;
1796 add_to_env_var("-q");
1797 break;
1798 case 's':
1799 add_to_env_var("-s");
1800 logging = 1;
1801 break;
1802 case 'n':
1803 flags |= mit_dry_run;
1804 break;
1805 case 'd':
1806 basedir = optarg;
1807 break;
1808 case 'S':
1809 strncpy(buf.release, optarg, sizeof(buf.release));
1810 buf.release[sizeof(buf.release)-1] = '\0';
1811 break;
1812 case 'C':
1813 configname = optarg;
1814 add_to_env_var("-C");
1815 add_to_env_var(configname);
1816 break;
1817 case 'D':
1818 flags |= mit_dry_run;
1819 flags |= mit_ignore_loaded;
1820 verbose = 1;
1821 break;
1822 case 'R':
1823 flags |= mit_resolve_alias;
1824 break;
1825 case 'o':
1826 newname = optarg;
1827 break;
1828 case 'r':
1829 flags |= mit_remove;
1830 break;
1831 case 'c':
1832 dump_config = 1;
1833 break;
1834 case 'l':
1835 list_only = 1;
1836 break;
1837 case 't':
1838 type = optarg;
1839 break;
1840 case 'a':
1841 all = 1;
1842 error = warn;
1843 break;
1844 case 'i':
1845 flags |= mit_ignore_commands;
1846 break;
1847 case 'b':
1848 flags |= mit_use_blacklist;
1849 break;
1850 case 'f':
1851 flags |= mit_strip_vermagic;
1852 flags |= mit_strip_modversion;
1853 break;
1854 case 1:
1855 flags |= mit_strip_vermagic;
1856 break;
1857 case 2:
1858 flags |= mit_strip_modversion;
1859 break;
1860 case 3:
1861 flags |= mit_first_time;
1862 break;
1863 case 4:
1864 dump_modver = 1;
1865 break;
1866 default:
1867 print_usage(argv[0]);
1871 /* If stderr not open, go to syslog */
1872 if (logging || fstat(STDERR_FILENO, &statbuf) != 0) {
1873 openlog("modprobe", LOG_CONS, LOG_DAEMON);
1874 logging = 1;
1877 if (argc < optind + 1 && !dump_config && !list_only)
1878 print_usage(argv[0]);
1880 nofail_asprintf(&dirname, "%s%s/%s", basedir, MODULE_DIR, buf.release);
1882 /* Old-style -t xxx wildcard? Only with -l. */
1883 if (list_only) {
1884 if (optind+1 < argc)
1885 fatal("Can't have multiple wildcards\n");
1886 /* fprintf(stderr, "man find\n"); return 1; */
1887 failed = do_wildcard(dirname, type, argv[optind]?:"*");
1888 goto out;
1890 if (type)
1891 fatal("-t only supported with -l");
1893 /* Read aliases, options etc. */
1894 parse_toplevel_config(configname, &conf, dump_config, flags & mit_remove);
1896 /* Read module options from kernel command line */
1897 parse_kcmdline(1, &conf.options);
1899 if (dump_config) {
1900 char *aliasfilename, *symfilename;
1901 struct modprobe_conf conf = {};
1903 nofail_asprintf(&aliasfilename, "%s/modules.alias", dirname);
1904 nofail_asprintf(&symfilename, "%s/modules.symbols", dirname);
1906 parse_toplevel_config(configname, &conf, 1, 0);
1907 /* Read module options from kernel command line */
1908 parse_kcmdline(1, &conf.options);
1909 read_aliases(aliasfilename, "", 1, &conf.aliases);
1910 read_aliases(symfilename, "", 1, &conf.aliases);
1912 goto out;
1915 if ((flags & mit_remove) || all) {
1916 num_modules = argc - optind;
1917 cmdline_opts = NOFAIL(strdup(""));
1918 } else {
1919 num_modules = 1;
1920 cmdline_opts = gather_options(argv+optind+1);
1923 /* num_modules is always 1 except for -r or -a. */
1924 for (i = 0; i < num_modules; i++) {
1925 char *modname = argv[optind + i];
1927 if (dump_modver)
1928 dump_modversions(modname, error);
1929 else
1930 failed |= do_modprobe(modname, newname, cmdline_opts,
1931 &conf, dirname, error, flags);
1935 out:
1936 if (logging)
1937 closelog();
1938 free(dirname);
1939 free(cmdline_opts);
1940 /* Don't bother to free conf */
1942 exit(failed);