diff --git a/sbin/umount/umount.8 b/sbin/umount/umount.8 index eac8d02f2a559..941b19038d7e0 100644 --- a/sbin/umount/umount.8 +++ b/sbin/umount/umount.8 @@ -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 diff --git a/sbin/umount/umount.c b/sbin/umount/umount.c index 924ed7df09373..78edcac974a00 100644 --- a/sbin/umount/umount.c +++ b/sbin/umount/umount.c @@ -56,6 +56,10 @@ __RCSID("$NetBSD: umount.c,v 1.53 2020/04/23 04:21:13 christos Exp $"); #include #include #include + +#include +#include +#include #endif /* !SMALL */ #include @@ -72,7 +76,7 @@ typedef enum { MNTANY, MNTON, MNTFROM } mntwhat; #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 addrinfo *); 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 **typelist, int raw) 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 **typelist, int raw) #ifndef SMALL if (verbose) (void)printf("(No separate unmount program.)\n"); + + if (dflag && statvfs(mntpt, &sfs) < 0) { + warn("%s: statvfs", mntpt); + return 1; + } #endif if (unmount(mntpt, fflag) == -1) { @@ -336,6 +350,15 @@ umountfs(const char *name, const char **typelist, int raw) 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,38 @@ 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; + } + + fd = opendisk(dev, O_RDWR, rdev, sizeof(rdev), 0); + if (fd < 0) { + warn("%s: opendisk", rdev); + return -1; + } + + memset(&vndio, 0, sizeof(vndio)); + vndio.vnd_flags = fflag ? VNDIOF_FORCE : 0; + + if (ioctl(fd, VNDIOCCLR, &vndio) < 0) { + warn("%s: VNDIOCCLR", rdev); + close(fd); + return -1; + } + close(fd); + + return 0; +} #endif /* !SMALL */ static void @@ -454,8 +509,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);