1 Index: klibc-1.5/usr/utils/Kbuild
2 ===================================================================
3 --- klibc-1.5.orig/usr/utils/Kbuild 2008-03-07 22:01:45.223695348 +0100
4 +++ klibc-1.5/usr/utils/Kbuild 2008-03-07 22:48:44.660783243 +0100
8 progs := chroot dd mkdir mkfifo mknod mount pivot_root umount
9 -progs += true false sleep ln nuke minips cat
10 -progs += insmod uname halt kill readlink cpio
11 +progs += true false sleep ln nuke minips cat losetup
12 +progs += insmod uname halt kill readlink cpio modprobe
14 static-y := $(addprefix static/, $(progs))
15 shared-y := $(addprefix shared/, $(progs))
17 shared/readlink-y := readlink.o
18 static/cpio-y := cpio.o
19 shared/cpio-y := cpio.o
21 +static/modprobe-y := modprobe.o
22 +shared/modprobe-y := modprobe.o
23 +static/losetup-y := losetup.o
24 +shared/losetup-y := losetup.o
25 # Additionally linked targets
26 always := static/reboot static/poweroff shared/reboot shared/poweroff
28 Index: klibc-1.5/usr/utils/list.h
29 ===================================================================
30 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
31 +++ klibc-1.5/usr/utils/list.h 2008-03-07 22:33:22.287688586 +0100
33 +/* Stolen from Linux Kernel Source's list.h -- GPL. */
34 +#ifndef _MODINITTOOLS_LIST_H
35 +#define _MODINITTOOLS_LIST_H
38 +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
41 + * container_of - cast a member of a structure out to the containing structure
43 + * @ptr: the pointer to the member.
44 + * @type: the type of the container struct this is embedded in.
45 + * @member: the name of the member within the struct.
48 +#define container_of(ptr, type, member) ({ \
49 + const typeof( ((type *)0)->member ) *__mptr = (ptr); \
50 + (type *)( (char *)__mptr - offsetof(type,member) );})
53 + * Simple doubly linked list implementation.
55 + * Some of the internal functions ("__xxx") are useful when
56 + * manipulating whole lists rather than single entries, as
57 + * sometimes we already know the next/prev entries and we can
58 + * generate better code by using them directly rather than
59 + * using the generic single-entry routines.
63 + struct list_head *next, *prev;
66 +#define LIST_HEAD_INIT(name) { &(name), &(name) }
68 +#define LIST_HEAD(name) \
69 + struct list_head name = LIST_HEAD_INIT(name)
71 +#define INIT_LIST_HEAD(ptr) do { \
72 + (ptr)->next = (ptr); (ptr)->prev = (ptr); \
76 + * Insert a new entry between two known consecutive entries.
78 + * This is only for internal list manipulation where we know
79 + * the prev/next entries already!
81 +static inline void __list_add(struct list_head *new,
82 + struct list_head *prev,
83 + struct list_head *next)
92 + * list_add - add a new entry
93 + * @new: new entry to be added
94 + * @head: list head to add it after
96 + * Insert a new entry after the specified head.
97 + * This is good for implementing stacks.
99 +static inline void list_add(struct list_head *new, struct list_head *head)
101 + __list_add(new, head, head->next);
105 + * list_add_tail - add a new entry
106 + * @new: new entry to be added
107 + * @head: list head to add it before
109 + * Insert a new entry before the specified head.
110 + * This is useful for implementing queues.
112 +static inline void list_add_tail(struct list_head *new, struct list_head *head)
114 + __list_add(new, head->prev, head);
118 + * Delete a list entry by making the prev/next entries
119 + * point to each other.
121 + * This is only for internal list manipulation where we know
122 + * the prev/next entries already!
124 +static inline void __list_del(struct list_head * prev, struct list_head * next)
131 + * list_del - deletes entry from list.
132 + * @entry: the element to delete from the list.
133 + * Note: list_empty on entry does not return true after this, the entry is
134 + * in an undefined state.
136 +static inline void list_del(struct list_head *entry)
138 + __list_del(entry->prev, entry->next);
142 + * list_del_init - deletes entry from list and reinitialize it.
143 + * @entry: the element to delete from the list.
145 +static inline void list_del_init(struct list_head *entry)
147 + __list_del(entry->prev, entry->next);
148 + INIT_LIST_HEAD(entry);
152 + * list_move - delete from one list and add as another's head
153 + * @list: the entry to move
154 + * @head: the head that will precede our entry
156 +static inline void list_move(struct list_head *list, struct list_head *head)
158 + __list_del(list->prev, list->next);
159 + list_add(list, head);
163 + * list_move_tail - delete from one list and add as another's tail
164 + * @list: the entry to move
165 + * @head: the head that will follow our entry
167 +static inline void list_move_tail(struct list_head *list,
168 + struct list_head *head)
170 + __list_del(list->prev, list->next);
171 + list_add_tail(list, head);
175 + * list_empty - tests whether a list is empty
176 + * @head: the list to test.
178 +static inline int list_empty(struct list_head *head)
180 + return head->next == head;
183 +static inline void __list_splice(struct list_head *list,
184 + struct list_head *head)
186 + struct list_head *first = list->next;
187 + struct list_head *last = list->prev;
188 + struct list_head *at = head->next;
190 + first->prev = head;
191 + head->next = first;
198 + * list_splice - join two lists
199 + * @list: the new list to add.
200 + * @head: the place to add it in the first list.
202 +static inline void list_splice(struct list_head *list, struct list_head *head)
204 + if (!list_empty(list))
205 + __list_splice(list, head);
209 + * list_splice_init - join two lists and reinitialise the emptied list.
210 + * @list: the new list to add.
211 + * @head: the place to add it in the first list.
213 + * The list at @list is reinitialised
215 +static inline void list_splice_init(struct list_head *list,
216 + struct list_head *head)
218 + if (!list_empty(list)) {
219 + __list_splice(list, head);
220 + INIT_LIST_HEAD(list);
225 + * list_entry - get the struct for this entry
226 + * @ptr: the &struct list_head pointer.
227 + * @type: the type of the struct this is embedded in.
228 + * @member: the name of the list_struct within the struct.
230 +#define list_entry(ptr, type, member) \
231 + container_of(ptr, type, member)
234 + * list_for_each - iterate over a list
235 + * @pos: the &struct list_head to use as a loop counter.
236 + * @head: the head for your list.
238 +#define list_for_each(pos, head) \
239 + for (pos = (head)->next; pos != (head); pos = pos->next)
242 + * list_for_each_prev - iterate over a list backwards
243 + * @pos: the &struct list_head to use as a loop counter.
244 + * @head: the head for your list.
246 +#define list_for_each_prev(pos, head) \
247 + for (pos = (head)->prev; pos != (head); pos = pos->prev)
250 + * list_for_each_safe - iterate over a list safe against removal of list entry
251 + * @pos: the &struct list_head to use as a loop counter.
252 + * @n: another &struct list_head to use as temporary storage
253 + * @head: the head for your list.
255 +#define list_for_each_safe(pos, n, head) \
256 + for (pos = (head)->next, n = pos->next; pos != (head); \
257 + pos = n, n = pos->next)
260 + * list_for_each_entry - iterate over list of given type
261 + * @pos: the type * to use as a loop counter.
262 + * @head: the head for your list.
263 + * @member: the name of the list_struct within the struct.
265 +#define list_for_each_entry(pos, head, member) \
266 + for (pos = list_entry((head)->next, typeof(*pos), member); \
267 + &pos->member != (head); \
268 + pos = list_entry(pos->member.next, typeof(*pos), member))
271 Index: klibc-1.5/usr/utils/modprobe.c
272 ===================================================================
273 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
274 +++ klibc-1.5/usr/utils/modprobe.c 2008-03-08 03:05:51.847688952 +0100
276 +/* modprobe.c: insert a module into the kernel, intelligently.
277 + Copyright (C) 2001 Rusty Russell.
278 + Copyright (C) 2002, 2003 Rusty Russell, IBM Corporation.
280 + This program is free software; you can redistribute it and/or modify
281 + it under the terms of the GNU General Public License as published by
282 + the Free Software Foundation; either version 2 of the License, or
283 + (at your option) any later version.
285 + This program is distributed in the hope that it will be useful,
286 + but WITHOUT ANY WARRANTY; without even the implied warranty of
287 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
288 + GNU General Public License for more details.
290 + You should have received a copy of the GNU General Public License
291 + along with this program; if not, write to the Free Software
292 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
294 +#define _GNU_SOURCE /* asprintf */
296 +#include <sys/utsname.h>
297 +#include <sys/types.h>
298 +#include <sys/stat.h>
299 +#include <sys/mman.h>
312 +#include <fnmatch.h>
313 +#include <asm/unistd.h>
314 +#include <sys/wait.h>
318 +#define streq(a,b) (strcmp((a),(b)) == 0)
319 +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
322 +static inline void try_old_version(const char *progname, char *argv[])
325 +extern long init_module(void *, unsigned long, const char *);
326 +extern long delete_module(const char *, unsigned int);
329 + struct list_head list;
335 +#define MODULE_DIR "/lib/modules"
338 +typedef void (*errfn_t)(const char *fmt, ...);
340 +/* Do we use syslog or stderr for messages? */
343 +static void message(const char *prefix, const char *fmt, va_list *arglist)
347 + vasprintf(&buf, fmt, *arglist);
348 + asprintf(&buf2, "%s%s", prefix, buf);
351 + syslog(LOG_NOTICE, "%s", buf2);
353 + fprintf(stderr, "%s", buf2);
357 +void *grab_contents(gzFile *gzfd, unsigned long *size)
359 + unsigned int max = 16384;
360 + void *buffer = malloc(max);
367 + while ((ret = gzread(gzfd, buffer + *size, max - *size)) > 0) {
369 + if (*size == max) {
370 + buffer = realloc(buffer, max *= 2);
382 +void *grab_fd(int fd, unsigned long *size)
386 + gzfd = gzdopen(fd, "rb");
390 + /* gzclose(gzfd) would close fd, which would drop locks.
391 + Don't blame zlib: POSIX locking semantics are so horribly
392 + broken that they should be ripped out. */
393 + return grab_contents(gzfd, size);
395 +void release_file(void *data, unsigned long size)
401 +static int warned = 0;
402 +static void warn(const char *fmt, ...)
406 + va_start(arglist, fmt);
407 + message("WARNING: ", fmt, &arglist);
411 +static void fatal(const char *fmt, ...)
414 + va_start(arglist, fmt);
415 + message("FATAL: ", fmt, &arglist);
421 +static void grammar(const char *cmd, const char *filename, unsigned int line)
423 + warn("%s line %u: ignoring bad line starting with '%s'\n",
424 + filename, line, cmd);
427 +static void *do_nofail(void *ptr, const char *file, int line, const char *expr)
430 + fatal("Memory allocation failure %s line %d: %s.\n",
436 +#define NOFAIL(ptr) do_nofail((ptr), __FILE__, __LINE__, #ptr)
438 +static void print_usage(const char *progname)
441 + "Usage: %s [-v] [-V] [-C config-file] [-n] [-i] [-q] [-b] [-o <modname>] <modname> [parameters...]\n"
442 + "%s -r [-n] [-i] [-v] <modulename> ...\n"
443 + "%s -l -t <dirname> [ -a <modulename> ...]\n",
444 + progname, progname, progname);
448 +static int fgetc_wrapped(FILE *file, unsigned int *linenum)
451 + int ch = fgetc(file);
462 +static char *getline_wrapped(FILE *file, unsigned int *linenum)
466 + char *buf = NOFAIL(malloc(size));
468 + int ch = fgetc_wrapped(file, linenum);
471 + buf = NOFAIL(realloc(buf, size));
473 + if (ch < 0 && i == 0) {
477 + if (ch < 0 || ch == '\n') {
481 + return NOFAIL(realloc(buf, i+1));
487 +static struct module *find_module(const char *filename, struct list_head *list)
491 + list_for_each_entry(i, list, list) {
492 + if (strcmp(i->filename, filename) == 0)
498 +/* Convert filename to the module name. Works if filename == modname, too. */
499 +static void filename2modname(char *modname, const char *filename)
501 + const char *afterslash;
504 + afterslash = strrchr(filename, '/');
506 + afterslash = filename;
510 + /* Convert to underscores, stop at first . */
511 + for (i = 0; afterslash[i] && afterslash[i] != '.'; i++) {
512 + if (afterslash[i] == '-')
515 + modname[i] = afterslash[i];
520 +static int lock_file(const char *filename)
522 + int fd = open(filename, O_RDWR, 0);
526 + lock.l_type = F_WRLCK;
527 + lock.l_whence = SEEK_SET;
530 + fcntl(fd, F_SETLKW, &lock);
532 + /* Read-only filesystem? There goes locking... */
533 + fd = open(filename, O_RDONLY, 0);
537 +static void unlock_file(int fd)
539 + /* Valgrind is picky... */
543 +static void add_module(char *filename, int namelen, struct list_head *list)
545 + struct module *mod;
547 + /* If it's a duplicate: move it to the end, so it gets
548 + inserted where it is *first* required. */
549 + mod = find_module(filename, list);
551 + list_del(&mod->list);
553 + /* No match. Create a new module. */
554 + mod = NOFAIL(malloc(sizeof(struct module) + namelen + 1));
555 + memcpy(mod->filename, filename, namelen);
556 + mod->filename[namelen] = '\0';
557 + mod->modname = NOFAIL(malloc(namelen + 1));
558 + filename2modname(mod->modname, mod->filename);
561 + list_add_tail(&mod->list, list);
564 +/* Compare len chars of a to b, with _ and - equivalent. */
565 +static int modname_equal(const char *a, const char *b, unsigned int len)
569 + if (strlen(b) != len)
572 + for (i = 0; i < len; i++) {
573 + if ((a[i] == '_' || a[i] == '-')
574 + && (b[i] == '_' || b[i] == '-'))
582 +/* Fills in list of modules if this is the line we want. */
583 +static int add_modules_dep_line(char *line,
585 + struct list_head *list)
591 + /* Ignore lines without : or which start with a # */
592 + ptr = strchr(line, ':');
593 + if (ptr == NULL || line[strspn(line, "\t ")] == '#')
596 + /* Is this the module we are looking for? */
598 + if (strrchr(line, '/'))
599 + modname = strrchr(line, '/') + 1;
603 + len = strlen(modname);
604 + if (strchr(modname, '.'))
605 + len = strchr(modname, '.') - modname;
606 + if (!modname_equal(modname, name, len))
609 + /* Create the list. */
610 + add_module(line, ptr - line, list);
615 + ptr += strspn(ptr, " \t");
619 + ptr += strcspn(ptr, " \t");
620 + add_module(dep_start, ptr - dep_start, list);
625 +static void read_depends(const char *dirname,
626 + const char *start_name,
627 + struct list_head *list)
629 + char *modules_dep_name;
634 + asprintf(&modules_dep_name, "%s/%s", dirname, "modules.dep");
635 + modules_dep = fopen(modules_dep_name, "r");
637 + fatal("Could not load %s: %s\n",
638 + modules_dep_name, strerror(errno));
640 + /* Stop at first line, as we can have duplicates (eg. symlinks
642 + while (!done && (line = getline_wrapped(modules_dep, NULL)) != NULL) {
643 + done = add_modules_dep_line(line, start_name, list);
646 + fclose(modules_dep);
647 + free(modules_dep_name);
650 +/* We use error numbers in a loose translation... */
651 +static const char *insert_moderror(int err)
655 + return "Invalid module format";
657 + return "Unknown symbol in module, or unknown parameter (see dmesg)";
659 + return "Kernel does not have module support";
661 + return strerror(err);
665 +static const char *remove_moderror(int err)
669 + return "No such module";
671 + return "Kernel does not have module unloading support";
673 + return strerror(err);
677 +/* Is module in /proc/modules? If so, fill in usecount if not NULL.
678 + 0 means no, 1 means yes, -1 means unknown.
680 +static int module_in_kernel(const char *modname, unsigned int *usecount)
682 + FILE *proc_modules;
686 + /* Might not be mounted yet. Don't fail. */
687 + proc_modules = fopen("/proc/modules", "r");
691 + while ((line = getline_wrapped(proc_modules, NULL)) != NULL) {
692 + char *entry = strtok(line, " \n");
694 + if (entry && streq(entry, modname)) {
695 + /* If it exists, usecount is the third entry. */
696 + if (!strtok(NULL, " \n"))
699 + if (!(entry = strtok(NULL, " \n"))) /* usecount */
703 + *usecount = atoi(entry);
705 + /* Followed by - then status. */
706 + if (strtok(NULL, " \n")
707 + && (entry = strtok(NULL, " \n")) != NULL) {
708 + /* Locking will fail on ro fs, we might hit
709 + * cases where module is in flux. Spin. */
710 + if (streq(entry, "Loading")
711 + || streq(entry, "Unloading")) {
714 + fclose(proc_modules);
721 + fclose(proc_modules);
726 + fclose(proc_modules);
730 +static void replace_modname(struct module *module,
731 + void *mem, unsigned long len,
732 + const char *oldname, const char *newname)
736 + /* 64 - sizeof(unsigned long) - 1 */
737 + if (strlen(newname) > 55)
738 + fatal("New name %s is too long\n", newname);
740 + /* Find where it is in the module structure. Don't assume layout! */
741 + for (p = mem; p < (char *)mem + len - strlen(oldname); p++) {
742 + if (memcmp(p, oldname, strlen(oldname)) == 0) {
743 + strcpy(p, newname);
748 + warn("Could not find old name in %s to replace!\n", module->filename);
751 +static void *get_section32(void *file,
752 + unsigned long size,
754 + unsigned long *secsize)
756 + Elf32_Ehdr *hdr = file;
757 + Elf32_Shdr *sechdrs = file + hdr->e_shoff;
758 + const char *secnames;
762 + if (size < sizeof(*hdr))
764 + if (size < hdr->e_shoff + hdr->e_shnum * sizeof(sechdrs[0]))
766 + if (size < sechdrs[hdr->e_shstrndx].sh_offset)
769 + secnames = file + sechdrs[hdr->e_shstrndx].sh_offset;
770 + for (i = 1; i < hdr->e_shnum; i++)
771 + if (strcmp(secnames + sechdrs[i].sh_name, name) == 0) {
772 + *secsize = sechdrs[i].sh_size;
773 + return file + sechdrs[i].sh_offset;
778 +static void *get_section64(void *file,
779 + unsigned long size,
781 + unsigned long *secsize)
783 + Elf64_Ehdr *hdr = file;
784 + Elf64_Shdr *sechdrs = file + hdr->e_shoff;
785 + const char *secnames;
789 + if (size < sizeof(*hdr))
791 + if (size < hdr->e_shoff + hdr->e_shnum * sizeof(sechdrs[0]))
793 + if (size < sechdrs[hdr->e_shstrndx].sh_offset)
796 + secnames = file + sechdrs[hdr->e_shstrndx].sh_offset;
797 + for (i = 1; i < hdr->e_shnum; i++)
798 + if (strcmp(secnames + sechdrs[i].sh_name, name) == 0) {
799 + *secsize = sechdrs[i].sh_size;
800 + return file + sechdrs[i].sh_offset;
805 +static int elf_ident(void *mod, unsigned long size)
807 + /* "\177ELF" <byte> where byte = 001 for 32-bit, 002 for 64 */
810 + if (size < EI_CLASS || memcmp(mod, ELFMAG, SELFMAG) != 0)
811 + return ELFCLASSNONE;
812 + return ident[EI_CLASS];
815 +static void *get_section(void *file,
816 + unsigned long size,
818 + unsigned long *secsize)
820 + switch (elf_ident(file, size)) {
822 + return get_section32(file, size, name, secsize);
824 + return get_section64(file, size, name, secsize);
830 +static void rename_module(struct module *module,
833 + const char *newname)
836 + unsigned long modstruct_len;
839 + modstruct = get_section(mod, len, ".gnu.linkonce.this_module",
843 + modstruct = get_section(mod, len, "__module", &modstruct_len);
845 + warn("Could not find module name to change in %s\n",
848 + replace_modname(module, modstruct, modstruct_len,
849 + module->modname, newname);
852 +/* Kernel told to ignore these sections if SHF_ALLOC not set. */
853 +static void invalidate_section32(void *mod, const char *secname)
855 + Elf32_Ehdr *hdr = mod;
856 + Elf32_Shdr *sechdrs = mod + hdr->e_shoff;
857 + const char *secnames = mod + sechdrs[hdr->e_shstrndx].sh_offset;
860 + for (i = 1; i < hdr->e_shnum; i++)
861 + if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0)
862 + sechdrs[i].sh_flags &= ~SHF_ALLOC;
865 +static void invalidate_section64(void *mod, const char *secname)
867 + Elf64_Ehdr *hdr = mod;
868 + Elf64_Shdr *sechdrs = mod + hdr->e_shoff;
869 + const char *secnames = mod + sechdrs[hdr->e_shstrndx].sh_offset;
872 + for (i = 1; i < hdr->e_shnum; i++)
873 + if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0)
874 + sechdrs[i].sh_flags &= ~(unsigned long long)SHF_ALLOC;
877 +static void strip_section(struct module *module,
880 + const char *secname)
882 + switch (elf_ident(mod, len)) {
884 + invalidate_section32(mod, secname);
887 + invalidate_section64(mod, secname);
890 + warn("Unknown module format in %s: not forcing version\n",
895 +static const char *next_string(const char *string, unsigned long *secsize)
897 + /* Skip non-zero chars */
898 + while (string[0]) {
900 + if ((*secsize)-- <= 1)
904 + /* Skip any zero padding. */
905 + while (!string[0]) {
907 + if ((*secsize)-- <= 1)
913 +static void clear_magic(struct module *module, void *mod, unsigned long len)
916 + unsigned long modlen;
918 + /* Old-style: __vermagic section */
919 + strip_section(module, mod, len, "__vermagic");
921 + /* New-style: in .modinfo section */
922 + for (p = get_section(mod, len, ".modinfo", &modlen);
924 + p = next_string(p, &modlen)) {
925 + if (strncmp(p, "vermagic=", strlen("vermagic=")) == 0) {
926 + memset((char *)p, 0, strlen(p));
932 +struct module_options
934 + struct module_options *next;
939 +struct module_command
941 + struct module_command *next;
948 + struct module_alias *next;
952 +struct module_blacklist
954 + struct module_blacklist *next;
958 +/* Link in a new option line from the config file. */
959 +static struct module_options *
960 +add_options(const char *modname,
961 + const char *option,
962 + struct module_options *options)
964 + struct module_options *new;
967 + new = NOFAIL(malloc(sizeof(*new)));
968 + new->modulename = NOFAIL(strdup(modname));
969 + new->options = NOFAIL(strdup(option));
970 + /* We can handle tabs, kernel can't. */
971 + for (tab = strchr(new->options, '\t'); tab; tab = strchr(tab, '\t'))
973 + new->next = options;
977 +/* Link in a new install line from the config file. */
978 +static struct module_command *
979 +add_command(const char *modname,
980 + const char *command,
981 + struct module_command *commands)
983 + struct module_command *new;
985 + new = NOFAIL(malloc(sizeof(*new)));
986 + new->modulename = NOFAIL(strdup(modname));
987 + new->command = NOFAIL(strdup(command));
988 + new->next = commands;
992 +/* Link in a new alias line from the config file. */
993 +static struct module_alias *
994 +add_alias(const char *modname, struct module_alias *aliases)
996 + struct module_alias *new;
998 + new = NOFAIL(malloc(sizeof(*new)));
999 + new->module = NOFAIL(strdup(modname));
1000 + new->next = aliases;
1004 +/* Link in a new blacklist line from the config file. */
1005 +static struct module_blacklist *
1006 +add_blacklist(const char *modname, struct module_blacklist *blacklist)
1008 + struct module_blacklist *new;
1010 + new = NOFAIL(malloc(sizeof(*new)));
1011 + new->modulename = NOFAIL(strdup(modname));
1012 + new->next = blacklist;
1016 +/* Find blacklist commands if any. */
1018 +find_blacklist(const char *modname, const struct module_blacklist *blacklist)
1020 + while (blacklist) {
1021 + if (strcmp(blacklist->modulename, modname) == 0)
1023 + blacklist = blacklist->next;
1028 +/* return a new alias list, with backlisted elems filtered out */
1029 +static struct module_alias *
1030 +apply_blacklist(const struct module_alias *aliases,
1031 + const struct module_blacklist *blacklist)
1033 + struct module_alias *result = NULL;
1035 + char *modname = aliases->module;
1036 + if (!find_blacklist(modname, blacklist))
1037 + result = add_alias(modname, result);
1038 + aliases = aliases->next;
1043 +/* Find install commands if any. */
1044 +static const char *find_command(const char *modname,
1045 + const struct module_command *commands)
1047 + while (commands) {
1048 + if (fnmatch(commands->modulename, modname, 0) == 0)
1049 + return commands->command;
1050 + commands = commands->next;
1055 +static char *append_option(char *options, const char *newoption)
1057 + options = NOFAIL(realloc(options, strlen(options) + 1
1058 + + strlen(newoption) + 1));
1059 + if (strlen(options)) strcat(options, " ");
1060 + strcat(options, newoption);
1064 +/* Add to options */
1065 +static char *add_extra_options(const char *modname,
1067 + const struct module_options *options)
1070 + if (strcmp(options->modulename, modname) == 0)
1071 + optstring = append_option(optstring, options->options);
1072 + options = options->next;
1077 +/* If we don't flush, then child processes print before we do */
1078 +static void verbose_printf(int verbose, const char *fmt, ...)
1083 + va_start(arglist, fmt);
1084 + vprintf(fmt, arglist);
1090 +/* Do an install/remove command: replace $CMDLINE_OPTS if it's specified. */
1091 +static void do_command(const char *modname,
1092 + const char *command,
1093 + int verbose, int dry_run,
1096 + const char *cmdline_opts)
1099 + char *p, *replaced_cmd = NOFAIL(strdup(command));
1101 + while ((p = strstr(replaced_cmd, "$CMDLINE_OPTS")) != NULL) {
1103 + asprintf(&new, "%.*s%s%s",
1104 + p - replaced_cmd, replaced_cmd, cmdline_opts,
1105 + p + strlen("$CMDLINE_OPTS"));
1107 + free(replaced_cmd);
1108 + replaced_cmd = new;
1111 + verbose_printf(verbose, "%s %s\n", type, replaced_cmd);
1115 + setenv("MODPROBE_MODULE", modname, 1);
1116 + ret = system(replaced_cmd);
1117 + if (ret == -1 || WEXITSTATUS(ret))
1118 + error("Error running %s command for %s\n", type, modname);
1119 + free(replaced_cmd);
1122 +/* Actually do the insert. Frees second arg. */
1123 +static void insmod(struct list_head *list,
1125 + const char *newname,
1130 + const struct module_options *options,
1131 + const struct module_command *commands,
1132 + int ignore_commands,
1134 + int strip_vermagic,
1135 + int strip_modversion,
1136 + const char *cmdline_opts)
1139 + unsigned long len;
1141 + const char *command;
1142 + struct module *mod = list_entry(list->next, struct module, list);
1144 + /* Take us off the list. */
1145 + list_del(&mod->list);
1147 + /* Do things we (or parent) depend on first, but don't die if
1149 + if (!list_empty(list)) {
1150 + insmod(list, NOFAIL(strdup("")), NULL, 0, warn,
1151 + dry_run, verbose, options, commands, 0, ignore_proc,
1152 + strip_vermagic, strip_modversion, cmdline_opts);
1155 + /* Lock before we look, in case it's initializing. */
1156 + fd = lock_file(mod->filename);
1158 + error("Could not open '%s': %s\n",
1159 + mod->filename, strerror(errno));
1160 + goto out_optstring;
1163 + /* Don't do ANYTHING if already in kernel. */
1165 + && module_in_kernel(newname ?: mod->modname, NULL) == 1) {
1167 + error("Module %s already in kernel.\n",
1168 + newname ?: mod->modname);
1172 + command = find_command(mod->modname, commands);
1173 + if (command && !ignore_commands) {
1174 + /* It might recurse: unlock. */
1176 + do_command(mod->modname, command, verbose, dry_run, error,
1177 + "install", cmdline_opts);
1178 + goto out_optstring;
1181 + map = grab_fd(fd, &len);
1183 + error("Could not read '%s': %s\n",
1184 + mod->filename, strerror(errno));
1190 + rename_module(mod, map, len, newname);
1192 + if (strip_modversion)
1193 + strip_section(mod, map, len, "__versions");
1194 + if (strip_vermagic)
1195 + clear_magic(mod, map, len);
1197 + /* Config file might have given more options */
1198 + optstring = add_extra_options(mod->modname, optstring, options);
1200 + verbose_printf(verbose, "insmod %s %s\n", mod->filename, optstring);
1205 + ret = init_module(map, len, optstring);
1207 + if (errno == EEXIST) {
1209 + error("Module %s already in kernel.\n",
1210 + newname ?: mod->modname);
1213 + error("Error inserting %s (%s): %s\n",
1214 + mod->modname, mod->filename, insert_moderror(errno));
1217 + release_file(map, len);
1225 +/* Do recursive removal. */
1226 +static void rmmod(struct list_head *list,
1232 + struct module_command *commands,
1233 + int ignore_commands,
1235 + const char *cmdline_opts)
1237 + const char *command;
1238 + unsigned int usecount = 0;
1240 + struct module *mod = list_entry(list->next, struct module, list);
1242 + /* Take first one off the list. */
1243 + list_del(&mod->list);
1245 + /* Ignore failure; it's best effort here. */
1246 + lock = lock_file(mod->filename);
1249 + name = mod->modname;
1251 + /* Even if renamed, find commands to orig. name. */
1252 + command = find_command(mod->modname, commands);
1253 + if (command && !ignore_commands) {
1254 + /* It might recurse: unlock. */
1255 + unlock_file(lock);
1256 + do_command(mod->modname, command, verbose, dry_run, error,
1257 + "remove", cmdline_opts);
1258 + goto remove_rest_no_unlock;
1261 + if (module_in_kernel(name, &usecount) == 0)
1262 + goto nonexistent_module;
1264 + if (usecount != 0) {
1265 + if (!ignore_inuse)
1266 + error("Module %s is in use.\n", name);
1270 + verbose_printf(verbose, "rmmod %s\n", mod->filename);
1275 + if (delete_module(name, O_EXCL) != 0) {
1276 + if (errno == ENOENT)
1277 + goto nonexistent_module;
1278 + error("Error removing %s (%s): %s\n",
1279 + name, mod->filename,
1280 + remove_moderror(errno));
1284 + unlock_file(lock);
1285 + remove_rest_no_unlock:
1286 + /* Now do things we depend. */
1287 + if (!list_empty(list))
1288 + rmmod(list, NULL, 0, warn, dry_run, verbose, commands,
1289 + 0, 1, cmdline_opts);
1292 +nonexistent_module:
1294 + fatal("Module %s is not in kernel.\n", mod->modname);
1298 +/* Does path contain directory(s) subpath? */
1299 +static int type_matches(const char *path, const char *subpath)
1301 + char *subpath_with_slashes;
1304 + asprintf(&subpath_with_slashes, "/%s/", subpath);
1305 + NOFAIL(subpath_with_slashes);
1307 + ret = (strstr(path, subpath_with_slashes) != NULL);
1308 + free(subpath_with_slashes);
1312 +static char *underscores(char *string)
1316 + for (i = 0; string[i]; i++)
1317 + if (string[i] == '-')
1323 +static int do_wildcard(const char *dirname,
1325 + const char *wildcard)
1327 + char modules_dep_name[strlen(dirname) + sizeof("modules.dep") + 1];
1328 + char *line, *wcard;
1329 + FILE *modules_dep;
1331 + /* Canonicalize wildcard */
1332 + wcard = strdup(wildcard);
1333 + underscores(wcard);
1335 + sprintf(modules_dep_name, "%s/%s", dirname, "modules.dep");
1336 + modules_dep = fopen(modules_dep_name, "r");
1338 + fatal("Could not load %s: %s\n",
1339 + modules_dep_name, strerror(errno));
1341 + while ((line = getline_wrapped(modules_dep, NULL)) != NULL) {
1344 + /* Ignore lines without : or which start with a # */
1345 + ptr = strchr(line, ':');
1346 + if (ptr == NULL || line[strspn(line, "\t ")] == '#')
1350 + /* "type" must match complete directory component(s). */
1351 + if (!type || type_matches(line, type)) {
1352 + char modname[strlen(line)+1];
1354 + filename2modname(modname, line);
1355 + if (fnmatch(wcard, modname, 0) == 0)
1356 + printf("%s\n", line);
1366 +static char *strsep_skipspace(char **string, char *delim)
1370 + *string += strspn(*string, delim);
1371 + return strsep(string, delim);
1375 +static int read_config(const char *filename,
1379 + struct module_options **options,
1380 + struct module_command **commands,
1381 + struct module_alias **alias,
1382 + struct module_blacklist **blacklist);
1384 +/* FIXME: Maybe should be extended to "alias a b [and|or c]...". --RR */
1385 +static int read_config_file(const char *filename,
1389 + struct module_options **options,
1390 + struct module_command **commands,
1391 + struct module_alias **aliases,
1392 + struct module_blacklist **blacklist)
1395 + unsigned int linenum = 0;
1398 + cfile = fopen(filename, "r");
1402 + while ((line = getline_wrapped(cfile, &linenum)) != NULL) {
1404 + char *cmd, *modname;
1407 + printf("%s\n", line);
1409 + cmd = strsep_skipspace(&ptr, "\t ");
1410 + if (cmd == NULL || cmd[0] == '#' || cmd[0] == '\0')
1413 + if (strcmp(cmd, "alias") == 0) {
1415 + = underscores(strsep_skipspace(&ptr, "\t "));
1417 + = underscores(strsep_skipspace(&ptr, "\t "));
1419 + if (!wildcard || !realname)
1420 + grammar(cmd, filename, linenum);
1421 + else if (fnmatch(wildcard,name,0) == 0)
1422 + *aliases = add_alias(realname, *aliases);
1423 + } else if (strcmp(cmd, "include") == 0) {
1424 + struct module_alias *newalias = NULL;
1425 + char *newfilename;
1427 + newfilename = strsep_skipspace(&ptr, "\t ");
1429 + grammar(cmd, filename, linenum);
1431 + if (!read_config(newfilename, name,
1432 + dump_only, removing,
1433 + options, commands, &newalias,
1435 + warn("Failed to open included"
1436 + " config file %s: %s\n",
1437 + newfilename, strerror(errno));
1439 + /* Files included override aliases,
1440 + etc that was already set ... */
1442 + *aliases = newalias;
1444 + } else if (strcmp(cmd, "options") == 0) {
1445 + modname = strsep_skipspace(&ptr, "\t ");
1446 + if (!modname || !ptr)
1447 + grammar(cmd, filename, linenum);
1449 + ptr += strspn(ptr, "\t ");
1450 + *options = add_options(underscores(modname),
1453 + } else if (strcmp(cmd, "install") == 0) {
1454 + modname = strsep_skipspace(&ptr, "\t ");
1455 + if (!modname || !ptr)
1456 + grammar(cmd, filename, linenum);
1457 + else if (!removing) {
1458 + ptr += strspn(ptr, "\t ");
1459 + *commands = add_command(underscores(modname),
1462 + } else if (strcmp(cmd, "blacklist") == 0) {
1463 + modname = strsep_skipspace(&ptr, "\t ");
1465 + grammar(cmd, filename, linenum);
1466 + else if (!removing) {
1467 + *blacklist = add_blacklist(underscores(modname),
1470 + } else if (strcmp(cmd, "remove") == 0) {
1471 + modname = strsep_skipspace(&ptr, "\t ");
1472 + if (!modname || !ptr)
1473 + grammar(cmd, filename, linenum);
1474 + else if (removing) {
1475 + ptr += strspn(ptr, "\t ");
1476 + *commands = add_command(underscores(modname),
1480 + grammar(cmd, filename, linenum);
1488 +/* Simple format, ignore lines starting with #, one command per line.
1489 + Returns true or false. */
1490 +static int read_config(const char *filename,
1494 + struct module_options **options,
1495 + struct module_command **commands,
1496 + struct module_alias **aliases,
1497 + struct module_blacklist **blacklist)
1502 + /* ignore everything in this directory */
1503 + if (streq(filename, "/etc/modprobe.d/arch"))
1506 + /* Reiser4 has file/directory duality: treat it as both. */
1507 + dir = opendir(filename);
1510 + while ((i = readdir(dir)) != NULL) {
1511 + if (!streq(i->d_name,".") && !streq(i->d_name,"..")) {
1512 + char sub[strlen(filename) + 1
1513 + + strlen(i->d_name) + 1];
1515 + sprintf(sub, "%s/%s", filename, i->d_name);
1516 + if (!read_config(sub, name,
1517 + dump_only, removing, options,
1518 + commands, aliases, blacklist))
1519 + warn("Failed to open"
1520 + " config file %s: %s\n",
1521 + sub, strerror(errno));
1528 + if (read_config_file(filename, name, dump_only, removing,
1529 + options, commands, aliases, blacklist))
1535 +static const char *default_configs[] =
1537 + "/etc/modprobe.conf",
1538 + "/etc/modprobe.d",
1541 +static void read_toplevel_config(const char *filename,
1545 + struct module_options **options,
1546 + struct module_command **commands,
1547 + struct module_alias **aliases,
1548 + struct module_blacklist **blacklist)
1553 + if (!read_config(filename, name, dump_only, removing,
1554 + options, commands, aliases, blacklist))
1555 + fatal("Failed to open config file %s: %s\n",
1556 + filename, strerror(errno));
1560 + /* Try defaults. */
1561 + for (i = 0; i < ARRAY_SIZE(default_configs); i++) {
1562 + if (read_config(default_configs[i], name, dump_only, removing,
1563 + options, commands, aliases, blacklist))
1568 +static void add_to_env_var(const char *option)
1570 + const char *oldenv;
1572 + if ((oldenv = getenv("MODPROBE_OPTIONS")) != NULL) {
1574 + asprintf(&newenv, "%s %s", oldenv, option);
1575 + setenv("MODPROBE_OPTIONS", newenv, 1);
1577 + setenv("MODPROBE_OPTIONS", option, 1);
1580 +/* Prepend options from environment. */
1581 +static char **merge_args(char *args, char *argv[], int *argc)
1583 + char *arg, *argstring;
1584 + char **newargs = NULL;
1585 + unsigned int i, num_env = 0;
1590 + argstring = NOFAIL(strdup(args));
1591 + for (arg = strtok(argstring, " "); arg; arg = strtok(NULL, " ")) {
1593 + newargs = NOFAIL(realloc(newargs,
1594 + sizeof(newargs[0])
1595 + * (num_env + *argc + 1)));
1596 + newargs[num_env] = arg;
1599 + /* Append commandline args */
1600 + newargs[0] = argv[0];
1601 + for (i = 1; i <= *argc; i++)
1602 + newargs[num_env+i] = argv[i];
1608 +static char *gather_options(char *argv[])
1610 + char *optstring = NOFAIL(strdup(""));
1612 + /* Rest is module options */
1614 + /* Quote value if it contains spaces. */
1615 + unsigned int eq = strcspn(*argv, "=");
1617 + if (strchr(*argv+eq, ' ') && !strchr(*argv, '"')) {
1618 + char quoted[strlen(*argv) + 3];
1619 + (*argv)[eq] = '\0';
1620 + sprintf(quoted, "%s=\"%s\"", *argv, *argv+eq+1);
1621 + optstring = append_option(optstring, quoted);
1623 + optstring = append_option(optstring, *argv);
1629 +static void handle_module(const char *modname,
1630 + struct list_head *todo_list,
1631 + const char *newname,
1638 + struct module_options *modoptions,
1639 + struct module_command *commands,
1640 + int ignore_commands,
1642 + int strip_vermagic,
1643 + int strip_modversion,
1644 + int unknown_silent,
1645 + const char *cmdline_opts)
1647 + if (list_empty(todo_list)) {
1648 + const char *command;
1650 + /* The dependencies have to be real modules, but
1651 + handle case where the first is completely bogus. */
1652 + command = find_command(modname, commands);
1653 + if (command && !ignore_commands) {
1654 + do_command(modname, command, verbose, dry_run, error,
1655 + remove ? "remove":"install", cmdline_opts);
1659 + if (unknown_silent)
1661 + error("Module %s not found.\n", modname);
1666 + rmmod(todo_list, newname, first_time, error, dry_run, verbose,
1667 + commands, ignore_commands, 0, cmdline_opts);
1669 + insmod(todo_list, NOFAIL(strdup(options)), newname,
1670 + first_time, error, dry_run, verbose, modoptions,
1671 + commands, ignore_commands, ignore_proc, strip_vermagic,
1672 + strip_modversion, cmdline_opts);
1675 +static struct option options[] = { { "verbose", 0, NULL, 'v' },
1676 + { "version", 0, NULL, 'V' },
1677 + { "config", 1, NULL, 'C' },
1678 + { "name", 1, NULL, 'o' },
1679 + { "remove", 0, NULL, 'r' },
1680 + { "showconfig", 0, NULL, 'c' },
1681 + { "autoclean", 0, NULL, 'k' },
1682 + { "quiet", 0, NULL, 'q' },
1683 + { "show", 0, NULL, 'n' },
1684 + { "dry-run", 0, NULL, 'n' },
1685 + { "syslog", 0, NULL, 's' },
1686 + { "type", 1, NULL, 't' },
1687 + { "list", 0, NULL, 'l' },
1688 + { "all", 0, NULL, 'a' },
1689 + { "ignore-install", 0, NULL, 'i' },
1690 + { "ignore-remove", 0, NULL, 'i' },
1691 + { "force", 0, NULL, 'f' },
1692 + { "force-vermagic", 0, NULL, 1 },
1693 + { "force-modversion", 0, NULL, 2 },
1694 + { "set-version", 1, NULL, 'S' },
1695 + { "show-depends", 0, NULL, 'D' },
1696 + { "first-time", 0, NULL, 3 },
1697 + { "use-blacklist", 0, NULL, 'b' },
1698 + { NULL, 0, NULL, 0 } };
1700 +#define MODPROBE_DEVFSD_CONF "/etc/modprobe.devfs"
1702 +/* This is a horrible hack to allow devfsd, which calls modprobe with
1703 + -C /etc/modules.conf or /etc/modules.devfs, to work. FIXME. */
1704 +/* Modern devfsd or variants should use -q explicitly in 2.6. */
1705 +static int is_devfs_call(char *argv[])
1709 + /* Look for "/dev" arg */
1710 + for (i = 1; argv[i]; i++) {
1711 + if (strncmp(argv[i], "/dev/", 5) == 0)
1717 +int main(int argc, char *argv[])
1719 + struct utsname buf;
1720 + struct stat statbuf;
1722 + int dump_only = 0;
1726 + int unknown_silent = 0;
1727 + int list_only = 0;
1729 + int ignore_commands = 0;
1730 + int strip_vermagic = 0;
1731 + int strip_modversion = 0;
1732 + int ignore_proc = 0;
1733 + int first_time = 0;
1734 + int use_blacklist = 0;
1735 + unsigned int i, num_modules;
1736 + char *type = NULL;
1737 + const char *config = NULL;
1738 + char *dirname, *optstring;
1739 + char *newname = NULL;
1740 + char *aliasfilename, *symfilename;
1741 + errfn_t error = fatal;
1743 + /* Prepend options from environment. */
1744 + argv = merge_args(getenv("MODPROBE_OPTIONS"), argv, &argc);
1746 + /* --set-version overrides version, and disables backwards compat. */
1747 + for (opt = 1; opt < argc; opt++)
1748 + if (strncmp(argv[opt],"--set-version",strlen("--set-version"))
1753 + try_old_version("modprobe", argv);
1756 + while ((opt = getopt_long(argc, argv, "vVC:o:rknqQsclt:aifb", options, NULL)) != -1){
1759 + add_to_env_var("-v");
1763 + puts("module-init-tools version 3.2.2");
1766 + strncpy(buf.release, optarg, sizeof(buf.release));
1767 + buf.release[sizeof(buf.release)-1] = '\0';
1770 + if (is_devfs_call(argv)) {
1771 + if (streq("/etc/modules.devfs", optarg)) {
1772 + config = MODPROBE_DEVFSD_CONF;
1773 + add_to_env_var("-C");
1774 + add_to_env_var(config);
1775 + /* Fall thru to -q */
1776 + } else if (streq("/etc/modules.conf", optarg))
1777 + /* Ignore config, fall thru to -q */
1780 + /* False alarm. Treat as normal. */
1782 + add_to_env_var("-C");
1783 + add_to_env_var(config);
1788 + add_to_env_var("-C");
1789 + add_to_env_var(config);
1793 + unknown_silent = 1;
1794 + add_to_env_var("-q");
1800 + add_to_env_var("-D");
1822 + /* FIXME: This should actually do something */
1828 + add_to_env_var("-s");
1832 + ignore_commands = 1;
1835 + strip_vermagic = 1;
1836 + strip_modversion = 1;
1839 + use_blacklist = 1;
1842 + strip_vermagic = 1;
1845 + strip_modversion = 1;
1851 + print_usage(argv[0]);
1855 + /* If stderr not open, go to syslog */
1856 + if (log || fstat(STDERR_FILENO, &statbuf) != 0) {
1857 + openlog("modprobe", LOG_CONS, LOG_DAEMON);
1861 + if (argc < optind + 1 && !dump_only && !list_only && !remove)
1862 + print_usage(argv[0]);
1864 + dirname = NOFAIL(malloc(strlen(buf.release) + sizeof(MODULE_DIR) + 1));
1865 + sprintf(dirname, "%s/%s", MODULE_DIR, buf.release);
1866 + aliasfilename = NOFAIL(malloc(strlen(dirname)
1867 + + sizeof("/modules.alias")));
1868 + sprintf(aliasfilename, "%s/modules.alias", dirname);
1869 + symfilename = NOFAIL(malloc(strlen(dirname)
1870 + + sizeof("/modules.symbols")));
1871 + sprintf(symfilename, "%s/modules.symbols", dirname);
1873 + /* Old-style -t xxx wildcard? Only with -l. */
1875 + if (optind+1 < argc)
1876 + fatal("Can't have multiple wildcards\n");
1877 + /* fprintf(stderr, "man find\n"); return 1; */
1878 + return do_wildcard(dirname, type, argv[optind]?:"*");
1881 + fatal("-t only supported with -l");
1884 + struct module_command *commands = NULL;
1885 + struct module_options *modoptions = NULL;
1886 + struct module_alias *aliases = NULL;
1887 + struct module_blacklist *blacklist = NULL;
1889 + read_toplevel_config(config, "", 1, 0,
1890 + &modoptions, &commands, &aliases, &blacklist);
1891 + read_config(aliasfilename, "", 1, 0,&modoptions, &commands,
1892 + &aliases, &blacklist);
1893 + read_config(symfilename, "", 1, 0, &modoptions, &commands,
1894 + &aliases, &blacklist);
1898 + if (remove || all) {
1899 + num_modules = argc - optind;
1900 + optstring = NOFAIL(strdup(""));
1903 + optstring = gather_options(argv+optind+1);
1906 + /* num_modules is always 1 except for -r or -a. */
1907 + for (i = 0; i < num_modules; i++) {
1908 + struct module_command *commands = NULL;
1909 + struct module_options *modoptions = NULL;
1910 + struct module_alias *aliases = NULL;
1911 + struct module_blacklist *blacklist = NULL;
1913 + char *modulearg = argv[optind + i];
1915 + /* Convert name we are looking for */
1916 + underscores(modulearg);
1918 + /* Returns the resolved alias, options */
1919 + read_toplevel_config(config, modulearg, 0,
1920 + remove, &modoptions, &commands, &aliases, &blacklist);
1922 + /* No luck? Try symbol names, if starts with symbol:. */
1924 + && strncmp(modulearg, "symbol:", strlen("symbol:")) == 0)
1925 + read_config(symfilename, modulearg, 0,
1926 + remove, &modoptions, &commands,
1927 + &aliases, &blacklist);
1930 + /* We only use canned aliases as last resort. */
1931 + read_depends(dirname, modulearg, &list);
1933 + if (list_empty(&list)
1934 + && !find_command(modulearg, commands))
1936 + read_config(aliasfilename, modulearg, 0,
1937 + remove, &modoptions, &commands,
1938 + &aliases, &blacklist);
1939 + aliases = apply_blacklist(aliases, blacklist);
1944 + errfn_t err = error;
1946 + /* More than one alias? Don't bail out on failure. */
1947 + if (aliases->next)
1950 + /* Add the options for this alias. */
1951 + char *opts = NOFAIL(strdup(optstring));
1952 + opts = add_extra_options(modulearg,
1953 + opts, modoptions);
1955 + read_depends(dirname, aliases->module, &list);
1956 + handle_module(aliases->module, &list, newname,
1957 + remove, opts, first_time, err,
1958 + dry_run, verbose, modoptions,
1959 + commands, ignore_commands,
1960 + ignore_proc, strip_vermagic,
1965 + aliases = aliases->next;
1966 + INIT_LIST_HEAD(&list);
1970 + && find_blacklist(modulearg, blacklist))
1973 + handle_module(modulearg, &list, newname, remove,
1974 + optstring, first_time, error, dry_run,
1975 + verbose, modoptions, commands,
1976 + ignore_commands, ignore_proc,
1977 + strip_vermagic, strip_modversion,
1978 + unknown_silent, optstring);