diff options
author | Andriy Gapon <avg@FreeBSD.org> | 2019-10-03 11:08:45 +0000 |
---|---|---|
committer | Andriy Gapon <avg@FreeBSD.org> | 2019-10-03 11:08:45 +0000 |
commit | 912c3fe7157d22ee244e266c017287242cd8081c (patch) | |
tree | 65d320149156a4d1a9791e9de255926af13eda33 /cddl/contrib/opensolaris | |
parent | d60ac9d5610cdf34b52795f0a7eec69e83e2e167 (diff) | |
download | src-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.8 | 13 | ||||
-rw-r--r-- | cddl/contrib/opensolaris/cmd/zfs/zfs_main.c | 17 | ||||
-rw-r--r-- | cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c | 30 |
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); } |