summaryrefslogtreecommitdiffstats
path: root/cddl
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2011-10-24 21:14:50 +0000
committerpjd <pjd@FreeBSD.org>2011-10-24 21:14:50 +0000
commit7f814b700d8ebd9d427f04ce0902705af1a9d625 (patch)
treec72e3c411813edfc145bedbe98797b87d21b108f /cddl
parent036925291ef871d3375f7b7d4b0331d461df82a3 (diff)
downloadFreeBSD-src-7f814b700d8ebd9d427f04ce0902705af1a9d625.zip
FreeBSD-src-7f814b700d8ebd9d427f04ce0902705af1a9d625.tar.gz
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
Diffstat (limited to 'cddl')
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs.820
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs_main.c38
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h11
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c11
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c35
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h6
6 files changed, 87 insertions, 34 deletions
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 b/cddl/contrib/opensolaris/cmd/zfs/zfs.8
index e30b4b2..03deef2 100644
--- a/cddl/contrib/opensolaris/cmd/zfs/zfs.8
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs.8
@@ -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 snapshots previous to this snapshot, are n
.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 target can be located anywhere in the \fBZFS\
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
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
index bc5a662..1f51bc2 100644
--- a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
@@ -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);
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
index 1077958..1f226b5 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
@@ -518,7 +518,16 @@ extern int zfs_destroy_snaps(zfs_handle_t *, char *, boolean_t);
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) */
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c
index 8f222a9..46179d6 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c
@@ -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 *clp)
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 *clp)
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) &&
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
index bdd48b1..976d7e9 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
@@ -3480,7 +3480,7 @@ zfs_iter_dependents(zfs_handle_t *zhp, boolean_t allowrecursion,
* 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 *target, boolean_t recursive)
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 *target, boolean_t recursive)
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 *target, boolean_t recursive)
} 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 *target, boolean_t recursive)
(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 *target, boolean_t recursive)
(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 *target, boolean_t recursive)
* 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);
}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
index db4aca7..e52a649 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
@@ -160,11 +160,9 @@ int zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp,
*/
#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;
OpenPOWER on IntegriCloud