diff --git a/utils/mount/mount.c b/utils/mount/mount.c index 5b6a22e..a7de2e4 100644 --- a/utils/mount/mount.c +++ b/utils/mount/mount.c @@ -46,6 +46,9 @@ int verbose; int mounttype; int sloppy; +#define FOREGROUND (0) +#define BACKGROUND (1) + static struct option longopts[] = { { "fake", 0, 0, 'f' }, { "help", 0, 0, 'h' }, @@ -384,6 +387,41 @@ static int chk_mountpoint(char *mount_point) } #define NFS_MOUNT_VERS_DEFAULT 3 +static int try_mount(char *spec, char *mount_point, int *flags, + int nfs_mount_vers, char **extra_opts, char **mount_opts, + int fake, int nomtab, int bg) +{ + int ret = 1; + + if (nfs_mount_vers == 4) + ret = nfs4mount(spec, mount_point, flags, + extra_opts, mount_opts, bg); + else + ret = nfsmount(spec, mount_point, flags, + extra_opts, mount_opts, bg); + + if (ret) + return ret; + + if (!fake) { + ret = do_mount_syscall(spec, mount_point, + nfs_mount_vers == 4 ? "nfs4" : "nfs", + *flags, *mount_opts); + + if (ret) { + mount_error(mount_point, spec); + exit(EX_FAIL); + } + } + + if (!nomtab) + add_mtab(spec, mount_point, + nfs_mount_vers == 4 ? "nfs4" : "nfs", + *flags, *extra_opts, 0, 0); + + return ret; +} + int main(int argc, char *argv[]) { int c, flags = 0, nfs_mount_vers, mnt_err = 1, fake = 0; @@ -514,33 +552,28 @@ int main(int argc, char *argv[]) if (chk_mountpoint(mount_point)) exit(EX_FAIL); - if (nfs_mount_vers == 4) { - mnt_err = nfs4mount(spec, mount_point, &flags, - &extra_opts, &mount_opts, 0); - } - else { - if (!strcmp(progname, "mount.nfs")) { - mnt_err = nfsmount(spec, mount_point, &flags, - &extra_opts, &mount_opts, 0); - } - } - if (mnt_err) - exit(EX_FAIL); + mnt_err = try_mount(spec, mount_point, &flags, nfs_mount_vers, + &extra_opts, &mount_opts, fake, nomtab, FOREGROUND); - if (!fake) { - mnt_err = do_mount_syscall(spec, mount_point, - nfs_mount_vers == 4 ? "nfs4" : "nfs", - flags, mount_opts); + if (mnt_err == EX_BG) { + printf("%s: backgrounding \"%s\"\n", progname, spec); + fflush(stdout); - if (mnt_err) { - mount_error(mount_point, spec); + /* + * Parent exits immediately with success. + */ + if (daemon(0, 0)) { + fprintf(stderr, "%s: failed to start " + "background process: %s\n", + progname, strerror(errno)); exit(EX_FAIL); } - } + mnt_err = try_mount(spec, mount_point, &flags, nfs_mount_vers, + &extra_opts, &mount_opts, fake, nomtab, BACKGROUND); - if (!nomtab) { - add_mtab(spec, mount_point, nfs_mount_vers == 4 ? "nfs4" : "nfs", - flags, extra_opts, 0, 0); + if (verbose && mnt_err) + printf("%s: giving up \"%s\"\n", + progname, spec); } return 0; diff --git a/utils/mount/nfs4mount.c b/utils/mount/nfs4mount.c index e756379..1495dfb 100644 --- a/utils/mount/nfs4mount.c +++ b/utils/mount/nfs4mount.c @@ -183,11 +183,10 @@ int nfs4mount(const char *spec, const char *node, int *flags, int val; int bg, soft, intr; int nocto, noac, unshared, fscache; - int retry; - int retval; + int retry = -1; + int retval = EX_FAIL; time_t timeout, t; - retval = EX_FAIL; if (strlen(spec) >= sizeof(hostdir)) { fprintf(stderr, _("mount: " "excessively long host:dir argument\n")); @@ -235,7 +234,6 @@ int nfs4mount(const char *spec, const char *node, int *flags, noac = 0; unshared = 0; fscache = 0; - retry = 10000; /* 10000 minutes ~ 1 week */ /* * NFSv4 specifies that the default port should be 2049 @@ -338,6 +336,13 @@ int nfs4mount(const char *spec, const char *node, int *flags, | (unshared ? NFS4_MOUNT_UNSHARED : 0) | (fscache ? NFS4_MOUNT_FSCACHE : 0); + if (retry == -1) { + if (bg) + retry = 10000; /* 10000 mins == ~1 week */ + else + retry = 2; + } + if (unshared && fscache) { fprintf(stderr, _("mount: invalid mount options: " "nosharecache and fsc are incompatible.\n")); @@ -435,6 +440,13 @@ int nfs4mount(const char *spec, const char *node, int *flags, mount_errors(hostname, 0, bg); goto fail; } + + if (bg && !running_bg) { + if (retry > 0) + retval = EX_BG; + goto fail; + } + t = time(NULL); if (t >= timeout) { mount_errors(hostname, 0, bg); diff --git a/utils/mount/nfsmount.c b/utils/mount/nfsmount.c index 61634b9..70ec45c 100644 --- a/utils/mount/nfsmount.c +++ b/utils/mount/nfsmount.c @@ -864,7 +864,6 @@ int nfsmount(const char *spec, const char *node, int *flags, char **extra_opts, char **mount_opts, int running_bg) { - static char *prev_bg_host; char hostdir[1024]; char *hostname, *dirname, *old_opts, *mounthost = NULL; char new_opts[1024], cbuf[1024]; @@ -947,7 +946,7 @@ nfsmount(const char *spec, const char *node, int *flags, data.pseudoflavor = AUTH_SYS; bg = 0; - retry = 10000; /* 10000 minutes ~ 1 week */ + retry = -1; memset(mnt_pmap, 0, sizeof(*mnt_pmap)); mnt_pmap->pm_prog = MOUNTPROG; @@ -962,8 +961,12 @@ nfsmount(const char *spec, const char *node, int *flags, if (!nfsmnt_check_compat(nfs_pmap, mnt_pmap)) goto fail; - if (retry == 10000 && !bg) - retry = 2; /* reset for fg mounts */ + if (retry == -1) { + if (bg) + retry = 10000; /* 10000 minutes == ~1 week */ + else + retry = 2; /* 2 for fg mounts */ + } #ifdef NFS_MOUNT_DEBUG @@ -1002,18 +1005,6 @@ nfsmount(const char *spec, const char *node, int *flags, if (*flags & MS_REMOUNT) goto out_ok; - /* - * If the previous mount operation on the same host was - * backgrounded, and the "bg" for this mount is also set, - * give up immediately, to avoid the initial timeout. - */ - if (bg && !running_bg && - prev_bg_host && strcmp(hostname, prev_bg_host) == 0) { - if (retry > 0) - retval = EX_BG; - return retval; - } - /* create mount deamon client */ /* @@ -1082,7 +1073,6 @@ nfsmount(const char *spec, const char *node, int *flags, continue; } if (!running_bg) { - prev_bg_host = xstrdup(hostname); if (retry > 0) retval = EX_BG; goto fail;