aboutsummaryrefslogtreecommitdiff
path: root/cddl/contrib/opensolaris
diff options
context:
space:
mode:
authorAndriy Gapon <avg@FreeBSD.org>2019-10-03 11:08:45 +0000
committerAndriy Gapon <avg@FreeBSD.org>2019-10-03 11:08:45 +0000
commit912c3fe7157d22ee244e266c017287242cd8081c (patch)
tree65d320149156a4d1a9791e9de255926af13eda33 /cddl/contrib/opensolaris
parentd60ac9d5610cdf34b52795f0a7eec69e83e2e167 (diff)
downloadsrc-912c3fe7157d22ee244e266c017287242cd8081c.tar.gz
src-912c3fe7157d22ee244e266c017287242cd8081c.zip
ZFS: add bookmark renaming
The feature is implemented as an extension of the existing ZFS_IOC_RENAME ioctl. Both the userland and the DSL interfaces support renaming only a single bookmark at a time. As of now, there is no ZCP interface to the new functionality. I am going to add it once the DSL interface passes a test of time. This change picks up support for zfs_ioc_namecheck_t::ENTITY_NAME that was added to ZoL as part of Redacted Send/Receive feature by Paul Dagnelie <pcd@delphix.com>. This is needed to allow a bookmark name in zc_name. Discussed with: mahrens Reviewed by: bcr (man page) Sponsored by: CyberSecure Differential Revision: https://reviews.freebsd.org/D21795
Notes
Notes: svn path=/head/; revision=353037
Diffstat (limited to 'cddl/contrib/opensolaris')
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs.813
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs_main.c17
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c30
3 files changed, 46 insertions, 14 deletions
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 b/cddl/contrib/opensolaris/cmd/zfs/zfs.8
index 84f13273af22..9ede617b01bc 100644
--- a/cddl/contrib/opensolaris/cmd/zfs/zfs.8
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs.8
@@ -105,6 +105,9 @@
.Ar snapshot snapshot
.Nm
.Cm rename
+.Ar bookmark bookmark
+.Nm
+.Cm rename
.Fl u
.Op Fl p
.Ar filesystem filesystem
@@ -2094,6 +2097,16 @@ Recursively rename the snapshots of all descendent datasets. Snapshots are the
only dataset that can be renamed recursively.
.It Xo
.Nm
+.Cm rename
+.Ar bookmark bookmark
+.Xc
+.Pp
+Renames the given bookmark.
+Bookmarks can only be renamed within the parent file system or volume.
+When renaming a bookmark, the parent file system or volume of the bookmark
+does not need to be specified as part of the second argument.
+.It Xo
+.Nm
.Cm list
.Op Fl r Ns | Ns Fl d Ar depth
.Op Fl Hp
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
index bb5a2a94ccc0..c2f9f9548ca3 100644
--- a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
@@ -284,6 +284,7 @@ get_usage(zfs_help_t idx)
"<filesystem|volume|snapshot>\n"
"\trename [-f] -p <filesystem|volume> <filesystem|volume>\n"
"\trename -r <snapshot> <snapshot>\n"
+ "\trename <bookmark> <bookmark>\n"
"\trename -u [-p] <filesystem> <filesystem>"));
case HELP_ROLLBACK:
return (gettext("\trollback [-rRf] <snapshot>\n"));
@@ -3254,6 +3255,7 @@ zfs_do_list(int argc, char **argv)
* zfs rename [-f] <fs | snap | vol> <fs | snap | vol>
* zfs rename [-f] -p <fs | vol> <fs | vol>
* zfs rename -r <snap> <snap>
+ * zfs rename <bmark> <bmark>
* zfs rename -u [-p] <fs> <fs>
*
* Renames the given dataset to another of the same type.
@@ -3270,6 +3272,7 @@ zfs_do_rename(int argc, char **argv)
int ret = 0;
int types;
boolean_t parents = B_FALSE;
+ boolean_t bookmarks = B_FALSE;
char *snapshot = NULL;
/* check options */
@@ -3320,7 +3323,7 @@ zfs_do_rename(int argc, char **argv)
usage(B_FALSE);
}
- if (flags.recurse && strchr(argv[0], '@') == 0) {
+ if (flags.recurse && strchr(argv[0], '@') == NULL) {
(void) fprintf(stderr, gettext("source dataset for recursive "
"rename must be a snapshot\n"));
usage(B_FALSE);
@@ -3332,10 +3335,22 @@ zfs_do_rename(int argc, char **argv)
usage(B_FALSE);
}
+ if (strchr(argv[0], '#') != NULL)
+ bookmarks = B_TRUE;
+
+ if (bookmarks && (flags.nounmount || flags.recurse ||
+ flags.forceunmount || parents)) {
+ (void) fprintf(stderr, gettext("options are not supported "
+ "for renaming bookmarks\n"));
+ usage(B_FALSE);
+ }
+
if (flags.nounmount)
types = ZFS_TYPE_FILESYSTEM;
else if (parents)
types = ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME;
+ else if (bookmarks)
+ types = ZFS_TYPE_BOOKMARK;
else
types = ZFS_TYPE_DATASET;
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
index 1d344b1f6f71..76a71f39d987 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
@@ -4291,17 +4291,18 @@ zfs_rename(zfs_handle_t *zhp, const char *source, const char *target,
/*
* Make sure the target name is valid
*/
- if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
- if ((strchr(target, '@') == NULL) ||
- *target == '@') {
+ if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT ||
+ zhp->zfs_type == ZFS_TYPE_BOOKMARK) {
+ const char sep = zhp->zfs_type == ZFS_TYPE_SNAPSHOT ? '@' : '#';
+
+ if ((strchr(target, sep) == NULL) || *target == sep) {
/*
* Snapshot target name is abbreviated,
* reconstruct full dataset name
*/
- (void) strlcpy(parent, zhp->zfs_name,
- sizeof (parent));
- delim = strchr(parent, '@');
- if (strchr(target, '@') == NULL)
+ (void) strlcpy(parent, zhp->zfs_name, sizeof (parent));
+ delim = strchr(parent, sep);
+ if (strchr(target, sep) == NULL)
*(++delim) = '\0';
else
*delim = '\0';
@@ -4311,12 +4312,13 @@ zfs_rename(zfs_handle_t *zhp, const char *source, const char *target,
/*
* Make sure we're renaming within the same dataset.
*/
- delim = strchr(target, '@');
+ delim = strchr(target, sep);
if (strncmp(zhp->zfs_name, target, delim - target)
- != 0 || zhp->zfs_name[delim - target] != '@') {
+ != 0 || zhp->zfs_name[delim - target] != sep) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "snapshots must be part of same "
- "dataset"));
+ "%s must be part of same dataset"),
+ zhp->zfs_type == ZFS_TYPE_SNAPSHOT ?
+ "snapshots" : "bookmarks");
return (zfs_error(hdl, EZFS_CROSSTARGET,
errbuf));
}
@@ -4379,7 +4381,6 @@ zfs_rename(zfs_handle_t *zhp, const char *source, const char *target,
flags.nounmount = B_TRUE;
}
if (flags.recurse) {
-
parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
if (parentname == NULL) {
ret = -1;
@@ -4392,7 +4393,8 @@ zfs_rename(zfs_handle_t *zhp, const char *source, const char *target,
ret = -1;
goto error;
}
- } else if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT) {
+ } else if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT &&
+ zhp->zfs_type != ZFS_TYPE_BOOKMARK) {
if ((cl = changelist_gather(zhp, ZFS_PROP_NAME,
flags.nounmount ? CL_GATHER_DONT_UNMOUNT : 0,
flags.forceunmount ? MS_FORCE : 0)) == NULL) {
@@ -4437,6 +4439,8 @@ zfs_rename(zfs_handle_t *zhp, const char *source, const char *target,
"a child dataset already has a snapshot "
"with the new name"));
(void) zfs_error(hdl, EZFS_EXISTS, errbuf);
+ } else if (errno == EINVAL) {
+ (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
} else {
(void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf);
}