svn commit: r321689 - head/sbin/umount

Rick Macklem rmacklem at FreeBSD.org
Sat Jul 29 20:08:27 UTC 2017


Author: rmacklem
Date: Sat Jul 29 20:08:25 2017
New Revision: 321689
URL: https://svnweb.freebsd.org/changeset/base/321689

Log:
  Add a new "-N" option to umount(8), that does a forced dismount of an NFS mount
  point.
  
  The new "-N" option does a forced dismount of an NFS mount point, but avoids
  doing any checking of the mounted-on path, so that it will not get hung
  when a vnode lock is held by another hung process on the mounted-on vnode.
  The most common case of this is a "umount" with the "-f" option.
  Other than avoiding checking the mounted-on path, it performs the same
  forced dismount as a successful "umount -f" would do.
  
  This commit includes a content change to the man page.
  
  Tested by:	pho
  Reviewed by:	kib
  MFC after:	2 weeks
  Relnotes:	yes
  Differential Revision:	https://reviews.freebsd.org/D11735

Modified:
  head/sbin/umount/umount.8
  head/sbin/umount/umount.c

Modified: head/sbin/umount/umount.8
==============================================================================
--- head/sbin/umount/umount.8	Sat Jul 29 19:52:47 2017	(r321688)
+++ head/sbin/umount/umount.8	Sat Jul 29 20:08:25 2017	(r321689)
@@ -28,7 +28,7 @@
 .\"     @(#)umount.8	8.2 (Berkeley) 5/8/95
 .\" $FreeBSD$
 .\"
-.Dd September 10, 2016
+.Dd July 25, 2017
 .Dt UMOUNT 8
 .Os
 .Sh NAME
@@ -36,7 +36,7 @@
 .Nd unmount file systems
 .Sh SYNOPSIS
 .Nm
-.Op Fl fnv
+.Op Fl fNnv
 .Ar special ... | node ... | fsid ...
 .Nm
 .Fl a | A
@@ -81,6 +81,15 @@ The root file system cannot be forcibly unmounted.
 For NFS, a forced dismount can take up to 1 minute or more to
 complete against an unresponsive server and may throw away
 data not yet written to the server for this case.
+If a process, such as
+.Nm
+without the
+.Fl f
+flag is hung on an
+.Tn NFS
+mount point, use the
+.Fl N
+flag instead.
 Also, doing a forced dismount of an NFSv3 mount when
 .Xr rpc.lockd 8
 is running is unsafe and can result in a crash.
@@ -94,6 +103,24 @@ option and, unless otherwise specified with the
 option, will only unmount
 .Tn NFS
 file systems.
+.It Fl N
+Do a forced dismount of an
+.Tn NFS
+mount point without checking the mount path.
+This option can only be used with the path to the mount point
+.Ar node
+and the path must be specified exactly as it was at mount time.
+This option is useful when a process is hung waiting for an unresponsive
+.Tn NFS
+server while holding a vnode lock on the mounted-on vnode, such that
+.Nm
+with the
+.Fl f
+flag can't complete.
+Using this option can result in a loss of file updates that have not been
+flushed to the
+.Tn NFS
+server.
 .It Fl n
 Unless the
 .Fl f

Modified: head/sbin/umount/umount.c
==============================================================================
--- head/sbin/umount/umount.c	Sat Jul 29 19:52:47 2017	(r321688)
+++ head/sbin/umount/umount.c	Sat Jul 29 20:08:25 2017	(r321689)
@@ -86,13 +86,13 @@ int	 xdr_dir (XDR *, char *);
 int
 main(int argc, char *argv[])
 {
-	int all, errs, ch, mntsize, error;
+	int all, errs, ch, mntsize, error, nfsforce, ret;
 	char **typelist = NULL;
 	struct statfs *mntbuf, *sfs;
 	struct addrinfo hints;
 
-	all = errs = 0;
-	while ((ch = getopt(argc, argv, "AaF:fh:nt:v")) != -1)
+	nfsforce = all = errs = 0;
+	while ((ch = getopt(argc, argv, "AaF:fh:Nnt:v")) != -1)
 		switch (ch) {
 		case 'A':
 			all = 2;
@@ -110,6 +110,9 @@ main(int argc, char *argv[])
 			all = 2;
 			nfshost = optarg;
 			break;
+		case 'N':
+			nfsforce = 1;
+			break;
 		case 'n':
 			fflag |= MNT_NONBUSY;
 			break;
@@ -132,12 +135,15 @@ main(int argc, char *argv[])
 		err(1, "-f and -n are mutually exclusive");
 
 	/* Start disks transferring immediately. */
-	if ((fflag & (MNT_FORCE | MNT_NONBUSY)) == 0)
+	if ((fflag & (MNT_FORCE | MNT_NONBUSY)) == 0 && nfsforce == 0)
 		sync();
 
 	if ((argc == 0 && !all) || (argc != 0 && all))
 		usage();
 
+	if (nfsforce != 0 && (argc == 0 || nfshost != NULL || typelist != NULL))
+		usage();
+
 	/* -h implies "-t nfs" if no -t flag. */
 	if ((nfshost != NULL) && (typelist == NULL))
 		typelist = makevfslist("nfs");
@@ -175,7 +181,20 @@ main(int argc, char *argv[])
 		break;
 	case 0:
 		for (errs = 0; *argv != NULL; ++argv)
-			if (checkname(*argv, typelist) != 0)
+			if (nfsforce != 0) {
+				/*
+				 * First do the nfssvc() syscall to shut down
+				 * the mount point and then do the forced
+				 * dismount.
+				 */
+				ret = nfssvc(NFSSVC_FORCEDISM, *argv);
+				if (ret >= 0)
+					ret = unmount(*argv, MNT_FORCE);
+				if (ret < 0) {
+					warn("%s", *argv);
+					errs = 1;
+				}
+			} else if (checkname(*argv, typelist) != 0)
 				errs = 1;
 		break;
 	}
@@ -635,7 +654,7 @@ usage(void)
 {
 
 	(void)fprintf(stderr, "%s\n%s\n",
-	    "usage: umount [-fnv] special ... | node ... | fsid ...",
+	    "usage: umount [-fNnv] special ... | node ... | fsid ...",
 	    "       umount -a | -A [-F fstab] [-fnv] [-h host] [-t type]");
 	exit(1);
 }


More information about the svn-src-head mailing list