[PATCH] module-init-tools : insmod_correct_argv0_computation
[mit.git] / modprobe.c
blob4d4af93d5250044ca6ba0a9234c2f2ca484cdaf4
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 #define streq(a,b) (strcmp((a),(b)) == 0)
43 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
45 #include "zlibsupport.h"
46 #include "list.h"
47 #include "backwards_compat.c"
49 extern long init_module(void *, unsigned long, const char *);
50 extern long delete_module(const char *, unsigned int);
52 struct module {
53 struct list_head list;
54 char *modname;
55 char filename[0];
58 #ifndef MODULE_DIR
59 #define MODULE_DIR "/lib/modules"
60 #endif
62 typedef void (*errfn_t)(const char *fmt, ...);
64 /* Do we use syslog or stderr for messages? */
65 static int log;
67 static void message(const char *prefix, const char *fmt, va_list *arglist)
69 char *buf, *buf2;
71 vasprintf(&buf, fmt, *arglist);
72 asprintf(&buf2, "%s%s", prefix, buf);
74 if (log)
75 syslog(LOG_NOTICE, "%s", buf2);
76 else
77 fprintf(stderr, "%s", buf2);
78 free(buf2);
79 free(buf);
82 static int warned = 0;
83 static void warn(const char *fmt, ...)
85 va_list arglist;
86 warned++;
87 va_start(arglist, fmt);
88 message("WARNING: ", fmt, &arglist);
89 va_end(arglist);
92 static void fatal(const char *fmt, ...)
94 va_list arglist;
95 va_start(arglist, fmt);
96 message("FATAL: ", fmt, &arglist);
97 va_end(arglist);
98 exit(1);
102 static void grammar(const char *cmd, const char *filename, unsigned int line)
104 warn("%s line %u: ignoring bad line starting with '%s'\n",
105 filename, line, cmd);
108 static void *do_nofail(void *ptr, const char *file, int line, const char *expr)
110 if (!ptr) {
111 fatal("Memory allocation failure %s line %d: %s.\n",
112 file, line, expr);
114 return ptr;
117 #define NOFAIL(ptr) do_nofail((ptr), __FILE__, __LINE__, #ptr)
119 static void print_usage(const char *progname)
121 fprintf(stderr,
122 "Usage: %s [-v] [-V] [-C config-file] [-n] [-i] [-q] [-b] [-o <modname>] [ --dump-modversions ] <modname> [parameters...]\n"
123 "%s -r [-n] [-i] [-v] <modulename> ...\n"
124 "%s -l -t <dirname> [ -a <modulename> ...]\n",
125 progname, progname, progname);
126 exit(1);
129 static int fgetc_wrapped(FILE *file, unsigned int *linenum)
131 for (;;) {
132 int ch = fgetc(file);
133 if (ch != '\\')
134 return ch;
135 ch = fgetc(file);
136 if (ch != '\n')
137 return ch;
138 if (linenum)
139 (*linenum)++;
143 static char *getline_wrapped(FILE *file, unsigned int *linenum)
145 int size = 1024;
146 int i = 0;
147 char *buf = NOFAIL(malloc(size));
148 for(;;) {
149 int ch = fgetc_wrapped(file, linenum);
150 if (i == size) {
151 size *= 2;
152 buf = NOFAIL(realloc(buf, size));
154 if (ch < 0 && i == 0) {
155 free(buf);
156 return NULL;
158 if (ch < 0 || ch == '\n') {
159 if (linenum)
160 (*linenum)++;
161 buf[i] = '\0';
162 return NOFAIL(realloc(buf, i+1));
164 buf[i++] = ch;
168 static struct module *find_module(const char *filename, struct list_head *list)
170 struct module *i;
172 list_for_each_entry(i, list, list) {
173 if (strcmp(i->filename, filename) == 0)
174 return i;
176 return NULL;
179 /* Convert filename to the module name. Works if filename == modname, too. */
180 static void filename2modname(char *modname, const char *filename)
182 const char *afterslash;
183 unsigned int i;
185 afterslash = strrchr(filename, '/');
186 if (!afterslash)
187 afterslash = filename;
188 else
189 afterslash++;
191 /* Convert to underscores, stop at first . */
192 for (i = 0; afterslash[i] && afterslash[i] != '.'; i++) {
193 if (afterslash[i] == '-')
194 modname[i] = '_';
195 else
196 modname[i] = afterslash[i];
198 modname[i] = '\0';
201 static int lock_file(const char *filename)
203 int fd = open(filename, O_RDWR, 0);
205 if (fd >= 0) {
206 struct flock lock;
207 lock.l_type = F_WRLCK;
208 lock.l_whence = SEEK_SET;
209 lock.l_start = 0;
210 lock.l_len = 1;
211 fcntl(fd, F_SETLKW, &lock);
212 } else
213 /* Read-only filesystem? There goes locking... */
214 fd = open(filename, O_RDONLY, 0);
215 return fd;
218 static void unlock_file(int fd)
220 /* Valgrind is picky... */
221 close(fd);
224 static void add_module(char *filename, int namelen, struct list_head *list)
226 struct module *mod;
228 /* If it's a duplicate: move it to the end, so it gets
229 inserted where it is *first* required. */
230 mod = find_module(filename, list);
231 if (mod)
232 list_del(&mod->list);
233 else {
234 /* No match. Create a new module. */
235 mod = NOFAIL(malloc(sizeof(struct module) + namelen + 1));
236 memcpy(mod->filename, filename, namelen);
237 mod->filename[namelen] = '\0';
238 mod->modname = NOFAIL(malloc(namelen + 1));
239 filename2modname(mod->modname, mod->filename);
242 list_add_tail(&mod->list, list);
245 /* Compare len chars of a to b, with _ and - equivalent. */
246 static int modname_equal(const char *a, const char *b, unsigned int len)
248 unsigned int i;
250 if (strlen(b) != len)
251 return 0;
253 for (i = 0; i < len; i++) {
254 if ((a[i] == '_' || a[i] == '-')
255 && (b[i] == '_' || b[i] == '-'))
256 continue;
257 if (a[i] != b[i])
258 return 0;
260 return 1;
263 /* Fills in list of modules if this is the line we want. */
264 static int add_modules_dep_line(char *line,
265 const char *name,
266 struct list_head *list)
268 char *ptr;
269 int len;
270 char *modname;
272 /* Ignore lines without : or which start with a # */
273 ptr = strchr(line, ':');
274 if (ptr == NULL || line[strspn(line, "\t ")] == '#')
275 return 0;
277 /* Is this the module we are looking for? */
278 *ptr = '\0';
279 if (strrchr(line, '/'))
280 modname = strrchr(line, '/') + 1;
281 else
282 modname = line;
284 len = strlen(modname);
285 if (strchr(modname, '.'))
286 len = strchr(modname, '.') - modname;
287 if (!modname_equal(modname, name, len))
288 return 0;
290 /* Create the list. */
291 add_module(line, ptr - line, list);
293 ptr++;
294 for(;;) {
295 char *dep_start;
296 ptr += strspn(ptr, " \t");
297 if (*ptr == '\0')
298 break;
299 dep_start = ptr;
300 ptr += strcspn(ptr, " \t");
301 add_module(dep_start, ptr - dep_start, list);
303 return 1;
306 static void read_depends(const char *dirname,
307 const char *start_name,
308 struct list_head *list)
310 char *modules_dep_name;
311 char *line;
312 FILE *modules_dep;
313 int done = 0;
315 asprintf(&modules_dep_name, "%s/%s", dirname, "modules.dep");
316 modules_dep = fopen(modules_dep_name, "r");
317 if (!modules_dep)
318 fatal("Could not load %s: %s\n",
319 modules_dep_name, strerror(errno));
321 /* Stop at first line, as we can have duplicates (eg. symlinks
322 from boot/ */
323 while (!done && (line = getline_wrapped(modules_dep, NULL)) != NULL) {
324 done = add_modules_dep_line(line, start_name, list);
325 free(line);
327 fclose(modules_dep);
328 free(modules_dep_name);
331 /* We use error numbers in a loose translation... */
332 static const char *insert_moderror(int err)
334 switch (err) {
335 case ENOEXEC:
336 return "Invalid module format";
337 case ENOENT:
338 return "Unknown symbol in module, or unknown parameter (see dmesg)";
339 case ENOSYS:
340 return "Kernel does not have module support";
341 default:
342 return strerror(err);
346 static const char *remove_moderror(int err)
348 switch (err) {
349 case ENOENT:
350 return "No such module";
351 case ENOSYS:
352 return "Kernel does not have module unloading support";
353 default:
354 return strerror(err);
358 /* Is module in /proc/modules? If so, fill in usecount if not NULL.
359 0 means no, 1 means yes, -1 means unknown.
361 static int module_in_kernel(const char *modname, unsigned int *usecount)
363 FILE *proc_modules;
364 char *line;
366 again:
367 /* Might not be mounted yet. Don't fail. */
368 proc_modules = fopen("/proc/modules", "r");
369 if (!proc_modules)
370 return -1;
372 while ((line = getline_wrapped(proc_modules, NULL)) != NULL) {
373 char *entry = strtok(line, " \n");
375 if (entry && streq(entry, modname)) {
376 /* If it exists, usecount is the third entry. */
377 if (!strtok(NULL, " \n"))
378 goto out;
380 if (!(entry = strtok(NULL, " \n"))) /* usecount */
381 goto out;
382 else
383 if (usecount)
384 *usecount = atoi(entry);
386 /* Followed by - then status. */
387 if (strtok(NULL, " \n")
388 && (entry = strtok(NULL, " \n")) != NULL) {
389 /* Locking will fail on ro fs, we might hit
390 * cases where module is in flux. Spin. */
391 if (streq(entry, "Loading")
392 || streq(entry, "Unloading")) {
393 usleep(100000);
394 free(line);
395 fclose(proc_modules);
396 goto again;
400 out:
401 free(line);
402 fclose(proc_modules);
403 return 1;
405 free(line);
407 fclose(proc_modules);
408 return 0;
411 static void replace_modname(struct module *module,
412 void *mem, unsigned long len,
413 const char *oldname, const char *newname)
415 char *p;
417 /* 64 - sizeof(unsigned long) - 1 */
418 if (strlen(newname) > 55)
419 fatal("New name %s is too long\n", newname);
421 /* Find where it is in the module structure. Don't assume layout! */
422 for (p = mem; p < (char *)mem + len - strlen(oldname); p++) {
423 if (memcmp(p, oldname, strlen(oldname)) == 0) {
424 strcpy(p, newname);
425 return;
429 warn("Could not find old name in %s to replace!\n", module->filename);
432 static void *get_section32(void *file,
433 unsigned long size,
434 const char *name,
435 unsigned long *secsize)
437 Elf32_Ehdr *hdr = file;
438 Elf32_Shdr *sechdrs = file + hdr->e_shoff;
439 const char *secnames;
440 unsigned int i;
442 /* Too short? */
443 if (size < sizeof(*hdr))
444 return NULL;
445 if (size < hdr->e_shoff + hdr->e_shnum * sizeof(sechdrs[0]))
446 return NULL;
447 if (size < sechdrs[hdr->e_shstrndx].sh_offset)
448 return NULL;
450 secnames = file + sechdrs[hdr->e_shstrndx].sh_offset;
451 for (i = 1; i < hdr->e_shnum; i++)
452 if (strcmp(secnames + sechdrs[i].sh_name, name) == 0) {
453 *secsize = sechdrs[i].sh_size;
454 return file + sechdrs[i].sh_offset;
456 return NULL;
459 static void *get_section64(void *file,
460 unsigned long size,
461 const char *name,
462 unsigned long *secsize)
464 Elf64_Ehdr *hdr = file;
465 Elf64_Shdr *sechdrs = file + hdr->e_shoff;
466 const char *secnames;
467 unsigned int i;
469 /* Too short? */
470 if (size < sizeof(*hdr))
471 return NULL;
472 if (size < hdr->e_shoff + hdr->e_shnum * sizeof(sechdrs[0]))
473 return NULL;
474 if (size < sechdrs[hdr->e_shstrndx].sh_offset)
475 return NULL;
477 secnames = file + sechdrs[hdr->e_shstrndx].sh_offset;
478 for (i = 1; i < hdr->e_shnum; i++)
479 if (strcmp(secnames + sechdrs[i].sh_name, name) == 0) {
480 *secsize = sechdrs[i].sh_size;
481 return file + sechdrs[i].sh_offset;
483 return NULL;
486 static int elf_ident(void *mod, unsigned long size)
488 /* "\177ELF" <byte> where byte = 001 for 32-bit, 002 for 64 */
489 char *ident = mod;
491 if (size < EI_CLASS || memcmp(mod, ELFMAG, SELFMAG) != 0)
492 return ELFCLASSNONE;
493 return ident[EI_CLASS];
496 static void *get_section(void *file,
497 unsigned long size,
498 const char *name,
499 unsigned long *secsize)
501 switch (elf_ident(file, size)) {
502 case ELFCLASS32:
503 return get_section32(file, size, name, secsize);
504 case ELFCLASS64:
505 return get_section64(file, size, name, secsize);
506 default:
507 return NULL;
511 static void rename_module(struct module *module,
512 void *mod,
513 unsigned long len,
514 const char *newname)
516 void *modstruct;
517 unsigned long modstruct_len;
519 /* Old-style */
520 modstruct = get_section(mod, len, ".gnu.linkonce.this_module",
521 &modstruct_len);
522 /* New-style */
523 if (!modstruct)
524 modstruct = get_section(mod, len, "__module", &modstruct_len);
525 if (!modstruct)
526 warn("Could not find module name to change in %s\n",
527 module->filename);
528 else
529 replace_modname(module, modstruct, modstruct_len,
530 module->modname, newname);
533 /* Kernel told to ignore these sections if SHF_ALLOC not set. */
534 static void invalidate_section32(void *mod, const char *secname)
536 Elf32_Ehdr *hdr = mod;
537 Elf32_Shdr *sechdrs = mod + hdr->e_shoff;
538 const char *secnames = mod + sechdrs[hdr->e_shstrndx].sh_offset;
539 unsigned int i;
541 for (i = 1; i < hdr->e_shnum; i++)
542 if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0)
543 sechdrs[i].sh_flags &= ~SHF_ALLOC;
546 static void invalidate_section64(void *mod, const char *secname)
548 Elf64_Ehdr *hdr = mod;
549 Elf64_Shdr *sechdrs = mod + hdr->e_shoff;
550 const char *secnames = mod + sechdrs[hdr->e_shstrndx].sh_offset;
551 unsigned int i;
553 for (i = 1; i < hdr->e_shnum; i++)
554 if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0)
555 sechdrs[i].sh_flags &= ~(unsigned long long)SHF_ALLOC;
558 static void strip_section(struct module *module,
559 void *mod,
560 unsigned long len,
561 const char *secname)
563 switch (elf_ident(mod, len)) {
564 case ELFCLASS32:
565 invalidate_section32(mod, secname);
566 break;
567 case ELFCLASS64:
568 invalidate_section64(mod, secname);
569 break;
570 default:
571 warn("Unknown module format in %s: not forcing version\n",
572 module->filename);
576 static const char *next_string(const char *string, unsigned long *secsize)
578 /* Skip non-zero chars */
579 while (string[0]) {
580 string++;
581 if ((*secsize)-- <= 1)
582 return NULL;
585 /* Skip any zero padding. */
586 while (!string[0]) {
587 string++;
588 if ((*secsize)-- <= 1)
589 return NULL;
591 return string;
594 static void clear_magic(struct module *module, void *mod, unsigned long len)
596 const char *p;
597 unsigned long modlen;
599 /* Old-style: __vermagic section */
600 strip_section(module, mod, len, "__vermagic");
602 /* New-style: in .modinfo section */
603 for (p = get_section(mod, len, ".modinfo", &modlen);
605 p = next_string(p, &modlen)) {
606 if (strncmp(p, "vermagic=", strlen("vermagic=")) == 0) {
607 memset((char *)p, 0, strlen(p));
608 return;
613 struct module_options
615 struct module_options *next;
616 char *modulename;
617 char *options;
620 struct module_command
622 struct module_command *next;
623 char *modulename;
624 char *command;
627 struct module_alias
629 struct module_alias *next;
630 char *module;
633 struct module_blacklist
635 struct module_blacklist *next;
636 char *modulename;
639 /* Link in a new option line from the config file. */
640 static struct module_options *
641 add_options(const char *modname,
642 const char *option,
643 struct module_options *options)
645 struct module_options *new;
646 char *tab;
648 new = NOFAIL(malloc(sizeof(*new)));
649 new->modulename = NOFAIL(strdup(modname));
650 new->options = NOFAIL(strdup(option));
651 /* We can handle tabs, kernel can't. */
652 for (tab = strchr(new->options, '\t'); tab; tab = strchr(tab, '\t'))
653 *tab = ' ';
654 new->next = options;
655 return new;
658 /* Link in a new install line from the config file. */
659 static struct module_command *
660 add_command(const char *modname,
661 const char *command,
662 struct module_command *commands)
664 struct module_command *new;
666 new = NOFAIL(malloc(sizeof(*new)));
667 new->modulename = NOFAIL(strdup(modname));
668 new->command = NOFAIL(strdup(command));
669 new->next = commands;
670 return new;
673 /* Link in a new alias line from the config file. */
674 static struct module_alias *
675 add_alias(const char *modname, struct module_alias *aliases)
677 struct module_alias *new;
679 new = NOFAIL(malloc(sizeof(*new)));
680 new->module = NOFAIL(strdup(modname));
681 new->next = aliases;
682 return new;
685 /* Link in a new blacklist line from the config file. */
686 static struct module_blacklist *
687 add_blacklist(const char *modname, struct module_blacklist *blacklist)
689 struct module_blacklist *new;
691 new = NOFAIL(malloc(sizeof(*new)));
692 new->modulename = NOFAIL(strdup(modname));
693 new->next = blacklist;
694 return new;
697 /* Find blacklist commands if any. */
698 static int
699 find_blacklist(const char *modname, const struct module_blacklist *blacklist)
701 while (blacklist) {
702 if (strcmp(blacklist->modulename, modname) == 0)
703 return 1;
704 blacklist = blacklist->next;
706 return 0;
709 /* return a new alias list, with backlisted elems filtered out */
710 static struct module_alias *
711 apply_blacklist(const struct module_alias *aliases,
712 const struct module_blacklist *blacklist)
714 struct module_alias *result = NULL;
715 while (aliases) {
716 char *modname = aliases->module;
717 if (!find_blacklist(modname, blacklist))
718 result = add_alias(modname, result);
719 aliases = aliases->next;
721 return result;
724 /* Find install commands if any. */
725 static const char *find_command(const char *modname,
726 const struct module_command *commands)
728 while (commands) {
729 if (fnmatch(commands->modulename, modname, 0) == 0)
730 return commands->command;
731 commands = commands->next;
733 return NULL;
736 static char *append_option(char *options, const char *newoption)
738 options = NOFAIL(realloc(options, strlen(options) + 1
739 + strlen(newoption) + 1));
740 if (strlen(options)) strcat(options, " ");
741 strcat(options, newoption);
742 return options;
745 /* Add to options */
746 static char *add_extra_options(const char *modname,
747 char *optstring,
748 const struct module_options *options)
750 while (options) {
751 if (strcmp(options->modulename, modname) == 0)
752 optstring = append_option(optstring, options->options);
753 options = options->next;
755 return optstring;
758 /* If we don't flush, then child processes print before we do */
759 static void verbose_printf(int verbose, const char *fmt, ...)
761 va_list arglist;
763 if (verbose) {
764 va_start(arglist, fmt);
765 vprintf(fmt, arglist);
766 fflush(stdout);
767 va_end(arglist);
771 /* Do an install/remove command: replace $CMDLINE_OPTS if it's specified. */
772 static void do_command(const char *modname,
773 const char *command,
774 int verbose, int dry_run,
775 errfn_t error,
776 const char *type,
777 const char *cmdline_opts)
779 int ret;
780 char *p, *replaced_cmd = NOFAIL(strdup(command));
782 while ((p = strstr(replaced_cmd, "$CMDLINE_OPTS")) != NULL) {
783 char *new;
784 asprintf(&new, "%.*s%s%s",
785 (int)(p - replaced_cmd), replaced_cmd, cmdline_opts,
786 p + strlen("$CMDLINE_OPTS"));
787 NOFAIL(new);
788 free(replaced_cmd);
789 replaced_cmd = new;
792 verbose_printf(verbose, "%s %s\n", type, replaced_cmd);
793 if (dry_run)
794 return;
796 setenv("MODPROBE_MODULE", modname, 1);
797 ret = system(replaced_cmd);
798 if (ret == -1 || WEXITSTATUS(ret))
799 error("Error running %s command for %s\n", type, modname);
800 free(replaced_cmd);
803 /* Actually do the insert. Frees second arg. */
804 static void insmod(struct list_head *list,
805 char *optstring,
806 const char *newname,
807 int first_time,
808 errfn_t error,
809 int dry_run,
810 int verbose,
811 const struct module_options *options,
812 const struct module_command *commands,
813 int ignore_commands,
814 int ignore_proc,
815 int strip_vermagic,
816 int strip_modversion,
817 const char *cmdline_opts)
819 int ret, fd;
820 unsigned long len;
821 void *map;
822 const char *command;
823 struct module *mod = list_entry(list->next, struct module, list);
825 /* Take us off the list. */
826 list_del(&mod->list);
828 /* Do things we (or parent) depend on first, but don't die if
829 * they fail. */
830 if (!list_empty(list)) {
831 insmod(list, NOFAIL(strdup("")), NULL, 0, warn,
832 dry_run, verbose, options, commands, 0, ignore_proc,
833 strip_vermagic, strip_modversion, "");
836 /* Lock before we look, in case it's initializing. */
837 fd = lock_file(mod->filename);
838 if (fd < 0) {
839 error("Could not open '%s': %s\n",
840 mod->filename, strerror(errno));
841 goto out_optstring;
844 /* Don't do ANYTHING if already in kernel. */
845 if (!ignore_proc
846 && module_in_kernel(newname ?: mod->modname, NULL) == 1) {
847 if (first_time)
848 error("Module %s already in kernel.\n",
849 newname ?: mod->modname);
850 goto out_unlock;
853 command = find_command(mod->modname, commands);
854 if (command && !ignore_commands) {
855 /* It might recurse: unlock. */
856 unlock_file(fd);
857 do_command(mod->modname, command, verbose, dry_run, error,
858 "install", cmdline_opts);
859 goto out_optstring;
862 map = grab_fd(fd, &len);
863 if (!map) {
864 error("Could not read '%s': %s\n",
865 mod->filename, strerror(errno));
866 goto out_unlock;
869 /* Rename it? */
870 if (newname)
871 rename_module(mod, map, len, newname);
873 if (strip_modversion)
874 strip_section(mod, map, len, "__versions");
875 if (strip_vermagic)
876 clear_magic(mod, map, len);
878 /* Config file might have given more options */
879 optstring = add_extra_options(mod->modname, optstring, options);
881 verbose_printf(verbose, "insmod %s %s\n", mod->filename, optstring);
883 if (dry_run)
884 goto out;
886 ret = init_module(map, len, optstring);
887 if (ret != 0) {
888 if (errno == EEXIST) {
889 if (first_time)
890 error("Module %s already in kernel.\n",
891 newname ?: mod->modname);
892 goto out_unlock;
894 error("Error inserting %s (%s): %s\n",
895 mod->modname, mod->filename, insert_moderror(errno));
897 out:
898 release_file(map, len);
899 out_unlock:
900 unlock_file(fd);
901 out_optstring:
902 free(optstring);
903 return;
906 /* Do recursive removal. */
907 static void rmmod(struct list_head *list,
908 const char *name,
909 int first_time,
910 errfn_t error,
911 int dry_run,
912 int verbose,
913 struct module_command *commands,
914 int ignore_commands,
915 int ignore_inuse,
916 const char *cmdline_opts)
918 const char *command;
919 unsigned int usecount = 0;
920 int lock;
921 struct module *mod = list_entry(list->next, struct module, list);
923 /* Take first one off the list. */
924 list_del(&mod->list);
926 /* Ignore failure; it's best effort here. */
927 lock = lock_file(mod->filename);
929 if (!name)
930 name = mod->modname;
932 /* Even if renamed, find commands to orig. name. */
933 command = find_command(mod->modname, commands);
934 if (command && !ignore_commands) {
935 /* It might recurse: unlock. */
936 unlock_file(lock);
937 do_command(mod->modname, command, verbose, dry_run, error,
938 "remove", cmdline_opts);
939 goto remove_rest_no_unlock;
942 if (module_in_kernel(name, &usecount) == 0)
943 goto nonexistent_module;
945 if (usecount != 0) {
946 if (!ignore_inuse)
947 error("Module %s is in use.\n", name);
948 goto remove_rest;
951 verbose_printf(verbose, "rmmod %s\n", mod->filename);
953 if (dry_run)
954 goto remove_rest;
956 if (delete_module(name, O_EXCL) != 0) {
957 if (errno == ENOENT)
958 goto nonexistent_module;
959 error("Error removing %s (%s): %s\n",
960 name, mod->filename,
961 remove_moderror(errno));
964 remove_rest:
965 unlock_file(lock);
966 remove_rest_no_unlock:
967 /* Now do things we depend. */
968 if (!list_empty(list))
969 rmmod(list, NULL, 0, warn, dry_run, verbose, commands,
970 0, 1, "");
971 return;
973 nonexistent_module:
974 if (first_time)
975 fatal("Module %s is not in kernel.\n", mod->modname);
976 goto remove_rest;
979 /* Does path contain directory(s) subpath? */
980 static int type_matches(const char *path, const char *subpath)
982 char *subpath_with_slashes;
983 int ret;
985 asprintf(&subpath_with_slashes, "/%s/", subpath);
986 NOFAIL(subpath_with_slashes);
988 ret = (strstr(path, subpath_with_slashes) != NULL);
989 free(subpath_with_slashes);
990 return ret;
993 /* Careful! Don't munge - in [ ] as per Debian Bug#350915 */
994 static char *underscores(char *string)
996 if (string) {
997 unsigned int i;
998 int inbracket = 0;
999 for (i = 0; string[i]; i++) {
1000 switch (string[i]) {
1001 case '[':
1002 inbracket++;
1003 break;
1004 case ']':
1005 inbracket--;
1006 break;
1007 case '-':
1008 if (!inbracket)
1009 string[i] = '_';
1012 if (inbracket)
1013 warn("Unmatched bracket in %s\n", string);
1015 return string;
1018 static int do_wildcard(const char *dirname,
1019 const char *type,
1020 const char *wildcard)
1022 char modules_dep_name[strlen(dirname) + sizeof("modules.dep") + 1];
1023 char *line, *wcard;
1024 FILE *modules_dep;
1026 /* Canonicalize wildcard */
1027 wcard = strdup(wildcard);
1028 underscores(wcard);
1030 sprintf(modules_dep_name, "%s/%s", dirname, "modules.dep");
1031 modules_dep = fopen(modules_dep_name, "r");
1032 if (!modules_dep)
1033 fatal("Could not load %s: %s\n",
1034 modules_dep_name, strerror(errno));
1036 while ((line = getline_wrapped(modules_dep, NULL)) != NULL) {
1037 char *ptr;
1039 /* Ignore lines without : or which start with a # */
1040 ptr = strchr(line, ':');
1041 if (ptr == NULL || line[strspn(line, "\t ")] == '#')
1042 goto next;
1043 *ptr = '\0';
1045 /* "type" must match complete directory component(s). */
1046 if (!type || type_matches(line, type)) {
1047 char modname[strlen(line)+1];
1049 filename2modname(modname, line);
1050 if (fnmatch(wcard, modname, 0) == 0)
1051 printf("%s\n", line);
1053 next:
1054 free(line);
1057 free(wcard);
1058 return 0;
1061 static char *strsep_skipspace(char **string, char *delim)
1063 if (!*string)
1064 return NULL;
1065 *string += strspn(*string, delim);
1066 return strsep(string, delim);
1069 /* Recursion */
1070 static int read_config(const char *filename,
1071 const char *name,
1072 int dump_only,
1073 int removing,
1074 struct module_options **options,
1075 struct module_command **commands,
1076 struct module_alias **alias,
1077 struct module_blacklist **blacklist);
1079 /* FIXME: Maybe should be extended to "alias a b [and|or c]...". --RR */
1080 static int read_config_file(const char *filename,
1081 const char *name,
1082 int dump_only,
1083 int removing,
1084 struct module_options **options,
1085 struct module_command **commands,
1086 struct module_alias **aliases,
1087 struct module_blacklist **blacklist)
1089 char *line;
1090 unsigned int linenum = 0;
1091 FILE *cfile;
1093 cfile = fopen(filename, "r");
1094 if (!cfile)
1095 return 0;
1097 while ((line = getline_wrapped(cfile, &linenum)) != NULL) {
1098 char *ptr = line;
1099 char *cmd, *modname;
1101 if (dump_only)
1102 printf("%s\n", line);
1104 cmd = strsep_skipspace(&ptr, "\t ");
1105 if (cmd == NULL || cmd[0] == '#' || cmd[0] == '\0')
1106 continue;
1108 if (strcmp(cmd, "alias") == 0) {
1109 char *wildcard
1110 = underscores(strsep_skipspace(&ptr, "\t "));
1111 char *realname
1112 = underscores(strsep_skipspace(&ptr, "\t "));
1114 if (!wildcard || !realname)
1115 grammar(cmd, filename, linenum);
1116 else if (fnmatch(wildcard,name,0) == 0)
1117 *aliases = add_alias(realname, *aliases);
1118 } else if (strcmp(cmd, "include") == 0) {
1119 struct module_alias *newalias = NULL;
1120 char *newfilename;
1122 newfilename = strsep_skipspace(&ptr, "\t ");
1123 if (!newfilename)
1124 grammar(cmd, filename, linenum);
1125 else {
1126 if (!read_config(newfilename, name,
1127 dump_only, removing,
1128 options, commands, &newalias,
1129 blacklist))
1130 warn("Failed to open included"
1131 " config file %s: %s\n",
1132 newfilename, strerror(errno));
1134 /* Files included override aliases,
1135 etc that was already set ... */
1136 if (newalias)
1137 *aliases = newalias;
1139 } else if (strcmp(cmd, "options") == 0) {
1140 modname = strsep_skipspace(&ptr, "\t ");
1141 if (!modname || !ptr)
1142 grammar(cmd, filename, linenum);
1143 else {
1144 ptr += strspn(ptr, "\t ");
1145 *options = add_options(underscores(modname),
1146 ptr, *options);
1148 } else if (strcmp(cmd, "install") == 0) {
1149 modname = strsep_skipspace(&ptr, "\t ");
1150 if (!modname || !ptr)
1151 grammar(cmd, filename, linenum);
1152 else if (!removing) {
1153 ptr += strspn(ptr, "\t ");
1154 *commands = add_command(underscores(modname),
1155 ptr, *commands);
1157 } else if (strcmp(cmd, "blacklist") == 0) {
1158 modname = strsep_skipspace(&ptr, "\t ");
1159 if (!modname)
1160 grammar(cmd, filename, linenum);
1161 else if (!removing) {
1162 *blacklist = add_blacklist(underscores(modname),
1163 *blacklist);
1165 } else if (strcmp(cmd, "remove") == 0) {
1166 modname = strsep_skipspace(&ptr, "\t ");
1167 if (!modname || !ptr)
1168 grammar(cmd, filename, linenum);
1169 else if (removing) {
1170 ptr += strspn(ptr, "\t ");
1171 *commands = add_command(underscores(modname),
1172 ptr, *commands);
1174 } else
1175 grammar(cmd, filename, linenum);
1177 free(line);
1179 fclose(cfile);
1180 return 1;
1183 /* Simple format, ignore lines starting with #, one command per line.
1184 Returns true or false. */
1185 static int read_config(const char *filename,
1186 const char *name,
1187 int dump_only,
1188 int removing,
1189 struct module_options **options,
1190 struct module_command **commands,
1191 struct module_alias **aliases,
1192 struct module_blacklist **blacklist)
1194 DIR *dir;
1195 int ret = 0;
1197 /* Reiser4 has file/directory duality: treat it as both. */
1198 dir = opendir(filename);
1199 if (dir) {
1200 struct dirent *i;
1201 while ((i = readdir(dir)) != NULL) {
1202 if (!streq(i->d_name,".") && !streq(i->d_name,"..")) {
1203 char sub[strlen(filename) + 1
1204 + strlen(i->d_name) + 1];
1206 sprintf(sub, "%s/%s", filename, i->d_name);
1207 if (!read_config(sub, name,
1208 dump_only, removing, options,
1209 commands, aliases, blacklist))
1210 warn("Failed to open"
1211 " config file %s: %s\n",
1212 sub, strerror(errno));
1215 closedir(dir);
1216 ret = 1;
1219 if (read_config_file(filename, name, dump_only, removing,
1220 options, commands, aliases, blacklist))
1221 ret = 1;
1223 return ret;
1226 static const char *default_configs[] =
1228 "/etc/modprobe.conf",
1229 "/etc/modprobe.d",
1232 static void read_toplevel_config(const char *filename,
1233 const char *name,
1234 int dump_only,
1235 int removing,
1236 struct module_options **options,
1237 struct module_command **commands,
1238 struct module_alias **aliases,
1239 struct module_blacklist **blacklist)
1241 unsigned int i;
1243 if (filename) {
1244 if (!read_config(filename, name, dump_only, removing,
1245 options, commands, aliases, blacklist))
1246 fatal("Failed to open config file %s: %s\n",
1247 filename, strerror(errno));
1248 return;
1251 /* Try defaults. */
1252 for (i = 0; i < ARRAY_SIZE(default_configs); i++) {
1253 if (read_config(default_configs[i], name, dump_only, removing,
1254 options, commands, aliases, blacklist))
1255 return;
1259 static void add_to_env_var(const char *option)
1261 const char *oldenv;
1263 if ((oldenv = getenv("MODPROBE_OPTIONS")) != NULL) {
1264 char *newenv;
1265 asprintf(&newenv, "%s %s", oldenv, option);
1266 setenv("MODPROBE_OPTIONS", newenv, 1);
1267 } else
1268 setenv("MODPROBE_OPTIONS", option, 1);
1271 /* Prepend options from environment. */
1272 static char **merge_args(char *args, char *argv[], int *argc)
1274 char *arg, *argstring;
1275 char **newargs = NULL;
1276 unsigned int i, num_env = 0;
1278 if (!args)
1279 return argv;
1281 argstring = NOFAIL(strdup(args));
1282 for (arg = strtok(argstring, " "); arg; arg = strtok(NULL, " ")) {
1283 num_env++;
1284 newargs = NOFAIL(realloc(newargs,
1285 sizeof(newargs[0])
1286 * (num_env + *argc + 1)));
1287 newargs[num_env] = arg;
1290 /* Append commandline args */
1291 newargs[0] = argv[0];
1292 for (i = 1; i <= *argc; i++)
1293 newargs[num_env+i] = argv[i];
1295 *argc += num_env;
1296 return newargs;
1299 static char *gather_options(char *argv[])
1301 char *optstring = NOFAIL(strdup(""));
1303 /* Rest is module options */
1304 while (*argv) {
1305 /* Quote value if it contains spaces. */
1306 unsigned int eq = strcspn(*argv, "=");
1308 if (strchr(*argv+eq, ' ') && !strchr(*argv, '"')) {
1309 char quoted[strlen(*argv) + 3];
1310 (*argv)[eq] = '\0';
1311 sprintf(quoted, "%s=\"%s\"", *argv, *argv+eq+1);
1312 optstring = append_option(optstring, quoted);
1313 } else
1314 optstring = append_option(optstring, *argv);
1315 argv++;
1317 return optstring;
1320 static void handle_module(const char *modname,
1321 struct list_head *todo_list,
1322 const char *newname,
1323 int remove,
1324 char *options,
1325 int first_time,
1326 errfn_t error,
1327 int dry_run,
1328 int verbose,
1329 struct module_options *modoptions,
1330 struct module_command *commands,
1331 int ignore_commands,
1332 int ignore_proc,
1333 int strip_vermagic,
1334 int strip_modversion,
1335 int unknown_silent,
1336 const char *cmdline_opts)
1338 if (list_empty(todo_list)) {
1339 const char *command;
1341 /* The dependencies have to be real modules, but
1342 handle case where the first is completely bogus. */
1343 command = find_command(modname, commands);
1344 if (command && !ignore_commands) {
1345 do_command(modname, command, verbose, dry_run, error,
1346 remove ? "remove":"install", cmdline_opts);
1347 return;
1350 if (unknown_silent)
1351 exit(1);
1352 error("Module %s not found.\n", modname);
1353 return;
1356 if (remove)
1357 rmmod(todo_list, newname, first_time, error, dry_run, verbose,
1358 commands, ignore_commands, 0, cmdline_opts);
1359 else
1360 insmod(todo_list, NOFAIL(strdup(options)), newname,
1361 first_time, error, dry_run, verbose, modoptions,
1362 commands, ignore_commands, ignore_proc, strip_vermagic,
1363 strip_modversion, cmdline_opts);
1366 static struct option options[] = { { "verbose", 0, NULL, 'v' },
1367 { "version", 0, NULL, 'V' },
1368 { "config", 1, NULL, 'C' },
1369 { "name", 1, NULL, 'o' },
1370 { "remove", 0, NULL, 'r' },
1371 { "showconfig", 0, NULL, 'c' },
1372 { "autoclean", 0, NULL, 'k' },
1373 { "quiet", 0, NULL, 'q' },
1374 { "show", 0, NULL, 'n' },
1375 { "dry-run", 0, NULL, 'n' },
1376 { "syslog", 0, NULL, 's' },
1377 { "type", 1, NULL, 't' },
1378 { "list", 0, NULL, 'l' },
1379 { "all", 0, NULL, 'a' },
1380 { "ignore-install", 0, NULL, 'i' },
1381 { "ignore-remove", 0, NULL, 'i' },
1382 { "force", 0, NULL, 'f' },
1383 { "force-vermagic", 0, NULL, 1 },
1384 { "force-modversion", 0, NULL, 2 },
1385 { "set-version", 1, NULL, 'S' },
1386 { "show-depends", 0, NULL, 'D' },
1387 { "first-time", 0, NULL, 3 },
1388 { "use-blacklist", 0, NULL, 'b' },
1389 { NULL, 0, NULL, 0 } };
1391 #define MODPROBE_DEVFSD_CONF "/etc/modprobe.devfs"
1393 /* This is a horrible hack to allow devfsd, which calls modprobe with
1394 -C /etc/modules.conf or /etc/modules.devfs, to work. FIXME. */
1395 /* Modern devfsd or variants should use -q explicitly in 2.6. */
1396 static int is_devfs_call(char *argv[])
1398 unsigned int i;
1400 /* Look for "/dev" arg */
1401 for (i = 1; argv[i]; i++) {
1402 if (strncmp(argv[i], "/dev/", 5) == 0)
1403 return 1;
1405 return 0;
1408 int main(int argc, char *argv[])
1410 struct utsname buf;
1411 struct stat statbuf;
1412 int opt;
1413 int dump_only = 0;
1414 int dry_run = 0;
1415 int remove = 0;
1416 int verbose = 0;
1417 int unknown_silent = 0;
1418 int list_only = 0;
1419 int all = 0;
1420 int ignore_commands = 0;
1421 int strip_vermagic = 0;
1422 int strip_modversion = 0;
1423 int ignore_proc = 0;
1424 int first_time = 0;
1425 int use_blacklist = 0;
1426 unsigned int i, num_modules;
1427 char *type = NULL;
1428 const char *config = NULL;
1429 char *dirname, *optstring;
1430 char *newname = NULL;
1431 char *aliasfilename, *symfilename;
1432 errfn_t error = fatal;
1434 /* Prepend options from environment. */
1435 argv = merge_args(getenv("MODPROBE_OPTIONS"), argv, &argc);
1437 /* --set-version overrides version, and disables backwards compat. */
1438 for (opt = 1; opt < argc; opt++)
1439 if (strncmp(argv[opt],"--set-version",strlen("--set-version"))
1440 == 0)
1441 break;
1443 if (opt == argc)
1444 try_old_version("modprobe", argv);
1446 uname(&buf);
1447 while ((opt = getopt_long(argc, argv, "vVC:o:rknqQsclt:aifb", options, NULL)) != -1){
1448 switch (opt) {
1449 case 'v':
1450 add_to_env_var("-v");
1451 verbose = 1;
1452 break;
1453 case 'V':
1454 puts(PACKAGE " version " VERSION);
1455 exit(0);
1456 case 'S':
1457 strncpy(buf.release, optarg, sizeof(buf.release));
1458 buf.release[sizeof(buf.release)-1] = '\0';
1459 break;
1460 case 'C':
1461 if (is_devfs_call(argv)) {
1462 if (streq("/etc/modules.devfs", optarg)) {
1463 config = MODPROBE_DEVFSD_CONF;
1464 add_to_env_var("-C");
1465 add_to_env_var(config);
1466 /* Fall thru to -q */
1467 } else if (streq("/etc/modules.conf", optarg))
1468 /* Ignore config, fall thru to -q */
1470 else {
1471 /* False alarm. Treat as normal. */
1472 config = optarg;
1473 add_to_env_var("-C");
1474 add_to_env_var(config);
1475 break;
1477 } else {
1478 config = optarg;
1479 add_to_env_var("-C");
1480 add_to_env_var(config);
1481 break;
1483 case 'q':
1484 unknown_silent = 1;
1485 add_to_env_var("-q");
1486 break;
1487 case 'D':
1488 dry_run = 1;
1489 ignore_proc = 1;
1490 verbose = 1;
1491 add_to_env_var("-D");
1492 break;
1493 case 'o':
1494 newname = optarg;
1495 break;
1496 case 'r':
1497 remove = 1;
1498 break;
1499 case 'c':
1500 dump_only = 1;
1501 break;
1502 case 't':
1503 type = optarg;
1504 break;
1505 case 'l':
1506 list_only = 1;
1507 break;
1508 case 'a':
1509 all = 1;
1510 error = warn;
1511 break;
1512 case 'k':
1513 /* FIXME: This should actually do something */
1514 break;
1515 case 'n':
1516 dry_run = 1;
1517 break;
1518 case 's':
1519 add_to_env_var("-s");
1520 log = 1;
1521 break;
1522 case 'i':
1523 ignore_commands = 1;
1524 break;
1525 case 'f':
1526 strip_vermagic = 1;
1527 strip_modversion = 1;
1528 break;
1529 case 'b':
1530 use_blacklist = 1;
1531 break;
1532 case 1:
1533 strip_vermagic = 1;
1534 break;
1535 case 2:
1536 strip_modversion = 1;
1537 break;
1538 case 3:
1539 first_time = 1;
1540 break;
1541 default:
1542 print_usage(argv[0]);
1546 /* If stderr not open, go to syslog */
1547 if (log || fstat(STDERR_FILENO, &statbuf) != 0) {
1548 openlog("modprobe", LOG_CONS, LOG_DAEMON);
1549 log = 1;
1552 if (argc < optind + 1 && !dump_only && !list_only && !remove)
1553 print_usage(argv[0]);
1555 dirname = NOFAIL(malloc(strlen(buf.release) + sizeof(MODULE_DIR) + 1));
1556 sprintf(dirname, "%s/%s", MODULE_DIR, buf.release);
1557 aliasfilename = NOFAIL(malloc(strlen(dirname)
1558 + sizeof("/modules.alias")));
1559 sprintf(aliasfilename, "%s/modules.alias", dirname);
1560 symfilename = NOFAIL(malloc(strlen(dirname)
1561 + sizeof("/modules.symbols")));
1562 sprintf(symfilename, "%s/modules.symbols", dirname);
1564 /* Old-style -t xxx wildcard? Only with -l. */
1565 if (list_only) {
1566 if (optind+1 < argc)
1567 fatal("Can't have multiple wildcards\n");
1568 /* fprintf(stderr, "man find\n"); return 1; */
1569 return do_wildcard(dirname, type, argv[optind]?:"*");
1571 if (type)
1572 fatal("-t only supported with -l");
1574 if (dump_only) {
1575 struct module_command *commands = NULL;
1576 struct module_options *modoptions = NULL;
1577 struct module_alias *aliases = NULL;
1578 struct module_blacklist *blacklist = NULL;
1580 read_toplevel_config(config, "", 1, 0,
1581 &modoptions, &commands, &aliases, &blacklist);
1582 read_config(aliasfilename, "", 1, 0,&modoptions, &commands,
1583 &aliases, &blacklist);
1584 read_config(symfilename, "", 1, 0, &modoptions, &commands,
1585 &aliases, &blacklist);
1586 exit(0);
1589 if (remove || all) {
1590 num_modules = argc - optind;
1591 optstring = NOFAIL(strdup(""));
1592 } else {
1593 num_modules = 1;
1594 optstring = gather_options(argv+optind+1);
1597 /* num_modules is always 1 except for -r or -a. */
1598 for (i = 0; i < num_modules; i++) {
1599 struct module_command *commands = NULL;
1600 struct module_options *modoptions = NULL;
1601 struct module_alias *aliases = NULL;
1602 struct module_blacklist *blacklist = NULL;
1603 LIST_HEAD(list);
1604 char *modulearg = argv[optind + i];
1606 /* Convert name we are looking for */
1607 underscores(modulearg);
1609 /* Returns the resolved alias, options */
1610 read_toplevel_config(config, modulearg, 0,
1611 remove, &modoptions, &commands, &aliases, &blacklist);
1613 /* No luck? Try symbol names, if starts with symbol:. */
1614 if (!aliases
1615 && strncmp(modulearg, "symbol:", strlen("symbol:")) == 0)
1616 read_config(symfilename, modulearg, 0,
1617 remove, &modoptions, &commands,
1618 &aliases, &blacklist);
1620 if (!aliases) {
1621 /* We only use canned aliases as last resort. */
1622 read_depends(dirname, modulearg, &list);
1624 if (list_empty(&list)
1625 && !find_command(modulearg, commands))
1627 read_config(aliasfilename, modulearg, 0,
1628 remove, &modoptions, &commands,
1629 &aliases, &blacklist);
1630 aliases = apply_blacklist(aliases, blacklist);
1634 if (aliases) {
1635 errfn_t err = error;
1637 /* More than one alias? Don't bail out on failure. */
1638 if (aliases->next)
1639 err = warn;
1640 while (aliases) {
1641 /* Add the options for this alias. */
1642 char *opts = NOFAIL(strdup(optstring));
1643 opts = add_extra_options(modulearg,
1644 opts, modoptions);
1646 read_depends(dirname, aliases->module, &list);
1647 handle_module(aliases->module, &list, newname,
1648 remove, opts, first_time, err,
1649 dry_run, verbose, modoptions,
1650 commands, ignore_commands,
1651 ignore_proc, strip_vermagic,
1652 strip_modversion,
1653 unknown_silent,
1654 optstring);
1656 aliases = aliases->next;
1657 INIT_LIST_HEAD(&list);
1659 } else {
1660 if (use_blacklist
1661 && find_blacklist(modulearg, blacklist))
1662 continue;
1664 handle_module(modulearg, &list, newname, remove,
1665 optstring, first_time, error, dry_run,
1666 verbose, modoptions, commands,
1667 ignore_commands, ignore_proc,
1668 strip_vermagic, strip_modversion,
1669 unknown_silent, optstring);
1672 if (log)
1673 closelog();
1675 return 0;