Module Name:    src
Committed By:   christos
Date:           Tue Mar 25 19:01:11 UTC 2025

Modified Files:
        src/sbin/umount: umount.8 umount.c

Log Message:
GitHub/31: Ricardo Branco: Add -d flag to umount to detach vnds, like FreeBSD
and Linux.


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sbin/umount/umount.8
cvs rdiff -u -r1.53 -r1.54 src/sbin/umount/umount.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sbin/umount/umount.8
diff -u src/sbin/umount/umount.8:1.19 src/sbin/umount/umount.8:1.20
--- src/sbin/umount/umount.8:1.19	Sat Jan 22 04:59:26 2022
+++ src/sbin/umount/umount.8	Tue Mar 25 15:01:11 2025
@@ -1,4 +1,4 @@
-.\"	$NetBSD: umount.8,v 1.19 2022/01/22 09:59:26 wiz Exp $
+.\"	$NetBSD: umount.8,v 1.20 2025/03/25 19:01:11 christos Exp $
 .\"
 .\" Copyright (c) 1980, 1989, 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)umount.8	8.2 (Berkeley) 5/8/95
 .\"
-.Dd September 12, 2016
+.Dd February 3, 2024
 .Dt UMOUNT 8
 .Os
 .Sh NAME
@@ -37,12 +37,12 @@
 .Nd unmount file systems
 .Sh SYNOPSIS
 .Nm
-.Op Fl fvFR
+.Op Fl dfvFR
 .Op Fl t Ar fstypelist
 .Ar special | node
 .Nm
 .Fl a
-.Op Fl fvF
+.Op Fl dfvF
 .Op Fl h Ar host
 .Op Fl t Ar fstypelist
 .Sh DESCRIPTION
@@ -83,6 +83,11 @@ The options are as follows:
 .Bl -tag -width indent
 .It Fl a
 All the currently mounted file systems except the root are unmounted.
+.It Fl d
+If the filesystem is mounted on an
+.Xr vnd 4
+device (a vnode disk), detach it after
+.Xr unmount 2 .
 .It Fl f
 The file system is forcibly unmounted.
 Active special devices continue to work,
@@ -165,7 +170,8 @@ file system table
 .Sh SEE ALSO
 .Xr unmount 2 ,
 .Xr fstab 5 ,
-.Xr mount 8
+.Xr mount 8 ,
+.Xr vndconfig 8
 .Sh HISTORY
 A
 .Nm

Index: src/sbin/umount/umount.c
diff -u src/sbin/umount/umount.c:1.53 src/sbin/umount/umount.c:1.54
--- src/sbin/umount/umount.c:1.53	Thu Apr 23 00:21:13 2020
+++ src/sbin/umount/umount.c	Tue Mar 25 15:01:11 2025
@@ -1,4 +1,4 @@
-/*	$NetBSD: umount.c,v 1.53 2020/04/23 04:21:13 christos Exp $	*/
+/*	$NetBSD: umount.c,v 1.54 2025/03/25 19:01:11 christos Exp $	*/
 
 /*-
  * Copyright (c) 1980, 1989, 1993
@@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 19
 #if 0
 static char sccsid[] = "@(#)umount.c	8.8 (Berkeley) 5/8/95";
 #else
-__RCSID("$NetBSD: umount.c,v 1.53 2020/04/23 04:21:13 christos Exp $");
+__RCSID("$NetBSD: umount.c,v 1.54 2025/03/25 19:01:11 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -56,6 +56,10 @@ __RCSID("$NetBSD: umount.c,v 1.53 2020/0
 #include <rpc/pmap_prot.h>
 #include <nfs/rpcv2.h>
 #include <nfs/nfsmount.h>
+
+#include <dev/vndvar.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
 #endif /* !SMALL */
 
 #include <err.h>
@@ -72,7 +76,7 @@ typedef enum { MNTANY, MNTON, MNTFROM } 
 #ifndef SMALL
 #include "mountprog.h"
 
-static int	 fake, verbose;
+static int	 dflag, fake, verbose;
 static char	*nfshost;
 static struct addrinfo *nfshost_ai = NULL;
 
