svn commit: r359808 - in head/cddl/contrib/opensolaris: cmd/zfs lib/libzfs/common

Mariusz Zaborski oshogbo at FreeBSD.org
Sat Apr 11 17:54:36 UTC 2020


Author: oshogbo
Date: Sat Apr 11 17:54:35 2020
New Revision: 359808
URL: https://svnweb.freebsd.org/changeset/base/359808

Log:
  zfs: Add option for forcible unmounting dataset while receiving snapshot.
  
  Currently when the dataset is in use we can't receive snapshots.
  
  zfs send test/1 at asd | zfs recv -FM test/2
  cannot unmount '/test/2': Device busy
  
  This commits add option 'M' which attempts to forcibly unmount the
  dataset.  Thanks to this we can enforce receiving snapshots in a
  single step.
  
  Note that this functionality is not supported on Linux because the
  VFS will prevent active mounted filesystems from being unmounted,
  even with the force option.  This is the intended VFS behavior.
  
  Discussed-with: Pawel Jakub Dawidek <pjd at FreeBSD.org>
  Reviewed-by: Ryan Moeller <ryan at iXsystems.com>
  Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
  Reviewed-by: Allan Jude <allanjude at freebsd.org>
  Differential Revision:	https://reviews.freebsd.org/D22306
  
  openzfs/zfs at a57d3d45d6efdff935421e2ef3f97e3dc089d93d

Modified:
  head/cddl/contrib/opensolaris/cmd/zfs/zfs.8
  head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
  head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
  head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c

Modified: head/cddl/contrib/opensolaris/cmd/zfs/zfs.8
==============================================================================
--- head/cddl/contrib/opensolaris/cmd/zfs/zfs.8	Sat Apr 11 17:30:33 2020	(r359807)
+++ head/cddl/contrib/opensolaris/cmd/zfs/zfs.8	Sat Apr 11 17:54:35 2020	(r359808)
@@ -32,7 +32,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd October 16, 2019
+.Dd February 16, 2020
 .Dt ZFS 8
 .Os
 .Sh NAME
@@ -201,12 +201,12 @@
 .Fl t Ar receive_resume_token
 .Nm
 .Cm receive Ns | Ns Cm recv
-.Op Fl vnsFu
+.Op Fl vnsFMu
 .Op Fl o Sy origin Ns = Ns Ar snapshot
 .Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
 .Nm
 .Cm receive Ns | Ns Cm recv
-.Op Fl vnsFu
+.Op Fl vnsFMu
 .Op Fl d | e
 .Op Fl o Sy origin Ns = Ns Ar snapshot
 .Ar filesystem
@@ -2909,14 +2909,14 @@ for more details.
 .It Xo
 .Nm
 .Cm receive Ns | Ns Cm recv
-.Op Fl vnsFu
+.Op Fl vnsFMu
 .Op Fl o Sy origin Ns = Ns Ar snapshot
 .Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
 .Xc
 .It Xo
 .Nm
 .Cm receive Ns | Ns Cm recv
-.Op Fl vnsFu
+.Op Fl vnsFMu
 .Op Fl d | e
 .Op Fl o Sy origin Ns = Ns Ar snapshot
 .Ar filesystem
@@ -3016,6 +3016,9 @@ performing the receive operation. If receiving an incr
 stream (for example, one generated by
 .Qq Nm Cm send Fl R Bro Fl i | Fl I Brc ) ,
 destroy snapshots and file systems that do not exist on the sending side.
+.It Fl M
+Force an unmount of the file system while receiving a snapshot.
+This option is not supported on Linux.
 .It Fl s
 If the receive is interrupted, save the partially received state, rather
 than deleting it.  Interruption may be due to premature termination of

Modified: head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
==============================================================================
--- head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c	Sat Apr 11 17:30:33 2020	(r359807)
+++ head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c	Sat Apr 11 17:54:35 2020	(r359808)
@@ -274,9 +274,9 @@ get_usage(zfs_help_t idx)
 	case HELP_PROMOTE:
 		return (gettext("\tpromote <clone-filesystem>\n"));
 	case HELP_RECEIVE:
-		return (gettext("\treceive|recv [-vnsFu] <filesystem|volume|"
+		return (gettext("\treceive|recv [-vnsFMu] <filesystem|volume|"
 		    "snapshot>\n"
-		    "\treceive|recv [-vnsFu] [-o origin=<snapshot>] [-d | -e] "
+		    "\treceive|recv [-vnsFMu] [-o origin=<snapshot>] [-d | -e] "
 		    "<filesystem>\n"
 		    "\treceive|recv -A <filesystem|volume>\n"));
 	case HELP_RENAME:
@@ -4078,7 +4078,7 @@ zfs_do_receive(int argc, char **argv)
 		nomem();
 
 	/* check options */
-	while ((c = getopt(argc, argv, ":o:denuvFsA")) != -1) {
+	while ((c = getopt(argc, argv, ":o:denuvMFsA")) != -1) {
 		switch (c) {
 		case 'o':
 			if (parseprop(props, optarg) != 0)
@@ -4105,6 +4105,9 @@ zfs_do_receive(int argc, char **argv)
 			break;
 		case 'F':
 			flags.force = B_TRUE;
+			break;
+		case 'M':
+			flags.forceunmount = B_TRUE;
 			break;
 		case 'A':
 			abort_resumable = B_TRUE;

Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h	Sat Apr 11 17:30:33 2020	(r359807)
+++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h	Sat Apr 11 17:54:35 2020	(r359808)
@@ -737,6 +737,9 @@ typedef struct recvflags {
 
 	/* do not mount file systems as they are extracted (private) */
 	boolean_t nomount;
+
+	/* force unmount while recv snapshot (private) */
+	boolean_t forceunmount;
 } recvflags_t;
 
 extern int zfs_receive(libzfs_handle_t *, const char *, nvlist_t *,

Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c	Sat Apr 11 17:30:33 2020	(r359807)
+++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c	Sat Apr 11 17:54:35 2020	(r359808)
@@ -2913,7 +2913,8 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, cons
 				    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 |=
@@ -3435,7 +3436,8 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const 
 		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);
 				zcmd_free_nvlists(&zc);
@@ -3881,6 +3883,7 @@ zfs_receive(libzfs_handle_t *hdl, const char *tosnap, 
 	int cleanup_fd;
 	uint64_t action_handle = 0;
 	char *originsnap = NULL;
+
 	if (props) {
 		err = nvlist_lookup_string(props, "origin", &originsnap);
 		if (err && err != ENOENT)
@@ -3902,7 +3905,8 @@ zfs_receive(libzfs_handle_t *hdl, const char *tosnap, 
 		zhp = zfs_open(hdl, top_zfs, ZFS_TYPE_FILESYSTEM);
 		if (zhp != NULL) {
 			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) {
 				/* mount and share received datasets */


More information about the svn-src-head mailing list