From: Chuck Lever Date: Wed, 10 Oct 2007 19:06:43 +0000 (-0400) Subject: text-based mount.nfs: Add functions to handle background mounting X-Git-Tag: nfs-utils-1-1-1~16 X-Git-Url: https://git.decadent.org.uk/gitweb/?a=commitdiff_plain;h=ec565223d509f1537c38ae01d330fb24e4305da9;p=nfs-utils.git text-based mount.nfs: Add functions to handle background mounting Add helper functions that handle background mounts; one each for foreground processing (to try the request, and determine when to fork); and one for background processing (retry the request multiple times as a forked background daemon). Signed-off-by: Chuck Lever Signed-off-by: Neil Brown --- diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c index 72480b7..2d717fb 100644 --- a/utils/mount/stropts.c +++ b/utils/mount/stropts.c @@ -575,6 +575,95 @@ static int nfsmount_fg(const char *spec, const char *node, return EX_FAIL; } +/* + * Handle "background" NFS mount [first try] + * + * Returns a valid mount command exit code. + * + * EX_BG should cause the caller to fork and invoke nfsmount_child. + */ +static int nfsmount_parent(const char *spec, const char *node, + const char *type, char *hostname, int flags, + struct mount_options *options, + int fake, char **extra_opts) +{ + if (try_mount(spec, node, type, flags, options, + fake, extra_opts)) + return EX_SUCCESS; + + if (is_permanent_error(errno)) { + mount_error(spec, node, errno); + return EX_FAIL; + } + + sys_mount_errors(hostname, errno, 1, 1); + return EX_BG; +} + +/* + * Handle "background" NFS mount [retry daemon] + * + * Returns a valid mount command exit code: EX_SUCCESS if successful, + * EX_FAIL if a failure occurred. There's nothing to catch the + * error return, though, so we use sys_mount_errors to log the + * failure. + */ +static int nfsmount_child(const char *spec, const char *node, + const char *type, char *hostname, int flags, + struct mount_options *options, + int fake, char **extra_opts) +{ + unsigned int secs = 1; + time_t timeout = time(NULL); + char *retry; + + timeout += 60 * 10000; /* default: 10,000 minutes */ + retry = po_get(options, "retry"); + if (retry) + timeout += 60 * atoi(retry); + + for (;;) { + if (sleep(secs)) + break; + secs <<= 1; + if (secs > 120) + secs = 120; + + if (try_mount(spec, node, type, flags, options, + fake, extra_opts)) + return EX_SUCCESS; + + if (is_permanent_error(errno)) + break; + + if (time(NULL) > timeout) + break; + + sys_mount_errors(hostname, errno, 1, 1); + }; + + sys_mount_errors(hostname, errno, 1, 0); + return EX_FAIL; +} + +/* + * Handle "background" NFS mount + * + * Returns a valid mount command exit code. + */ +static int nfsmount_bg(const char *spec, const char *node, + const char *type, char *hostname, int flags, + struct mount_options *options, + int fake, int child, char **extra_opts) +{ + if (!child) + return nfsmount_parent(spec, node, type, hostname, flags, + options, fake, extra_opts); + else + return nfsmount_child(spec, node, type, hostname, flags, + options, fake, extra_opts); +} + /** * nfsmount_string - Mount an NFS file system using C string options * @spec: C string specifying remote share to mount ("hostname:path")