Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Oct 2011 21:14:50 +0000 (UTC)
From:      Pawel Jakub Dawidek <pjd@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r226705 - in head/cddl/contrib/opensolaris: cmd/zfs lib/libzfs/common
Message-ID:  <201110242114.p9OLEp4Q063177@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pjd
Date: Mon Oct 24 21:14:50 2011
New Revision: 226705
URL: http://svn.freebsd.org/changeset/base/226705

Log:
  Extend r226676 to allow rename without unmount even for file systems with
  non-legacy mountpoints. It is better to be able to rename such file systems and
  let them be mounted in old places until next reboot than using live CD, etc. to
  rename with remount.
  
  This is implemented by adding -u option to 'zfs rename'. If file system's
  mountpoint property is set to 'legacy' or 'none', there is no need to specify -u.
  
  Update zfs(8) manual page to reflect this addition.
  
  MFC after:	2 weeks

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_changelist.c
  head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
  head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h

Modified: head/cddl/contrib/opensolaris/cmd/zfs/zfs.8
==============================================================================
--- head/cddl/contrib/opensolaris/cmd/zfs/zfs.8	Mon Oct 24 21:01:20 2011	(r226704)
+++ head/cddl/contrib/opensolaris/cmd/zfs/zfs.8	Mon Oct 24 21:14:50 2011	(r226705)
@@ -76,6 +76,11 @@ zfs \- configures ZFS file systems
 
 .LP
 .nf
+\fBzfs\fR \fBrename\fR \fB-u\fR [\fB-p\fR] \fIfilesystem\fR \fIfilesystem\fR
+.fi
+
+.LP
+.nf
 \fBzfs\fR \fBlist\fR [\fB-r\fR|\fB-d\fR \fIdepth\fR][\fB-H\fR][\fB-o\fR \fIproperty\fR[,...]] [\fB-t\fR \fItype\fR[,...]]
      [\fB-s\fR \fIproperty\fR] ... [\fB-S\fR \fIproperty\fR] ... [\fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR] ...
 .fi
@@ -1479,6 +1484,10 @@ The snapshot that was cloned, and any sn
 .na
 \fB\fBzfs rename\fR [\fB-p\fR] \fIfilesystem\fR|\fIvolume\fR \fIfilesystem\fR|\fIvolume\fR\fR
 .ad
+.br
+.na
+\fB\fBzfs rename\fR \fB-u\fR [\fB-p\fR] \fIfilesystem\fR \fIfilesystem\fR\fR
+.ad
 .sp .6
 .RS 4n
 Renames the given dataset. The new target can be located anywhere in the \fBZFS\fR hierarchy, with the exception of snapshots. Snapshots can only be renamed within the parent file system or volume. When renaming a snapshot, the parent file system of the snapshot does not need to be specified as part of the second argument. Renamed file systems can inherit new mount points, in which case they are unmounted and remounted at the new mount point.
@@ -1493,6 +1502,17 @@ Renames the given dataset. The new targe
 Creates all the nonexistent parent datasets. Datasets created in this manner are automatically mounted according to the \fBmountpoint\fR property inherited from their parent.
 .RE
 
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-u\fR\fR
+.ad
+.sp .6
+.RS 4n
+Do not remount file systems during rename. If a file system's \fBmountpoint\fR property is set to \fBlegacy\fR or \fBnone\fR, file system is not unmounted even if this option is not given.
+.RE
+
 .RE
 
 .sp

Modified: head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
==============================================================================
--- head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c	Mon Oct 24 21:01:20 2011	(r226704)
+++ head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c	Mon Oct 24 21:14:50 2011	(r226705)
@@ -253,7 +253,8 @@ get_usage(zfs_help_t idx)
 		return (gettext("\trename <filesystem|volume|snapshot> "
 		    "<filesystem|volume|snapshot>\n"
 		    "\trename -p <filesystem|volume> <filesystem|volume>\n"
-		    "\trename -r <snapshot> <snapshot>"));
+		    "\trename -r <snapshot> <snapshot>\n"
+		    "\trename -u [-p] <filesystem> <filesystem>"));
 	case HELP_ROLLBACK:
 		return (gettext("\trollback [-rRf] <snapshot>\n"));
 	case HELP_SEND:
@@ -2851,6 +2852,7 @@ zfs_do_list(int argc, char **argv)
  * zfs rename <fs | snap | vol> <fs | snap | vol>
  * zfs rename -p <fs | vol> <fs | vol>
  * zfs rename -r <snap> <snap>
+ * zfs rename -u [-p] <fs> <fs>
  *
  * Renames the given dataset to another of the same type.
  *
