text-based mount.nfs: add function to do foreground retries
authorChuck Lever <chuck.lever@oracle.com>
Wed, 10 Oct 2007 19:06:41 +0000 (15:06 -0400)
committerNeil Brown <neilb@suse.de>
Thu, 11 Oct 2007 01:03:18 +0000 (11:03 +1000)
Make the differences between the foreground and background mount logic
explicit by creating separate functions to handle each -- think of them as
separate scripts for doing a foreground or a background mount.

NFS foreground mounts are supposed to retry for a little while before
giving up.  Add a function to handle this.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Neil Brown <neilb@suse.de>
utils/mount/stropts.c

index b6d3a12..72480b7 100644 (file)
@@ -524,6 +524,57 @@ static int try_mount(const char *spec, const char *node, const char *type,
                                        options, fake, extra_opts);
 }
 
                                        options, fake, extra_opts);
 }
 
+/*
+ * Handle "foreground" NFS mounts.
+ *
+ * Retry the mount request for as long as the 'retry=' option says.
+ *
+ * Returns a valid mount command exit code.
+ */
+static int nfsmount_fg(const char *spec, const char *node,
+                      const char *type, int flags,
+                      struct mount_options *options, int fake,
+                      char **extra_opts)
+{
+       unsigned int secs = 1;
+       time_t timeout = time(NULL);
+       char *retry;
+
+       timeout += 60 * 2;              /* default: 2 minutes */
+       retry = po_get(options, "retry");
+       if (retry)
+               timeout += 60 * atoi(retry);
+
+       if (verbose)
+               printf(_("%s: timeout set for %s"),
+                       progname, ctime(&timeout));
+
+       for (;;) {
+               if (try_mount(spec, node, type, flags,
+                                       options, fake, extra_opts))
+                       return EX_SUCCESS;
+
+               if (is_permanent_error(errno))
+                       break;
+
+               if (time(NULL) > timeout) {
+                       errno = ETIMEDOUT;
+                       break;
+               }
+
+               if (errno != ETIMEDOUT) {
+                       if (sleep(secs))
+                               break;
+                       secs <<= 1;
+                       if (secs > 10)
+                               secs = 10;
+               }
+       };
+
+       mount_error(spec, node, errno);
+       return EX_FAIL;
+}
+
 /**
  * nfsmount_string - Mount an NFS file system using C string options
  * @spec: C string specifying remote share to mount ("hostname:path")
 /**
  * nfsmount_string - Mount an NFS file system using C string options
  * @spec: C string specifying remote share to mount ("hostname:path")