From: Chuck Lever <chuck.lever@oracle.com>
To: steved@redhat.com
Cc: linux-nfs@vger.kernel.org
Subject: [PATCH 14/15] umount.nfs: Distinguish between nfs4 and nfs mounts
Date: Sun, 10 Oct 2010 20:06:20 -0400 [thread overview]
Message-ID: <20101011000620.6667.79025.stgit@ellison.1015granger.net> (raw)
In-Reply-To: <20101010234836.6667.4057.stgit@ellison.1015granger.net>
Neil Brown reports that umount.nfs is still confused by "-t nfs -o
vers=4" mounts.
/etc/mtab can be confused. /proc/mounts is authoritative on the
fstype of a mount. Have umount.nfs consult it to determine which
mechanism to use for unmounting. The code to read /proc/mounts was
lifted from the nfsstat command.
The code introduced by this patch may look like belt-n-suspenders, but
we have two use cases to consider:
1. Old kernels don't support the "vers=4" mount option, so
umount.nfs must look for the "nfs4" fstype
2. Upcoming kernels may eliminate support the "nfs4" fstype, so
umount.nfs must look for the "vers=4" mount option
Thus this logic checks for "nfs4" first then looks for the NFS version
setting.
Note that we could handle unmounting entirely in the kernel, but that
won't help older kernels that have this issue.
See:
https://bugzilla.linux-nfs.org/show_bug.cgi?id=189
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
utils/mount/nfsumount.c | 111 ++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 104 insertions(+), 7 deletions(-)
diff --git a/utils/mount/nfsumount.c b/utils/mount/nfsumount.c
index b1927de..02d40ff 100644
--- a/utils/mount/nfsumount.c
+++ b/utils/mount/nfsumount.c
@@ -38,6 +38,9 @@
#include "parse_opt.h"
#include "parse_dev.h"
+#define MOUNTSFILE "/proc/mounts"
+#define LINELEN (4096)
+
#if !defined(MNT_FORCE)
/* dare not try to include <linux/mount.h> -- lots of errors */
#define MNT_FORCE 1
@@ -242,6 +245,91 @@ static int nfs_umount23(const char *devname, char *string)
return result;
}
+/*
+ * Detect NFSv4 mounts.
+ *
+ * Consult /proc/mounts to determine if the mount point
+ * is an NFSv4 mount. The kernel is authoritative about
+ * what type of mount this is.
+ *
+ * Returns 1 if "mc" is an NFSv4 mount, zero if not, and
+ * -1 if some error occurred.
+ */
+static int nfs_umount_is_vers4(const struct mntentchn *mc)
+{
+ char buffer[LINELEN], *next;
+ int retval;
+ FILE *f;
+
+ if ((f = fopen(MOUNTSFILE, "r")) == NULL) {
+ fprintf(stderr, "%s: %s\n",
+ MOUNTSFILE, strerror(errno));
+ return -1;
+ }
+
+ retval = -1;
+ while (fgets(buffer, sizeof(buffer), f) != NULL) {
+ char *device, *mntdir, *type, *flags;
+ struct mount_options *options;
+ char *line = buffer;
+
+ next = strchr(line, '\n');
+ if (next != NULL)
+ *next = '\0';
+
+ device = strtok(line, " \t");
+ if (device == NULL)
+ continue;
+ mntdir = strtok(NULL, " \t");
+ if (mntdir == NULL)
+ continue;
+ if (strcmp(device, mc->m.mnt_fsname) != 0 &&
+ strcmp(mntdir, mc->m.mnt_dir) != 0)
+ continue;
+
+ type = strtok(NULL, " \t");
+ if (type == NULL)
+ continue;
+ if (strcmp(type, "nfs4") == 0)
+ goto out_nfs4;
+
+ flags = strtok(NULL, " \t");
+ if (flags == NULL)
+ continue;
+ options = po_split(flags);
+ if (options != NULL) {
+ unsigned long version;
+ int rc;
+
+ rc = nfs_nfs_version(options, &version);
+ po_destroy(options);
+ if (rc && version == 4)
+ goto out_nfs4;
+ }
+
+ goto out_nfs;
+ }
+ if (retval == -1)
+ fprintf(stderr, "%s was not found in %s\n",
+ mc->m.mnt_dir, MOUNTSFILE);
+
+out:
+ fclose(f);
+ return retval;
+
+out_nfs4:
+ if (verbose)
+ fprintf(stderr, "NFSv4 mount point detected\n");
+ retval = 1;
+ goto out;
+
+out_nfs:
+ if (verbose)
+ fprintf(stderr, "Legacy NFS mount point detected\n");
+ retval = 0;
+ goto out;
+}
+
static struct option umount_longopts[] =
{
{ "force", 0, 0, 'f' },
@@ -365,13 +453,22 @@ int nfsumount(int argc, char *argv[])
ret = EX_SUCCESS;
if (mc) {
- if (!lazy && strcmp(mc->m.mnt_type, "nfs4") != 0)
- /* We ignore the error from 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!
- */
- nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts);
+ if (!lazy) {
+ switch (nfs_umount_is_vers4(mc)) {
+ case 0:
+ /* We ignore the error from 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!
+ */
+ nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts);
+ break;
+ case 1:
+ break;
+ default:
+ return EX_FAIL;
+ }
+ }
ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir);
} else if (*spec != '/') {
if (!lazy)
next prev parent reply other threads:[~2010-10-11 0:06 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-11 0:04 [PATCH 00/15] Fixes for nfs-utils-1.2.4 Chuck Lever
2010-10-11 0:04 ` [PATCH 01/15] mountd: Clear mountd registrations at start up Chuck Lever
2010-10-13 14:55 ` Steve Dickson
2010-10-13 15:12 ` Steve Dickson
2010-10-13 20:12 ` Chuck Lever
2010-10-13 20:39 ` Steve Dickson
2010-10-14 13:21 ` Steve Dickson
2010-10-11 0:04 ` [PATCH 02/15] libnfs.a: Allow multiple RPC listeners to share listener port number Chuck Lever
2010-10-11 0:20 ` Jim Rees
2010-10-11 13:22 ` Steve Dickson
2010-10-11 16:04 ` Chuck Lever
2010-10-11 20:00 ` Jim Rees
[not found] ` <20101011200017.GA2451-8f4Pc2RrbJmHXe+LvDLADg@public.gmane.org>
2010-10-13 14:17 ` Steve Dickson
2010-10-11 0:04 ` [PATCH 03/15] export: Ensure that we free struct exportent->e_uuid Chuck Lever
2010-10-11 0:04 ` [PATCH 04/15] mount.nfs: Eliminate compiler warnings Chuck Lever
2010-10-11 13:32 ` Steve Dickson
2010-10-11 16:18 ` Chuck Lever
2010-10-11 16:45 ` Steve Dickson
2010-10-11 0:04 ` [PATCH 05/15] mount.nfs: Eliminate compiler warning in utils/mount/mount.c Chuck Lever
2010-10-11 0:05 ` [PATCH 06/15] mount.nfs: Eliminate compiler warnings in utils/mount/version.h Chuck Lever
2010-10-11 0:05 ` [PATCH 07/15] mount.nfs: Eliminate compiler warning in utils/mount/mount.c Chuck Lever
2010-10-11 0:05 ` [PATCH 08/15] mount.nfs: Eliminate compiler warnings " Chuck Lever
2010-10-11 0:05 ` [PATCH 09/15] mount.nfs: Eliminate compiler warning in utils/mount/nfsumount.c Chuck Lever
2010-10-11 0:05 ` [PATCH 10/15] " Chuck Lever
2010-10-11 0:05 ` [PATCH 11/15] mount.nfs: Eliminate compiler warning in utils/mount/parse_opt.c Chuck Lever
2010-10-11 0:06 ` [PATCH 12/15] mount.nfs: Eliminate compiler warnings in utils/mount/network.c Chuck Lever
2010-10-11 0:06 ` [PATCH 13/15] mount.nfs: mountproto does not support RDMA Chuck Lever
2010-10-11 0:06 ` Chuck Lever [this message]
2010-10-11 0:06 ` [PATCH 15/15] mount.nfs: don't show "remount" flag in /etc/mtab Chuck Lever
2010-10-11 4:16 ` [PATCH 00/15] Fixes for nfs-utils-1.2.4 Neil Brown
2010-10-11 15:18 ` Chuck Lever
[not found] ` <20101010234836.6667.4057.stgit-ewv44WTpT0t9HhUboXbp9zCvJB+x5qRC@public.gmane.org>
2010-10-14 14:37 ` Steve Dickson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20101011000620.6667.79025.stgit@ellison.1015granger.net \
--to=chuck.lever@oracle.com \
--cc=linux-nfs@vger.kernel.org \
--cc=steved@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).