@@ -80,9 +84,10 @@ static int	 namematch(const struct addri
 static int	 sacmp(const struct sockaddr *, const struct sockaddr *);
 static int	 xdr_dir(XDR *, char *);
 static const char *getmntproto(const char *);
+static int	 vn_detach(const char *);
 #endif /* !SMALL */
 
-static int	 fflag;
+static int	 all, fflag;
 static char	*getmntname(const char *, mntwhat, char **);
 static int	 umountfs(const char *, const char **, int);
 static void	 usage(void) __dead;
@@ -90,7 +95,7 @@ static void	 usage(void) __dead;
 int
 main(int argc, char *argv[])
 {
-	int ch, errs, all = 0, raw = 0;
+	int ch, errs, raw = 0;
 	char mntfromname[MAXPATHLEN];
 #ifndef SMALL
 	int mnts;
@@ -102,7 +107,7 @@ main(int argc, char *argv[])
 #ifdef SMALL
 #define OPTS "fR"
 #else
-#define OPTS "AaFfh:Rt:v"
+#define OPTS "AadFfh:Rt:v"
 #endif
 	while ((ch = getopt(argc, argv, OPTS)) != -1)
 		switch (ch) {
@@ -117,6 +122,9 @@ main(int argc, char *argv[])
 		case 'a':
 			all = 1;
 			break;
+		case 'd':
+			dflag = 1;
+			break;
 		case 'F':
 			fake = 1;
 			break;
@@ -195,6 +203,7 @@ umountfs(const char *name, const char **
 	char *type, rname[MAXPATHLEN], umountprog[MAXPATHLEN];
 	mntwhat what;
 	struct stat sb;
+	struct statvfs sfs;
 
 	if (raw) {
 		mntpt = name;
@@ -310,6 +319,11 @@ umountfs(const char *name, const char **
 #ifndef SMALL
 	if (verbose)
 		(void)printf("(No separate unmount program.)\n");
+
+	if (dflag && statvfs(mntpt, &sfs) == -1) {
+		warn("%s: statvfs", mntpt);
+		return 1;
+	}
 #endif
 
 	if (unmount(mntpt, fflag) == -1) {
@@ -336,6 +350,15 @@ umountfs(const char *name, const char **
 		auth_destroy(clp->cl_auth);
 		clnt_destroy(clp);
 	}
+
+	if (dflag) {
+		if (vn_detach(sfs.f_mntfromname) == 0) {
+			if (verbose)
+				(void)printf("%s: detached\n",
+				    sfs.f_mntfromname);
+		} else if (!all)
+			return (-1);
+	}
 #endif /* ! SMALL */
 	return 0;
 }
@@ -444,6 +467,37 @@ getmntproto(const char *name)
 	(void)mount("nfs", name, MNT_GETARGS, &nfsargs, sizeof(nfsargs));
 	return nfsargs.sotype == SOCK_STREAM ? "tcp" : "udp";
 }
+
+int
+vn_detach(const char *dev)
+{
+	struct vnd_ioctl vndio;
+	char rdev[MAXPATHLEN + 1];
+	int fd;
+
+	if (strncmp(dev, "/dev/vnd", sizeof("/dev/vnd") - 1)) {
+		if (!all)
+			warnx("invalid vnd device: %s", dev);
+		return -1;
+	}
+
+	if ((fd = opendisk(dev, O_RDWR, rdev, sizeof(rdev), 0)) == -1) {
+		warn("%s: opendisk", rdev);
+		return -1;
+	}
+
+	memset(&vndio, 0, sizeof(vndio));
+	vndio.vnd_flags = fflag ? VNDIOF_FORCE : 0;
+
+	if (ioctl(fd, VNDIOCCLR, &vndio) == -1) {
+		warn("%s: VNDIOCCLR", rdev);
+		close(fd);
+		return -1;
+	}
+	close(fd);
+
+	return 0;
+}
 #endif /* !SMALL */
 
 static void
@@ -454,8 +508,8 @@ usage(void)
 	    "Usage: %s [-fR]  special | node\n", getprogname());
 #else
 	(void)fprintf(stderr,
-	    "Usage: %s [-fvFR] [-t fstypelist] special | node\n"
-	    "\t %s -a[fvF] [-h host] [-t fstypelist]\n", getprogname(),
+	    "Usage: %s [-dfvFR] [-t fstypelist] special | node\n"
+	    "\t %s -a[dfvF] [-h host] [-t fstypelist]\n", getprogname(),
 	    getprogname());
 #endif /* SMALL */
 	exit(1);

Reply via email to