Skip to content

Commit

Permalink
umount(8): Add -d option to detach vn(4) devices
Browse files Browse the repository at this point in the history
The '-d' option tells umount(8) to detach the underlying vn(4) device if
the filesystem was mounted from it.  Note that vn(4) is a virtual disk
and can provides multiple filesystems, so the vn(4) detaching can only
succeed when all the filesystems are umounted.

For example:
$ vnconfig -c vn dfly.img
vn4
$ mount_msdos /dev/vn4s1 /mnt/dfly/boot
$ mount_ufs /dev/vn4s2a /mnt/dfly/root
$ umount -d /mnt/dfly/boot
umount: VNIOCDETACH: /dev/vn4: Device busy
umount: detach of /dev/vn4s1 failed
$ umount -d /mnt/dfly/root
(now vn4 is detached)

A similar option exists in Linux's and FreeBSD's umount(8).

GitHub PR: #24
See Also: freebsd/freebsd-src#972
  • Loading branch information
ricardobranco777 authored and liweitianux committed Mar 22, 2024
1 parent c008937 commit ce0bf05
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 9 deletions.
13 changes: 9 additions & 4 deletions sbin/umount/umount.8
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@
.\" @(#)umount.8 8.2 (Berkeley) 5/8/95
.\" $FreeBSD: src/sbin/umount/umount.8,v 1.7.2.3 2001/12/14 15:17:57 ru Exp $
.\"
.Dd September 29, 2016
.Dd March 10, 2024
.Dt UMOUNT 8
.Os
.Sh NAME
.Nm umount
.Nd unmount filesystems
.Sh SYNOPSIS
.Nm
.Op Fl fv
.Op Fl dfv
.Ar special \&| node
.Nm
.Fl a | A
.Op Fl F Ar fstab
.Op Fl fv
.Op Fl dfv
.Op Fl h Ar host
.Op Fl t Ar type
.Sh DESCRIPTION
Expand Down Expand Up @@ -71,6 +71,10 @@ are unmounted.
.It Fl A
All the currently mounted filesystems except
the root are unmounted.
.It Fl d
If the filesystem was mounted from a
.Xr vn 4
vnode disk, detach the underlying disk as well.
.It Fl F Ar fstab
Specify the
.Pa fstab
Expand Down Expand Up @@ -132,7 +136,8 @@ filesystem table
.Sh SEE ALSO
.Xr unmount 2 ,
.Xr fstab 5 ,
.Xr mount 8
.Xr mount 8 ,
.Xr vnconfig 8
.Sh HISTORY
A
.Nm
Expand Down
66 changes: 61 additions & 5 deletions sbin/umount/umount.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,18 @@
*/

#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/vnioctl.h>

#include <netdb.h>
#include <rpc/rpc.h>
#include <vfs/nfs/rpcv2.h>

#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <fstab.h>
#include <stdio.h>
#include <stdlib.h>
Expand All @@ -55,7 +59,7 @@ typedef enum { MNTON, MNTFROM, NOTHING } mntwhat;
typedef enum { MARK, UNMARK, NAME, COUNT, FREE } dowhat;

struct addrinfo *nfshost_ai = NULL;
int fflag, vflag;
int all, dflag, fflag, vflag;
char *nfshost;

void checkmntlist (char *, char **, char **, char **);
Expand All @@ -71,26 +75,30 @@ int umountall (char **);
int checkname (char *, char **);
int umountfs (char *, char *, char *);
void usage (void) __dead2;
int vn_detach (const char *);
int xdr_dir (XDR *, char *);

int
main(int argc, char *argv[])
{
int all, errs, ch, mntsize, error;
int errs, ch, mntsize, error;
char **typelist = NULL, *mntonname, *mntfromname;
char *type, *mntfromnamerev, *mntonnamerev;
struct statfs *mntbuf;
struct addrinfo hints;

all = errs = 0;
while ((ch = getopt(argc, argv, "AaF:fh:t:v")) != -1) {
while ((ch = getopt(argc, argv, "AadF:fh:t:v")) != -1) {
switch (ch) {
case 'A':
all = 2;
break;
case 'a':
all = 1;
break;
case 'd':
dflag = 1;
break;
case 'F':
setfstab(optarg);
break;
Expand Down Expand Up @@ -443,6 +451,13 @@ umountfs(char *mntfromname, char *mntonname, char *type)
}
if (vflag)
printf("%s: unmount from %s\n", mntfromname, mntonname);
if (dflag) {
if (vn_detach(mntfromname) != 0 && !all) {
warnx("detach of %s failed", mntfromname);
return (1);
}
}

/*
* Report to mountd-server which nfsname
* has been unmounted.
Expand Down Expand Up @@ -478,6 +493,47 @@ umountfs(char *mntfromname, char *mntonname, char *type)
auth_destroy(clp->cl_auth);
clnt_destroy(clp);
}

return (0);
}

int
vn_detach(const char *fromname)
{
struct vn_ioctl vnio;
char *p, device[MAXPATHLEN];
int fd;

if (strncmp(fromname, "/dev/vn", sizeof("/dev/vn") - 1) != 0) {
if (!all)
warnx("invalid vn device: %s", fromname);
return (-1);
}

/* Strip the slice/partition part (e.g., /dev/vn4s1a -> /dev/vn4) */
snprintf(device, sizeof(device), "%s", fromname);
p = device + sizeof("/dev/vn");
while (*p >= '0' && *p <= '9')
p++;
*p = '\0';

fd = open(device, O_RDONLY);
if (fd < 0) {
warn("open: %s", device);
return (-1);
}

memset(&vnio, 0, sizeof(vnio));
if (ioctl(fd, VNIOCDETACH, &vnio) < 0) {
warn("VNIOCDETACH: %s", device);
close(fd);
return (-1);
}

close(fd);
if (vflag)
printf("%s: detached\n", device);

return (0);
}

Expand Down Expand Up @@ -744,7 +800,7 @@ usage(void)
{

fprintf(stderr, "%s\n%s\n",
"usage: umount [-fv] special | node",
" umount -a | -A [-F fstab] [-fv] [-h host] [-t type]");
"usage: umount [-dfv] special | node",
" umount -a | -A [-F fstab] [-dfv] [-h host] [-t type]");
exit(1);
}

0 comments on commit ce0bf05

Please sign in to comment.