OpenZFS 9630 - add lzc_rename and lzc_destroy to libzfs_core

Porting Notes:
* Additional changes to recv_rename_impl() were required due to
  encryption code not being merged in OpenZFS yet.
* libzfs_core python bindings (pyzfs) were updated to fully support
  both lzc_rename() and lzc_destroy()

Authored by: Andriy Gapon <avg@FreeBSD.org>
Reviewed by: Andy Stormont <astormont@racktopsystems.com>
Reviewed by: Matt Ahrens <matt@delphix.com>
Reviewed by: Serapheim Dimitropoulos <serapheim.dimitro@delphix.com>
Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
Approved by: Dan McDonald <danmcd@joyent.com>
Ported-by: loli10K <ezomori.nozomu@gmail.com>

OpenZFS-issue: https://www.illumos.org/issues/9630
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/049ba63
Closes #8207
This commit is contained in:
Andriy Gapon
2018-06-28 00:37:54 +03:00
committed by Brian Behlendorf
parent eff7d78f8a
commit dc1c630b8a
8 changed files with 81 additions and 51 deletions
+13 -11
View File
@@ -3856,32 +3856,34 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
int
zfs_destroy(zfs_handle_t *zhp, boolean_t defer)
{
zfs_cmd_t zc = {"\0"};
int error;
if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT && defer)
return (EINVAL);
if (zhp->zfs_type == ZFS_TYPE_BOOKMARK) {
nvlist_t *nv = fnvlist_alloc();
fnvlist_add_boolean(nv, zhp->zfs_name);
int error = lzc_destroy_bookmarks(nv, NULL);
error = lzc_destroy_bookmarks(nv, NULL);
fnvlist_free(nv);
if (error != 0) {
return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
return (zfs_standard_error_fmt(zhp->zfs_hdl, error,
dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
zhp->zfs_name));
}
return (0);
}
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
if (ZFS_IS_VOLUME(zhp)) {
zc.zc_objset_type = DMU_OST_ZVOL;
if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
nvlist_t *nv = fnvlist_alloc();
fnvlist_add_boolean(nv, zhp->zfs_name);
error = lzc_destroy_snaps(nv, defer, NULL);
fnvlist_free(nv);
} else {
zc.zc_objset_type = DMU_OST_ZFS;
error = lzc_destroy(zhp->zfs_name);
}
zc.zc_defer_destroy = defer;
if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY, &zc) != 0 &&
errno != ENOENT) {
if (error != 0 && error != ENOENT) {
return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
zhp->zfs_name));
+17 -23
View File
@@ -2294,7 +2294,7 @@ recv_open_grand_origin(zfs_handle_t *zhp)
}
static int
recv_rename_impl(zfs_handle_t *zhp, zfs_cmd_t *zc)
recv_rename_impl(zfs_handle_t *zhp, const char *name, const char *newname)
{
int err;
zfs_handle_t *ozhp = NULL;
@@ -2304,7 +2304,7 @@ recv_rename_impl(zfs_handle_t *zhp, zfs_cmd_t *zc)
* attempted to rename the dataset outside of its encryption root.
* Force the dataset to become an encryption root and try again.
*/
err = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_RENAME, &zc);
err = lzc_rename(name, newname);
if (err == EACCES) {
ozhp = recv_open_grand_origin(zhp);
if (ozhp == NULL) {
@@ -2317,7 +2317,7 @@ recv_rename_impl(zfs_handle_t *zhp, zfs_cmd_t *zc)
if (err != 0)
goto out;
err = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_RENAME, &zc);
err = lzc_rename(name, newname);
}
out:
@@ -2331,7 +2331,6 @@ recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
int baselen, char *newname, recvflags_t *flags)
{
static int seq;
zfs_cmd_t zc = {"\0"};
int err;
prop_changelist_t *clp = NULL;
zfs_handle_t *zhp = NULL;
@@ -2351,19 +2350,13 @@ recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
if (err)
goto out;
zc.zc_objset_type = DMU_OST_ZFS;
(void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
if (tryname) {
(void) strcpy(newname, tryname);
(void) strlcpy(zc.zc_value, tryname, sizeof (zc.zc_value));
if (flags->verbose) {
(void) printf("attempting rename %s to %s\n",
zc.zc_name, zc.zc_value);
name, newname);
}
err = recv_rename_impl(zhp, &zc);
err = recv_rename_impl(zhp, name, newname);
if (err == 0)
changelist_rename(clp, name, tryname);
} else {
@@ -2375,13 +2368,12 @@ recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
(void) snprintf(newname, ZFS_MAX_DATASET_NAME_LEN,
"%.*srecv-%u-%u", baselen, name, getpid(), seq);
(void) strlcpy(zc.zc_value, newname, sizeof (zc.zc_value));
if (flags->verbose) {
(void) printf("failed - trying rename %s to %s\n",
zc.zc_name, zc.zc_value);
name, newname);
}
err = recv_rename_impl(zhp, &zc);
err = recv_rename_impl(zhp, name, newname);
if (err == 0)
changelist_rename(clp, name, newname);
if (err && flags->verbose) {
@@ -2461,7 +2453,6 @@ static int
recv_destroy(libzfs_handle_t *hdl, const char *name, int baselen,
char *newname, recvflags_t *flags)
{
zfs_cmd_t zc = {"\0"};
int err = 0;
prop_changelist_t *clp;
zfs_handle_t *zhp;
@@ -2484,17 +2475,20 @@ recv_destroy(libzfs_handle_t *hdl, const char *name, int baselen,
if (err)
return (err);
zc.zc_objset_type = DMU_OST_ZFS;
zc.zc_defer_destroy = defer;
(void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
if (flags->verbose)
(void) printf("attempting destroy %s\n", zc.zc_name);
err = ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc);
(void) printf("attempting destroy %s\n", name);
if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
nvlist_t *nv = fnvlist_alloc();
fnvlist_add_boolean(nv, name);
err = lzc_destroy_snaps(nv, defer, NULL);
fnvlist_free(nv);
} else {
err = lzc_destroy(name);
}
if (err == 0) {
if (flags->verbose)
(void) printf("success\n");
changelist_remove(clp, zc.zc_name);
changelist_remove(clp, name);
}
(void) changelist_postfix(clp);
+24
View File
@@ -316,6 +316,30 @@ lzc_remap(const char *fsname)
return (error);
}
int
lzc_rename(const char *source, const char *target)
{
zfs_cmd_t zc = { "\0" };
int error;
ASSERT3S(g_refcount, >, 0);
VERIFY3S(g_fd, !=, -1);
(void) strlcpy(zc.zc_name, source, sizeof (zc.zc_name));
(void) strlcpy(zc.zc_value, target, sizeof (zc.zc_value));
error = ioctl(g_fd, ZFS_IOC_RENAME, &zc);
if (error != 0)
error = errno;
return (error);
}
int
lzc_destroy(const char *fsname)
{
int error;
nvlist_t *args = fnvlist_alloc();
error = lzc_ioctl(ZFS_IOC_DESTROY, fsname, args, NULL);
nvlist_free(args);
return (error);
}
/*
* Creates snapshots.
*