@@ -2861,19 +2863,21 @@ static int
 zfs_do_rename(int argc, char **argv)
 {
 	zfs_handle_t *zhp;
-	int c;
-	int ret;
-	boolean_t recurse = B_FALSE;
+	renameflags_t flags = { 0 };
+	int c, ret, types;
 	boolean_t parents = B_FALSE;
 
 	/* check options */
-	while ((c = getopt(argc, argv, "pr")) != -1) {
+	while ((c = getopt(argc, argv, "pru")) != -1) {
 		switch (c) {
 		case 'p':
 			parents = B_TRUE;
 			break;
 		case 'r':
-			recurse = B_TRUE;
+			flags.recurse = B_TRUE;
+			break;
+		case 'u':
+			flags.nounmount = B_TRUE;
 			break;
 		case '?':
 		default:
@@ -2902,20 +2906,32 @@ zfs_do_rename(int argc, char **argv)
 		usage(B_FALSE);
 	}
 
-	if (recurse && parents) {
+	if (flags.recurse && parents) {
 		(void) fprintf(stderr, gettext("-p and -r options are mutually "
 		    "exclusive\n"));
 		usage(B_FALSE);
 	}
 
-	if (recurse && strchr(argv[0], '@') == 0) {
+	if (flags.recurse && strchr(argv[0], '@') == 0) {
 		(void) fprintf(stderr, gettext("source dataset for recursive "
 		    "rename must be a snapshot\n"));
 		usage(B_FALSE);
 	}
 
-	if ((zhp = zfs_open(g_zfs, argv[0], parents ? ZFS_TYPE_FILESYSTEM |
-	    ZFS_TYPE_VOLUME : ZFS_TYPE_DATASET)) == NULL)
+	if (flags.nounmount && parents) {
+		(void) fprintf(stderr, gettext("-u and -r options are mutually "
+		    "exclusive\n"));
+		usage(B_FALSE);
+	}
+
+	if (flags.nounmount)
+		types = ZFS_TYPE_FILESYSTEM;
+	else if (parents)
+		types = ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME;
+	else
+		types = ZFS_TYPE_DATASET;
+
+	if ((zhp = zfs_open(g_zfs, argv[0], types)) == NULL)
 		return (1);
 
 	/* If we were asked and the name looks good, try to create ancestors. */
@@ -2925,7 +2941,7 @@ zfs_do_rename(int argc, char **argv)
 		return (1);
 	}
 
-	ret = (zfs_rename(zhp, argv[1], recurse) != 0);
+	ret = (zfs_rename(zhp, argv[1], flags) != 0);
 
 	zfs_close(zhp);
 	return (ret);

Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h	Mon Oct 24 21:01:20 2011	(r226704)
+++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h	Mon Oct 24 21:14:50 2011	(r226705)
@@ -518,7 +518,16 @@ extern int zfs_destroy_snaps(zfs_handle_
 extern int zfs_clone(zfs_handle_t *, const char *, nvlist_t *);
 extern int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t, nvlist_t *);
 extern int zfs_rollback(zfs_handle_t *, zfs_handle_t *, boolean_t);
-extern int zfs_rename(zfs_handle_t *, const char *, boolean_t);
+
+typedef struct renameflags {
+	/* recursive rename */
+	int recurse : 1;
+
+	/* don't unmount file systems */
+	int nounmount : 1;
+} renameflags_t;
+
+extern int zfs_rename(zfs_handle_t *, const char *, renameflags_t flags);
 
 typedef struct sendflags {
 	/* print informational messages (ie, -v was specified) */

Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c	Mon Oct 24 21:01:20 2011	(r226704)
+++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c	Mon Oct 24 21:14:50 2011	(r226705)
@@ -122,10 +122,8 @@ changelist_prefix(prop_changelist_t *clp
 			 */
 			switch (clp->cl_prop) {
 			case ZFS_PROP_MOUNTPOINT:
-				if (clp->cl_waslegacy &&
-				    (clp->cl_gflags & CL_GATHER_KEEP_LEGACY)) {
+				if (clp->cl_gflags & CL_GATHER_DONT_UNMOUNT)
 					break;
-				}
 				if (zfs_unmount(cn->cn_handle, NULL,
 				    clp->cl_mflags) != 0) {
 					ret = -1;
@@ -172,8 +170,10 @@ changelist_postfix(prop_changelist_t *cl
 	if ((cn = uu_list_last(clp->cl_list)) == NULL)
 		return (0);
 
-	if (clp->cl_prop == ZFS_PROP_MOUNTPOINT)
+	if (clp->cl_prop == ZFS_PROP_MOUNTPOINT &&
+	    !(clp->cl_gflags & CL_GATHER_DONT_UNMOUNT)) {
 		remove_mountpoint(cn->cn_handle);
+	}
 
 	/*
 	 * It is possible that the changelist_prefix() used libshare
@@ -228,7 +228,8 @@ changelist_postfix(prop_changelist_t *cl
 		    shareopts, sizeof (shareopts), NULL, NULL, 0,
 		    B_FALSE) == 0) && (strcmp(shareopts, "off") != 0));
 
-		mounted = zfs_is_mounted(cn->cn_handle, NULL);
+		mounted = (clp->cl_gflags & CL_GATHER_DONT_UNMOUNT) ||
+		    zfs_is_mounted(cn->cn_handle, NULL);
 
 		if (!mounted && (cn->cn_mounted ||
 		    ((sharenfs || sharesmb || clp->cl_waslegacy) &&

Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c	Mon Oct 24 21:01:20 2011	(r226704)
+++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c	Mon Oct 24 21:14:50 2011	(r226705)
@@ -3480,7 +3480,7 @@ zfs_iter_dependents(zfs_handle_t *zhp, b
  * Renames the given dataset.
  */
 int
-zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive)
+zfs_rename(zfs_handle_t *zhp, const char *target, renameflags_t flags)
 {
 	int ret;
 	zfs_cmd_t zc = { 0 };
@@ -3536,7 +3536,7 @@ zfs_rename(zfs_handle_t *zhp, const char
 		if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
 			return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
 	} else {
-		if (recursive) {
+		if (flags.recurse) {
 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 			    "recursive rename must be a snapshot"));
 			return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
@@ -3577,7 +3577,20 @@ zfs_rename(zfs_handle_t *zhp, const char
 		return (zfs_error(hdl, EZFS_ZONED, errbuf));
 	}
 
-	if (recursive) {
+	/*
+	 * Avoid unmounting file systems with mountpoint property set to
+	 * 'legacy' or 'none' even if -u option is not given.
+	 */
+	if (zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
+	    !flags.recurse && !flags.nounmount &&
+	    zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, property,
+	    sizeof (property), NULL, NULL, 0, B_FALSE) == 0 &&
+	    (strcmp(property, "legacy") == 0 ||
+	     strcmp(property, "none") == 0)) {
+		flags.nounmount = B_TRUE;
+	}
+
+	if (flags.recurse) {
 
 		parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
 		if (parentname == NULL) {
@@ -3594,7 +3607,7 @@ zfs_rename(zfs_handle_t *zhp, const char
 
 	} else {
 		if ((cl = changelist_gather(zhp, ZFS_PROP_NAME,
-		    CL_GATHER_KEEP_LEGACY, 0)) == NULL) {
+		    flags.nounmount ? CL_GATHER_DONT_UNMOUNT : 0, 0)) == NULL) {
 			return (-1);
 		}
 
@@ -3618,13 +3631,9 @@ zfs_rename(zfs_handle_t *zhp, const char
 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
 	(void) strlcpy(zc.zc_value, target, sizeof (zc.zc_value));
 
-	zc.zc_cookie = recursive ? 1 : 0;
-	if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, property, sizeof (property),
-	    NULL, NULL, 0, B_FALSE) == 0 &&
-	    (strcmp(property, "legacy") == 0 ||
-	     strcmp(property, "none") == 0)) {
+	zc.zc_cookie = flags.recurse ? 1 : 0;
+	if (flags.nounmount)
 		zc.zc_cookie |= 2;
-	}
 
 	if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_RENAME, &zc)) != 0) {
 		/*
@@ -3634,7 +3643,7 @@ zfs_rename(zfs_handle_t *zhp, const char
 		(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
 		    "cannot rename '%s'"), zc.zc_name);
 
-		if (recursive && errno == EEXIST) {
+		if (flags.recurse && errno == EEXIST) {
 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 			    "a child dataset already has a snapshot "
 			    "with the new name"));
@@ -3647,10 +3656,10 @@ zfs_rename(zfs_handle_t *zhp, const char
 		 * On failure, we still want to remount any filesystems that
 		 * were previously mounted, so we don't alter the system state.
 		 */
-		if (!recursive)
+		if (!flags.recurse)
 			(void) changelist_postfix(cl);
 	} else {
-		if (!recursive) {
+		if (!flags.recurse) {
 			changelist_rename(cl, zfs_get_name(zhp), target);
 			ret = changelist_postfix(cl);
 		}

Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h	Mon Oct 24 21:01:20 2011	(r226704)
+++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h	Mon Oct 24 21:14:50 2011	(r226705)
@@ -160,11 +160,9 @@ int zprop_expand_list(libzfs_handle_t *h
  */
 #define	CL_GATHER_MOUNT_ALWAYS	0x01
 /*
- * Use this changelist_gather() flag to prevent unmounting of legacy
- * file systems. Useful when renaming legacy file systems, where there is
- * no need to unmount them.
+ * Use this changelist_gather() flag to prevent unmounting of file systems.
  */
-#define	CL_GATHER_KEEP_LEGACY	0x02
+#define	CL_GATHER_DONT_UNMOUNT	0x02
 
 typedef struct prop_changelist prop_changelist_t;
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110242114.p9OLEp4Q063177>