X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fmount%2Fnfsumount.c;h=b2327e03561d9fc41bb4f69a875551b1abd3f864;hp=8902f0088a0533abdd3a0d64a06ac938d4231d86;hb=2d173a587a7dbee81ffaf246d044f384fb6487c8;hpb=97fed3061fd5c742ebd1f685e3e6dcb62e835b74 diff --git a/utils/mount/nfsumount.c b/utils/mount/nfsumount.c index 8902f00..b2327e0 100644 --- a/utils/mount/nfsumount.c +++ b/utils/mount/nfsumount.c @@ -34,6 +34,7 @@ #include "mount.h" #include "error.h" #include "network.h" +#include "parse_dev.h" #if !defined(MNT_FORCE) /* dare not try to include -- lots of errors */ @@ -142,7 +143,7 @@ static int del_mtab(const char *spec, const char *node) * We will need this information to get through the firewall again * to do the umount. */ -static int do_nfs_umount(const char *spec, char *opts) +static int do_nfs_umount23(const char *spec, char *opts) { char *hostname; char *dirname; @@ -150,21 +151,11 @@ static int do_nfs_umount(const char *spec, char *opts) struct mntent mnt = { .mnt_opts = opts }; struct pmap *pmap = &mnt_server.pmap; char *p; + int result = EX_USAGE; + + if (!nfs_parse_devname(spec, &hostname, &dirname)) + return result; - if (spec == NULL) { - nfs_error(_("%s: No NFS export name was provided"), - progname); - return EX_USAGE; - } - - p = strchr(spec, ':'); - if (p == NULL) { - nfs_error(_("%s: '%s' is not a legal NFS export name"), - progname, spec); - return EX_USAGE; - } - hostname = xstrndup(spec, p - spec); - dirname = xstrdup(p + 1); #ifdef NFS_MOUNT_DEBUG printf(_("host: %s, directory: %s\n"), hostname, dirname); #endif @@ -190,7 +181,7 @@ static int do_nfs_umount(const char *spec, char *opts) } pmap->pm_prog = MOUNTPROG; - pmap->pm_vers = MOUNTVERS_NFSV3; + pmap->pm_vers = 0; /* unknown */ if (opts && (p = strstr(opts, "mountprog=")) && isdigit(*(p+10))) pmap->pm_prog = atoi(p+10); if (opts && (p = strstr(opts, "mountport=")) && isdigit(*(p+10))) @@ -199,30 +190,40 @@ static int do_nfs_umount(const char *spec, char *opts) pmap->pm_vers = nfsvers_to_mnt(2); if (opts && hasmntopt(&mnt, "v3")) pmap->pm_vers = nfsvers_to_mnt(3); - if (opts && hasmntopt(&mnt, "v4")) - pmap->pm_vers = nfsvers_to_mnt(4); if (opts && (p = strstr(opts, "vers=")) && isdigit(*(p+5))) pmap->pm_vers = nfsvers_to_mnt(atoi(p+5)); if (opts && (p = strstr(opts, "mountvers=")) && isdigit(*(p+10))) pmap->pm_vers = atoi(p+10); - if (opts && (hasmntopt(&mnt, "udp") || hasmntopt(&mnt, "proto=udp"))) + if (opts && (hasmntopt(&mnt, "udp") + || hasmntopt(&mnt, "proto=udp") + || hasmntopt(&mnt, "mountproto=udp") + )) pmap->pm_prot = IPPROTO_UDP; - if (opts && (hasmntopt(&mnt, "tcp") || hasmntopt(&mnt, "proto=tcp"))) + if (opts && (hasmntopt(&mnt, "tcp") + || hasmntopt(&mnt, "proto=tcp") + || hasmntopt(&mnt, "mountproto=tcp") + )) pmap->pm_prot = IPPROTO_TCP; if (!nfs_gethostbyname(hostname, &mnt_server.saddr)) { - nfs_error(_("%s: '%s' does not contain a recognized hostname"), - progname, spec); - return EX_USAGE; + nfs_error(_("%s: DNS resolution of '%s' failed"), + progname, hostname); + goto out; } if (!nfs_call_umount(&mnt_server, &dirname)) { nfs_error(_("%s: Server failed to unmount '%s'"), progname, spec); - return EX_USAGE; + result = EX_FAIL; + goto out; } - return EX_SUCCESS; + result = EX_SUCCESS; + +out: + free(hostname); + free(dirname); + return result; } static struct option umount_longopts[] = @@ -349,12 +350,16 @@ int nfsumount(int argc, char *argv[]) ret = 0; if (mc) { if (!lazy && strcmp(mc->m.mnt_type, "nfs4") != 0) - ret = do_nfs_umount(mc->m.mnt_fsname, mc->m.mnt_opts); - if (!ret || force) - ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir); + /* We ignore the error from do_nfs_umount23. + * If the actual umount succeeds (in del_mtab), + * we don't want to signal an error, as that + * could cause /sbin/mount to retry! + */ + do_nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts); + ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir); } else if (*spec != '/') { if (!lazy) - ret = do_nfs_umount(spec, "tcp,v3"); + ret = do_nfs_umount23(spec, "tcp,v3"); } else ret = del_mtab(NULL, spec);