Hey-
        2nd of two patches.  This patch enhances modprobe to operate like rmmod
in non-blocking mode.  It also adds a -w option to allow for explicit blocking
operation.

Regards
Neil

Signed-off-by: Neil Horman <[EMAIL PROTECTED]>


 modprobe.8 |    9 +++++++++
 modprobe.c |   21 ++++++++++++++-------
 2 files changed, 23 insertions(+), 7 deletions(-)


diff --git a/modprobe.8 b/modprobe.8
index 6910b5a..83f3229 100644
--- a/modprobe.8
+++ b/modprobe.8
@@ -109,6 +109,15 @@ sense to specify module parameters when removing modules).
 There is usually no reason to remove modules, but some
 buggy modules require it.  Your kernel may not support
 removal of modules.
+
+.TP
+\fB-w --wait \fR
+This option is applicable only with the -r or --remove option.
+It causes modprobe to block in the kernel waiting for the specified
+modules reference count to reach zero.  Default operation is for
+modprobe to operate like rmmod, which exits with EWOULDBLOCK if the 
+modules reference count is non-zero.
+
 .TP
 \fB-V --version \fR
 Show version of program, and exit.  See below for caveats when run on older 
kernels.
diff --git a/modprobe.c b/modprobe.c
index ea8de74..c9bd6af 100644
--- a/modprobe.c
+++ b/modprobe.c
@@ -913,7 +913,8 @@ static void rmmod(struct list_head *list,
                  struct module_command *commands,
                  int ignore_commands,
                  int ignore_inuse,
-                 const char *cmdline_opts)
+                 const char *cmdline_opts,
+                 int flags)
 {
        const char *command;
        unsigned int usecount = 0;
@@ -967,7 +968,7 @@ static void rmmod(struct list_head *list,
        /* Now do things we depend. */
        if (!list_empty(list))
                rmmod(list, NULL, 0, warn, dry_run, verbose, commands,
-                     0, 1, cmdline_opts);
+                     0, 1, cmdline_opts, flags);
        return;
 
 nonexistent_module:
@@ -1333,7 +1334,8 @@ static void handle_module(const char *modname,
                          int strip_vermagic,
                          int strip_modversion,
                          int unknown_silent,
-                         const char *cmdline_opts)
+                         const char *cmdline_opts,
+                         int flags)
 {
        if (list_empty(todo_list)) {
                const char *command;
@@ -1355,7 +1357,7 @@ static void handle_module(const char *modname,
 
        if (remove)
                rmmod(todo_list, newname, first_time, error, dry_run, verbose,
-                     commands, ignore_commands, 0, cmdline_opts);
+                     commands, ignore_commands, 0, cmdline_opts, flags);
        else
                insmod(todo_list, NOFAIL(strdup(options)), newname,
                       first_time, error, dry_run, verbose, modoptions,
@@ -1368,6 +1370,7 @@ static struct option options[] = { { "verbose", 0, NULL, 
'v' },
                                   { "config", 1, NULL, 'C' },
                                   { "name", 1, NULL, 'o' },
                                   { "remove", 0, NULL, 'r' },
+                                  { "wait", 0, NULL, 'w' },
                                   { "showconfig", 0, NULL, 'c' },
                                   { "autoclean", 0, NULL, 'k' },
                                   { "quiet", 0, NULL, 'q' },
@@ -1430,6 +1433,7 @@ int main(int argc, char *argv[])
        char *newname = NULL;
        char *aliasfilename, *symfilename;
        errfn_t error = fatal;
+       int flags = O_NONBLOCK|O_EXCL;
 
        /* Prepend options from environment. */
        argv = merge_args(getenv("MODPROBE_OPTIONS"), argv, &argc);
@@ -1444,7 +1448,7 @@ int main(int argc, char *argv[])
                try_old_version("modprobe", argv);
 
        uname(&buf);
-       while ((opt = getopt_long(argc, argv, "vVC:o:rknqQsclt:aifb", options, 
NULL)) != -1){
+       while ((opt = getopt_long(argc, argv, "vVC:o:rknqQsclt:aifbw", options, 
NULL)) != -1){
                switch (opt) {
                case 'v':
                        add_to_env_var("-v");
@@ -1529,6 +1533,9 @@ int main(int argc, char *argv[])
                case 'b':
                        use_blacklist = 1;
                        break;
+               case 'w':
+                       flags &= ~O_NONBLOCK;
+                       break;
                case 1:
                        strip_vermagic = 1;
                        break;
@@ -1651,7 +1658,7 @@ int main(int argc, char *argv[])
                                              ignore_proc, strip_vermagic,
                                              strip_modversion,
                                              unknown_silent,
-                                             optstring);
+                                             optstring, flags);
 
                                aliases = aliases->next;
                                INIT_LIST_HEAD(&list);
@@ -1666,7 +1673,7 @@ int main(int argc, char *argv[])
                                      verbose, modoptions, commands,
                                      ignore_commands, ignore_proc,
                                      strip_vermagic, strip_modversion,
-                                     unknown_silent, optstring);
+                                     unknown_silent, optstring, flags);
                }
        }
        if (log)
-- 
/***************************************************
 *Neil Horman
 *Software Engineer
 *Red Hat, Inc.
 [EMAIL PROTECTED]
 *gpg keyid: 1024D / 0x92A74FA1
 *http://pgp.mit.edu
 ***************************************************/
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to