Skip to content

Commit

Permalink
zfs: add option for forcible unmounting dataset while receiving snaps…
Browse files Browse the repository at this point in the history
…hot.

Currently when the dataset is in use we can't receive snapshot.
zfs send test/1@asd | zfs recv -FM test/2
cannot unmount '/test/2': Device busy

The same goes for the Linux version:
oshogbo@u-wing:/test$ sudo sudo zfs send test/1@b | sudo zfs recv -F test/2
umount: /test/2: target is busy.
cannot unmount '/test/2': umount failed
oshogbo@u-wing:/test$ uname -a
Linux u-wing 4.18.0-25-generic openzfs#26-Ubuntu SMP Mon Jun 24 09:32:08 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

This commits add option 'M' which forcible unmounting the dataset.
Thanks to to that we can enforce receiving snapshot in single step.

Discussed with: pjd
Reviewed by:	AllanJude (FreeBSD version)
FreeBSD review:	https://reviews.freebsd.org/D22306

Signed-off-by: Mariusz Zaborski <oshogbo@vexillium.org>
  • Loading branch information
oshogbo committed Feb 16, 2020
1 parent a340316 commit 23dcedd
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 11 deletions.
9 changes: 6 additions & 3 deletions cmd/zfs/zfs_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,10 @@ get_usage(zfs_help_t idx)
case HELP_PROMOTE:
return (gettext("\tpromote <clone-filesystem>\n"));
case HELP_RECEIVE:
return (gettext("\treceive [-vnsFhu] "
return (gettext("\treceive [-vMnsFhu] "
"[-o <property>=<value>] ... [-x <property>] ...\n"
"\t <filesystem|volume|snapshot>\n"
"\treceive [-vnsFhu] [-o <property>=<value>] ... "
"\treceive [-vMnsFhu] [-o <property>=<value>] ... "
"[-x <property>] ... \n"
"\t [-d | -e] <filesystem>\n"
"\treceive -A <filesystem|volume>\n"));
Expand Down Expand Up @@ -4550,7 +4550,7 @@ zfs_do_receive(int argc, char **argv)
nomem();

/* check options */
while ((c = getopt(argc, argv, ":o:x:dehnuvFsA")) != -1) {
while ((c = getopt(argc, argv, ":o:x:dehMnuvFsA")) != -1) {
switch (c) {
case 'o':
if (!parseprop(props, optarg)) {
Expand Down Expand Up @@ -4585,6 +4585,9 @@ zfs_do_receive(int argc, char **argv)
case 'h':
flags.skipholds = B_TRUE;
break;
case 'M':
flags.forceunmount = B_TRUE;
break;
case 'n':
flags.dryrun = B_TRUE;
break;
Expand Down
3 changes: 3 additions & 0 deletions include/libzfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,9 @@ typedef struct recvflags {

/* mount the filesystem unless nomount is specified */
boolean_t domount;

/* force unmount while recv snapshot (private) */
boolean_t forceunmount;
} recvflags_t;

extern int zfs_receive(libzfs_handle_t *, const char *, nvlist_t *,
Expand Down
9 changes: 6 additions & 3 deletions lib/libzfs/libzfs_sendrecv.c
Original file line number Diff line number Diff line change
Expand Up @@ -4059,7 +4059,8 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
ZFS_TYPE_FILESYSTEM);
if (zhp != NULL) {
clp = changelist_gather(zhp,
ZFS_PROP_MOUNTPOINT, 0, 0);
ZFS_PROP_MOUNTPOINT, 0,
flags->forceunmount ? MS_FORCE : 0);
zfs_close(zhp);
if (clp != NULL) {
softerr |=
Expand Down Expand Up @@ -4876,7 +4877,8 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
if (!flags->dryrun && zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
stream_wantsnewfs) {
/* We can't do online recv in this case */
clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 0);
clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
flags->forceunmount ? MS_FORCE : 0);
if (clp == NULL) {
zfs_close(zhp);
err = -1;
Expand Down Expand Up @@ -5556,7 +5558,8 @@ zfs_receive(libzfs_handle_t *hdl, const char *tosnap, nvlist_t *props,
}

clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT,
CL_GATHER_MOUNT_ALWAYS, 0);
CL_GATHER_MOUNT_ALWAYS,
flags->forceunmount ? MS_FORCE : 0);
zfs_close(zhp);
if (clp == NULL) {
err = -1;
Expand Down
12 changes: 7 additions & 5 deletions man/man8/zfs-receive.8
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
.\" Copyright 2018 Nexenta Systems, Inc.
.\" Copyright 2019 Joyent, Inc.
.\"
.Dd June 30, 2019
.Dd January 27, 2020
.Dt ZFS-RECEIVE 8
.Os Linux
.Sh NAME
Expand All @@ -39,14 +39,14 @@
.Sh SYNOPSIS
.Nm
.Cm receive
.Op Fl Fhnsuv
.Op Fl FhMnsuv
.Op Fl o Sy origin Ns = Ns Ar snapshot
.Op Fl o Ar property Ns = Ns Ar value
.Op Fl x Ar property
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
.Nm
.Cm receive
.Op Fl Fhnsuv
.Op Fl FhMnsuv
.Op Fl d Ns | Ns Fl e
.Op Fl o Sy origin Ns = Ns Ar snapshot
.Op Fl o Ar property Ns = Ns Ar value
Expand All @@ -61,7 +61,7 @@
.It Xo
.Nm
.Cm receive
.Op Fl Fhnsuv
.Op Fl FhMnsuv
.Op Fl o Sy origin Ns = Ns Ar snapshot
.Op Fl o Ar property Ns = Ns Ar value
.Op Fl x Ar property
Expand All @@ -70,7 +70,7 @@
.It Xo
.Nm
.Cm receive
.Op Fl Fhnsuv
.Op Fl FhMnsuv
.Op Fl d Ns | Ns Fl e
.Op Fl o Sy origin Ns = Ns Ar snapshot
.Op Fl o Ar property Ns = Ns Ar value
Expand Down Expand Up @@ -229,6 +229,8 @@ that element to determine the name of the target file system for the new
snapshot as described in the paragraph above.
.It Fl h
Skip the receive of holds. There is no effect if holds are not sent.
.It Fl M
Force an unmount of the file system while receiving a snapshot.
.It Fl n
Do not actually receive the stream.
This can be useful in conjunction with the
Expand Down

0 comments on commit 23dcedd

Please sign in to comment.