mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
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:
committed by
Brian Behlendorf
parent
eff7d78f8a
commit
dc1c630b8a
+13
-11
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user