diff options
| -rw-r--r-- | include/asm-generic/vmlinux.lds.h | 1 | ||||
| -rw-r--r-- | include/linux/export.h | 4 | ||||
| -rw-r--r-- | include/linux/module.h | 3 | ||||
| -rw-r--r-- | init/main.c | 7 | ||||
| -rw-r--r-- | kernel/module.c | 66 | ||||
| -rw-r--r-- | scripts/Makefile.modpost | 4 | ||||
| -rw-r--r-- | scripts/mod/modpost.c | 22 |
7 files changed, 55 insertions, 52 deletions
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 83e2c31e8b00..bc2121fa9132 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
| @@ -473,6 +473,7 @@ | |||
| 473 | #define KERNEL_CTORS() . = ALIGN(8); \ | 473 | #define KERNEL_CTORS() . = ALIGN(8); \ |
| 474 | VMLINUX_SYMBOL(__ctors_start) = .; \ | 474 | VMLINUX_SYMBOL(__ctors_start) = .; \ |
| 475 | *(.ctors) \ | 475 | *(.ctors) \ |
| 476 | *(.init_array) \ | ||
| 476 | VMLINUX_SYMBOL(__ctors_end) = .; | 477 | VMLINUX_SYMBOL(__ctors_end) = .; |
| 477 | #else | 478 | #else |
| 478 | #define KERNEL_CTORS() | 479 | #define KERNEL_CTORS() |
diff --git a/include/linux/export.h b/include/linux/export.h index 412cd509effe..3f2793d51899 100644 --- a/include/linux/export.h +++ b/include/linux/export.h | |||
| @@ -43,7 +43,7 @@ extern struct module __this_module; | |||
| 43 | /* Mark the CRC weak since genksyms apparently decides not to | 43 | /* Mark the CRC weak since genksyms apparently decides not to |
| 44 | * generate a checksums for some symbols */ | 44 | * generate a checksums for some symbols */ |
| 45 | #define __CRC_SYMBOL(sym, sec) \ | 45 | #define __CRC_SYMBOL(sym, sec) \ |
| 46 | extern void *__crc_##sym __attribute__((weak)); \ | 46 | extern __visible void *__crc_##sym __attribute__((weak)); \ |
| 47 | static const unsigned long __kcrctab_##sym \ | 47 | static const unsigned long __kcrctab_##sym \ |
| 48 | __used \ | 48 | __used \ |
| 49 | __attribute__((section("___kcrctab" sec "+" #sym), unused)) \ | 49 | __attribute__((section("___kcrctab" sec "+" #sym), unused)) \ |
| @@ -59,7 +59,7 @@ extern struct module __this_module; | |||
| 59 | static const char __kstrtab_##sym[] \ | 59 | static const char __kstrtab_##sym[] \ |
| 60 | __attribute__((section("__ksymtab_strings"), aligned(1))) \ | 60 | __attribute__((section("__ksymtab_strings"), aligned(1))) \ |
| 61 | = VMLINUX_SYMBOL_STR(sym); \ | 61 | = VMLINUX_SYMBOL_STR(sym); \ |
| 62 | static const struct kernel_symbol __ksymtab_##sym \ | 62 | __visible const struct kernel_symbol __ksymtab_##sym \ |
| 63 | __used \ | 63 | __used \ |
| 64 | __attribute__((section("___ksymtab" sec "+" #sym), unused)) \ | 64 | __attribute__((section("___ksymtab" sec "+" #sym), unused)) \ |
| 65 | = { (unsigned long)&sym, __kstrtab_##sym } | 65 | = { (unsigned long)&sym, __kstrtab_##sym } |
diff --git a/include/linux/module.h b/include/linux/module.h index 05f2447f8c15..15cd6b1b211e 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
| @@ -367,9 +367,6 @@ struct module | |||
| 367 | /* What modules do I depend on? */ | 367 | /* What modules do I depend on? */ |
| 368 | struct list_head target_list; | 368 | struct list_head target_list; |
| 369 | 369 | ||
| 370 | /* Who is waiting for us to be unloaded */ | ||
| 371 | struct task_struct *waiter; | ||
| 372 | |||
| 373 | /* Destruction function. */ | 370 | /* Destruction function. */ |
| 374 | void (*exit)(void); | 371 | void (*exit)(void); |
| 375 | 372 | ||
diff --git a/init/main.c b/init/main.c index 5f191133376f..01573fdfa186 100644 --- a/init/main.c +++ b/init/main.c | |||
| @@ -131,6 +131,8 @@ char __initdata boot_command_line[COMMAND_LINE_SIZE]; | |||
| 131 | char *saved_command_line; | 131 | char *saved_command_line; |
| 132 | /* Command line for parameter parsing */ | 132 | /* Command line for parameter parsing */ |
| 133 | static char *static_command_line; | 133 | static char *static_command_line; |
| 134 | /* Command line for per-initcall parameter parsing */ | ||
| 135 | static char *initcall_command_line; | ||
| 134 | 136 | ||
| 135 | static char *execute_command; | 137 | static char *execute_command; |
| 136 | static char *ramdisk_execute_command; | 138 | static char *ramdisk_execute_command; |
| @@ -354,6 +356,7 @@ static inline void smp_prepare_cpus(unsigned int maxcpus) { } | |||
| 354 | static void __init setup_command_line(char *command_line) | 356 | static void __init setup_command_line(char *command_line) |
| 355 | { | 357 | { |
| 356 | saved_command_line = alloc_bootmem(strlen (boot_command_line)+1); | 358 | saved_command_line = alloc_bootmem(strlen (boot_command_line)+1); |
| 359 | initcall_command_line = alloc_bootmem(strlen (boot_command_line)+1); | ||
| 357 | static_command_line = alloc_bootmem(strlen (command_line)+1); | 360 | static_command_line = alloc_bootmem(strlen (command_line)+1); |
| 358 | strcpy (saved_command_line, boot_command_line); | 361 | strcpy (saved_command_line, boot_command_line); |
| 359 | strcpy (static_command_line, command_line); | 362 | strcpy (static_command_line, command_line); |
| @@ -751,9 +754,9 @@ static void __init do_initcall_level(int level) | |||
| 751 | extern const struct kernel_param __start___param[], __stop___param[]; | 754 | extern const struct kernel_param __start___param[], __stop___param[]; |
| 752 | initcall_t *fn; | 755 | initcall_t *fn; |
| 753 | 756 | ||
| 754 | strcpy(static_command_line, saved_command_line); | 757 | strcpy(initcall_command_line, saved_command_line); |
| 755 | parse_args(initcall_level_names[level], | 758 | parse_args(initcall_level_names[level], |
| 756 | static_command_line, __start___param, | 759 | initcall_command_line, __start___param, |
| 757 | __stop___param - __start___param, | 760 | __stop___param - __start___param, |
| 758 | level, level, | 761 | level, level, |
| 759 | &repair_env_string); | 762 | &repair_env_string); |
diff --git a/kernel/module.c b/kernel/module.c index af5ebd21d77b..f5a3b1e8ec51 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -641,8 +641,6 @@ static int module_unload_init(struct module *mod) | |||
| 641 | 641 | ||
| 642 | /* Hold reference count during initialization. */ | 642 | /* Hold reference count during initialization. */ |
| 643 | __this_cpu_write(mod->refptr->incs, 1); | 643 | __this_cpu_write(mod->refptr->incs, 1); |
| 644 | /* Backwards compatibility macros put refcount during init. */ | ||
| 645 | mod->waiter = current; | ||
| 646 | 644 | ||
| 647 | return 0; | 645 | return 0; |
| 648 | } | 646 | } |
| @@ -768,16 +766,9 @@ static int __try_stop_module(void *_sref) | |||
| 768 | 766 | ||
| 769 | static int try_stop_module(struct module *mod, int flags, int *forced) | 767 | static int try_stop_module(struct module *mod, int flags, int *forced) |
| 770 | { | 768 | { |
| 771 | if (flags & O_NONBLOCK) { | 769 | struct stopref sref = { mod, flags, forced }; |
| 772 | struct stopref sref = { mod, flags, forced }; | ||
| 773 | 770 | ||
| 774 | return stop_machine(__try_stop_module, &sref, NULL); | 771 | return stop_machine(__try_stop_module, &sref, NULL); |
| 775 | } else { | ||
| 776 | /* We don't need to stop the machine for this. */ | ||
| 777 | mod->state = MODULE_STATE_GOING; | ||
| 778 | synchronize_sched(); | ||
| 779 | return 0; | ||
| 780 | } | ||
| 781 | } | 772 | } |
| 782 | 773 | ||
| 783 | unsigned long module_refcount(struct module *mod) | 774 | unsigned long module_refcount(struct module *mod) |
| @@ -810,21 +801,6 @@ EXPORT_SYMBOL(module_refcount); | |||
| 810 | /* This exists whether we can unload or not */ | 801 | /* This exists whether we can unload or not */ |
| 811 | static void free_module(struct module *mod); | 802 | static void free_module(struct module *mod); |
| 812 | 803 | ||
| 813 | static void wait_for_zero_refcount(struct module *mod) | ||
| 814 | { | ||
| 815 | /* Since we might sleep for some time, release the mutex first */ | ||
| 816 | mutex_unlock(&module_mutex); | ||
| 817 | for (;;) { | ||
| 818 | pr_debug("Looking at refcount...\n"); | ||
| 819 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 820 | if (module_refcount(mod) == 0) | ||
| 821 | break; | ||
| 822 | schedule(); | ||
| 823 | } | ||
| 824 | current->state = TASK_RUNNING; | ||
| 825 | mutex_lock(&module_mutex); | ||
| 826 | } | ||
| 827 | |||
| 828 | SYSCALL_DEFINE2(delete_module, const char __user *, name_user, | 804 | SYSCALL_DEFINE2(delete_module, const char __user *, name_user, |
| 829 | unsigned int, flags) | 805 | unsigned int, flags) |
| 830 | { | 806 | { |
| @@ -839,6 +815,11 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, | |||
| 839 | return -EFAULT; | 815 | return -EFAULT; |
| 840 | name[MODULE_NAME_LEN-1] = '\0'; | 816 | name[MODULE_NAME_LEN-1] = '\0'; |
| 841 | 817 | ||
| 818 | if (!(flags & O_NONBLOCK)) { | ||
| 819 | printk(KERN_WARNING | ||
| 820 | "waiting module removal not supported: please upgrade"); | ||
| 821 | } | ||
| 822 | |||
| 842 | if (mutex_lock_interruptible(&module_mutex) != 0) | 823 | if (mutex_lock_interruptible(&module_mutex) != 0) |
| 843 | return -EINTR; | 824 | return -EINTR; |
| 844 | 825 | ||
| @@ -856,8 +837,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, | |||
| 856 | 837 | ||
| 857 | /* Doing init or already dying? */ | 838 | /* Doing init or already dying? */ |
| 858 | if (mod->state != MODULE_STATE_LIVE) { | 839 | if (mod->state != MODULE_STATE_LIVE) { |
| 859 | /* FIXME: if (force), slam module count and wake up | 840 | /* FIXME: if (force), slam module count damn the torpedoes */ |
| 860 | waiter --RR */ | ||
| 861 | pr_debug("%s already dying\n", mod->name); | 841 | pr_debug("%s already dying\n", mod->name); |
| 862 | ret = -EBUSY; | 842 | ret = -EBUSY; |
| 863 | goto out; | 843 | goto out; |
| @@ -873,18 +853,11 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, | |||
| 873 | } | 853 | } |
| 874 | } | 854 | } |
| 875 | 855 | ||
| 876 | /* Set this up before setting mod->state */ | ||
| 877 | mod->waiter = current; | ||
| 878 | |||
| 879 | /* Stop the machine so refcounts can't move and disable module. */ | 856 | /* Stop the machine so refcounts can't move and disable module. */ |
| 880 | ret = try_stop_module(mod, flags, &forced); | 857 | ret = try_stop_module(mod, flags, &forced); |
| 881 | if (ret != 0) | 858 | if (ret != 0) |
| 882 | goto out; | 859 | goto out; |
| 883 | 860 | ||
| 884 | /* Never wait if forced. */ | ||
| 885 | if (!forced && module_refcount(mod) != 0) | ||
| 886 | wait_for_zero_refcount(mod); | ||
| 887 | |||
| 888 | mutex_unlock(&module_mutex); | 861 | mutex_unlock(&module_mutex); |
| 889 | /* Final destruction now no one is using it. */ | 862 | /* Final destruction now no one is using it. */ |
| 890 | if (mod->exit != NULL) | 863 | if (mod->exit != NULL) |
| @@ -1002,9 +975,6 @@ void module_put(struct module *module) | |||
| 1002 | __this_cpu_inc(module->refptr->decs); | 975 | __this_cpu_inc(module->refptr->decs); |
| 1003 | 976 | ||
| 1004 | trace_module_put(module, _RET_IP_); | 977 | trace_module_put(module, _RET_IP_); |
| 1005 | /* Maybe they're waiting for us to drop reference? */ | ||
| 1006 | if (unlikely(!module_is_live(module))) | ||
| 1007 | wake_up_process(module->waiter); | ||
| 1008 | preempt_enable(); | 978 | preempt_enable(); |
| 1009 | } | 979 | } |
| 1010 | } | 980 | } |
| @@ -2728,7 +2698,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags) | |||
| 2728 | return 0; | 2698 | return 0; |
| 2729 | } | 2699 | } |
| 2730 | 2700 | ||
| 2731 | static void find_module_sections(struct module *mod, struct load_info *info) | 2701 | static int find_module_sections(struct module *mod, struct load_info *info) |
| 2732 | { | 2702 | { |
| 2733 | mod->kp = section_objs(info, "__param", | 2703 | mod->kp = section_objs(info, "__param", |
| 2734 | sizeof(*mod->kp), &mod->num_kp); | 2704 | sizeof(*mod->kp), &mod->num_kp); |
| @@ -2758,6 +2728,18 @@ static void find_module_sections(struct module *mod, struct load_info *info) | |||
| 2758 | #ifdef CONFIG_CONSTRUCTORS | 2728 | #ifdef CONFIG_CONSTRUCTORS |
| 2759 | mod->ctors = section_objs(info, ".ctors", | 2729 | mod->ctors = section_objs(info, ".ctors", |
| 2760 | sizeof(*mod->ctors), &mod->num_ctors); | 2730 | sizeof(*mod->ctors), &mod->num_ctors); |
| 2731 | if (!mod->ctors) | ||
| 2732 | mod->ctors = section_objs(info, ".init_array", | ||
| 2733 | sizeof(*mod->ctors), &mod->num_ctors); | ||
| 2734 | else if (find_sec(info, ".init_array")) { | ||
| 2735 | /* | ||
| 2736 | * This shouldn't happen with same compiler and binutils | ||
| 2737 | * building all parts of the module. | ||
| 2738 | */ | ||
| 2739 | printk(KERN_WARNING "%s: has both .ctors and .init_array.\n", | ||
| 2740 | mod->name); | ||
| 2741 | return -EINVAL; | ||
| 2742 | } | ||
| 2761 | #endif | 2743 | #endif |
| 2762 | 2744 | ||
| 2763 | #ifdef CONFIG_TRACEPOINTS | 2745 | #ifdef CONFIG_TRACEPOINTS |
| @@ -2795,6 +2777,8 @@ static void find_module_sections(struct module *mod, struct load_info *info) | |||
| 2795 | 2777 | ||
| 2796 | info->debug = section_objs(info, "__verbose", | 2778 | info->debug = section_objs(info, "__verbose", |
| 2797 | sizeof(*info->debug), &info->num_debug); | 2779 | sizeof(*info->debug), &info->num_debug); |
| 2780 | |||
| 2781 | return 0; | ||
| 2798 | } | 2782 | } |
| 2799 | 2783 | ||
| 2800 | static int move_module(struct module *mod, struct load_info *info) | 2784 | static int move_module(struct module *mod, struct load_info *info) |
| @@ -3248,7 +3232,9 @@ static int load_module(struct load_info *info, const char __user *uargs, | |||
| 3248 | 3232 | ||
| 3249 | /* Now we've got everything in the final locations, we can | 3233 | /* Now we've got everything in the final locations, we can |
| 3250 | * find optional sections. */ | 3234 | * find optional sections. */ |
| 3251 | find_module_sections(mod, info); | 3235 | err = find_module_sections(mod, info); |
| 3236 | if (err) | ||
| 3237 | goto free_unload; | ||
| 3252 | 3238 | ||
| 3253 | err = check_module_license_and_versions(mod); | 3239 | err = check_module_license_and_versions(mod); |
| 3254 | if (err) | 3240 | if (err) |
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 8dcdca27d836..69f0a1417e9a 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost | |||
| @@ -79,9 +79,11 @@ modpost = scripts/mod/modpost \ | |||
| 79 | $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \ | 79 | $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \ |
| 80 | $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) | 80 | $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) |
| 81 | 81 | ||
| 82 | MODPOST_OPT=$(subst -i,-n,$(filter -i,$(MAKEFLAGS))) | ||
| 83 | |||
| 82 | # We can go over command line length here, so be careful. | 84 | # We can go over command line length here, so be careful. |
| 83 | quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules | 85 | quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules |
| 84 | cmd_modpost = $(MODLISTCMD) | sed 's/\.ko$$/.o/' | $(modpost) -s -T - | 86 | cmd_modpost = $(MODLISTCMD) | sed 's/\.ko$$/.o/' | $(modpost) $(MODPOST_OPT) -s -T - |
| 85 | 87 | ||
| 86 | PHONY += __modpost | 88 | PHONY += __modpost |
| 87 | __modpost: $(modules:.ko=.o) FORCE | 89 | __modpost: $(modules:.ko=.o) FORCE |
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index bfcea5d3b27d..17855761e6b7 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <string.h> | 17 | #include <string.h> |
| 18 | #include <limits.h> | 18 | #include <limits.h> |
| 19 | #include <stdbool.h> | 19 | #include <stdbool.h> |
| 20 | #include <errno.h> | ||
| 20 | #include "modpost.h" | 21 | #include "modpost.h" |
| 21 | #include "../../include/generated/autoconf.h" | 22 | #include "../../include/generated/autoconf.h" |
| 22 | #include "../../include/linux/license.h" | 23 | #include "../../include/linux/license.h" |
| @@ -37,6 +38,8 @@ static int warn_unresolved = 0; | |||
| 37 | /* How a symbol is exported */ | 38 | /* How a symbol is exported */ |
| 38 | static int sec_mismatch_count = 0; | 39 | static int sec_mismatch_count = 0; |
| 39 | static int sec_mismatch_verbose = 1; | 40 | static int sec_mismatch_verbose = 1; |
| 41 | /* ignore missing files */ | ||
| 42 | static int ignore_missing_files; | ||
| 40 | 43 | ||
| 41 | enum export { | 44 | enum export { |
| 42 | export_plain, export_unused, export_gpl, | 45 | export_plain, export_unused, export_gpl, |
| @@ -161,7 +164,7 @@ struct symbol { | |||
| 161 | unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */ | 164 | unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */ |
| 162 | unsigned int kernel:1; /* 1 if symbol is from kernel | 165 | unsigned int kernel:1; /* 1 if symbol is from kernel |
| 163 | * (only for external modules) **/ | 166 | * (only for external modules) **/ |
| 164 | unsigned int preloaded:1; /* 1 if symbol from Module.symvers */ | 167 | unsigned int preloaded:1; /* 1 if symbol from Module.symvers, or crc */ |
| 165 | enum export export; /* Type of export */ | 168 | enum export export; /* Type of export */ |
| 166 | char name[0]; | 169 | char name[0]; |
| 167 | }; | 170 | }; |
| @@ -329,8 +332,11 @@ static void sym_update_crc(const char *name, struct module *mod, | |||
| 329 | { | 332 | { |
| 330 | struct symbol *s = find_symbol(name); | 333 | struct symbol *s = find_symbol(name); |
| 331 | 334 | ||
| 332 | if (!s) | 335 | if (!s) { |
| 333 | s = new_symbol(name, mod, export); | 336 | s = new_symbol(name, mod, export); |
| 337 | /* Don't complain when we find it later. */ | ||
| 338 | s->preloaded = 1; | ||
| 339 | } | ||
| 334 | s->crc = crc; | 340 | s->crc = crc; |
| 335 | s->crc_valid = 1; | 341 | s->crc_valid = 1; |
| 336 | } | 342 | } |
| @@ -407,6 +413,11 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
| 407 | 413 | ||
| 408 | hdr = grab_file(filename, &info->size); | 414 | hdr = grab_file(filename, &info->size); |
| 409 | if (!hdr) { | 415 | if (!hdr) { |
| 416 | if (ignore_missing_files) { | ||
| 417 | fprintf(stderr, "%s: %s (ignored)\n", filename, | ||
| 418 | strerror(errno)); | ||
| 419 | return 0; | ||
| 420 | } | ||
| 410 | perror(filename); | 421 | perror(filename); |
| 411 | exit(1); | 422 | exit(1); |
| 412 | } | 423 | } |
| @@ -1852,7 +1863,7 @@ static void add_header(struct buffer *b, struct module *mod) | |||
| 1852 | buf_printf(b, "\n"); | 1863 | buf_printf(b, "\n"); |
| 1853 | buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); | 1864 | buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); |
| 1854 | buf_printf(b, "\n"); | 1865 | buf_printf(b, "\n"); |
| 1855 | buf_printf(b, "struct module __this_module\n"); | 1866 | buf_printf(b, "__visible struct module __this_module\n"); |
| 1856 | buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n"); | 1867 | buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n"); |
| 1857 | buf_printf(b, "\t.name = KBUILD_MODNAME,\n"); | 1868 | buf_printf(b, "\t.name = KBUILD_MODNAME,\n"); |
| 1858 | if (mod->has_init) | 1869 | if (mod->has_init) |
| @@ -2118,7 +2129,7 @@ int main(int argc, char **argv) | |||
| 2118 | struct ext_sym_list *extsym_iter; | 2129 | struct ext_sym_list *extsym_iter; |
| 2119 | struct ext_sym_list *extsym_start = NULL; | 2130 | struct ext_sym_list *extsym_start = NULL; |
| 2120 | 2131 | ||
| 2121 | while ((opt = getopt(argc, argv, "i:I:e:msST:o:awM:K:")) != -1) { | 2132 | while ((opt = getopt(argc, argv, "i:I:e:mnsST:o:awM:K:")) != -1) { |
| 2122 | switch (opt) { | 2133 | switch (opt) { |
| 2123 | case 'i': | 2134 | case 'i': |
| 2124 | kernel_read = optarg; | 2135 | kernel_read = optarg; |
| @@ -2138,6 +2149,9 @@ int main(int argc, char **argv) | |||
| 2138 | case 'm': | 2149 | case 'm': |
| 2139 | modversions = 1; | 2150 | modversions = 1; |
| 2140 | break; | 2151 | break; |
| 2152 | case 'n': | ||
| 2153 | ignore_missing_files = 1; | ||
| 2154 | break; | ||
| 2141 | case 'o': | 2155 | case 'o': |
| 2142 | dump_write = optarg; | 2156 | dump_write = optarg; |
| 2143 | break; | 2157 | break; |
