diff options
author | Alan Jenkins <alan-jenkins@tuffmail.co.uk> | 2009-09-30 17:22:11 +0100 |
---|---|---|
committer | Alan Jenkins <alan-jenkins@tuffmail.co.uk> | 2009-10-01 09:04:16 +0100 |
commit | 1a8d5a031e8d6c007af77a6102693fa188ea4bc3 (patch) | |
tree | c96dfcf8acd17f059e35af674375ca32bcf575e0 | |
parent | 9a1c905651a38d1f2c6d4d836f81b5e06a503521 (diff) | |
download | module-init-tools-1a8d5a031e8d6c007af77a6102693fa188ea4bc3.tar.gz |
modprobe: Ignore custom install commands if module_in_kernel() doesn't work
Custom install commands rely on a working module_in_kernel() to avoid
an infinite fork-loop. This can fail if /sys/module/ is not available
(i.e. before sysfs is mounted). For example:
install snd-pcm /sbin/modprobe --ignore-install snd-pcm && \
{ /sbin/modprobe --quiet snd-pcm-oss ; : ; }
The snd-pcm-oss module depends on snd-pcm. If we can't tell that
snd-pcm is already loaded when we load snd-pcm-oss, we end up
running the entire install command again, ad infinitim.
Thanks go to Modestas Vainius for the idea and original patch.
Signed-off-by: Alan Jenkins <alan-jenkins@tuffmail.co.uk>
-rw-r--r-- | modprobe.c | 21 |
1 files changed, 15 insertions, 6 deletions
@@ -1095,6 +1095,7 @@ static int insmod(struct list_head *list, const char *command; struct module *mod = list_entry(list->next, struct module, list); int rc = 0; + int already_loaded; /* Take us off the list. */ list_del(&mod->list); @@ -1121,8 +1122,9 @@ static int insmod(struct list_head *list, } /* Don't do ANYTHING if already in kernel. */ - if (!(flags & mit_ignore_loaded) - && module_in_kernel(newname ?: mod->modname, NULL) == 1) { + already_loaded = module_in_kernel(newname ?: mod->modname, NULL); + + if (!(flags & mit_ignore_loaded) && already_loaded == 1) { if (flags & mit_first_time) error("Module %s already in kernel.\n", newname ?: mod->modname); @@ -1131,10 +1133,17 @@ static int insmod(struct list_head *list, command = find_command(mod->modname, commands); if (command && !(flags & mit_ignore_commands)) { - close_file(fd); - do_command(mod->modname, command, flags & mit_dry_run, error, - "install", cmdline_opts); - goto out_optstring; + if (already_loaded == -1) { + warn("/sys/module/ not present.\n"); + warn("Ignoring install commands for %s" + " in case it is already loaded.\n", + newname ?: mod->modname); + } else { + close_file(fd); + do_command(mod->modname, command, flags & mit_dry_run, + error, "install", cmdline_opts); + goto out_optstring; + } } module = grab_elf_file_fd(mod->filename, fd); |