summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorAndriy Gapon <avg@FreeBSD.org>2018-06-28 00:37:54 +0300
committerDan McDonald <danmcd@joyent.com>2018-12-07 16:34:34 -0500
commit049ba636fa37a2892809192fc671bff9158a01cd (patch)
treeaf20256dfd0e201c0043d6ded9df3c47a501990f /usr
parent37002877d7628586736855370376e9f6ec0d4704 (diff)
downloadillumos-joyent-049ba636fa37a2892809192fc671bff9158a01cd.tar.gz
9630 add lzc_rename and lzc_destroy to libzfs_core
Reviewed by: Andy Stormont <astormont@racktopsystems.com> Reviewed by: Matt Ahrens <matt@delphix.com> Reviewed by: Serapheim Dimitropoulos <serapheim.dimitro@delphix.com> Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr')
-rw-r--r--usr/src/lib/libzfs/common/libzfs_dataset.c24
-rw-r--r--usr/src/lib/libzfs/common/libzfs_sendrecv.c35
-rw-r--r--usr/src/lib/libzfs_core/common/libzfs_core.c28
-rw-r--r--usr/src/lib/libzfs_core/common/libzfs_core.h3
-rw-r--r--usr/src/lib/libzfs_core/common/mapfile-vers10
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_ioctl.c26
6 files changed, 87 insertions, 39 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c
index c0fd0cec32..980a1b7366 100644
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c
+++ b/usr/src/lib/libzfs/common/libzfs_dataset.c
@@ -3614,32 +3614,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));
diff --git a/usr/src/lib/libzfs/common/libzfs_sendrecv.c b/usr/src/lib/libzfs/common/libzfs_sendrecv.c
index d3002aec29..e56aa7f7c1 100644
--- a/usr/src/lib/libzfs/common/libzfs_sendrecv.c
+++ b/usr/src/lib/libzfs/common/libzfs_sendrecv.c
@@ -2133,7 +2133,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;
zfs_handle_t *zhp;
@@ -2150,19 +2149,13 @@ recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
if (err)
return (err);
- 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 = ioctl(hdl->libzfs_fd, ZFS_IOC_RENAME, &zc);
+ err = lzc_rename(name, newname);
if (err == 0)
changelist_rename(clp, name, tryname);
} else {
@@ -2174,13 +2167,11 @@ 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 = ioctl(hdl->libzfs_fd, ZFS_IOC_RENAME, &zc);
+ err = lzc_rename(name, newname);
if (err == 0)
changelist_rename(clp, name, newname);
if (err && flags->verbose) {
@@ -2205,7 +2196,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;
@@ -2228,17 +2218,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);
diff --git a/usr/src/lib/libzfs_core/common/libzfs_core.c b/usr/src/lib/libzfs_core/common/libzfs_core.c
index ac25820c61..268f1d6a7a 100644
--- a/usr/src/lib/libzfs_core/common/libzfs_core.c
+++ b/usr/src/lib/libzfs_core/common/libzfs_core.c
@@ -249,6 +249,34 @@ 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.
*
diff --git a/usr/src/lib/libzfs_core/common/libzfs_core.h b/usr/src/lib/libzfs_core/common/libzfs_core.h
index d4a9a49cc1..7dc618403e 100644
--- a/usr/src/lib/libzfs_core/common/libzfs_core.h
+++ b/usr/src/lib/libzfs_core/common/libzfs_core.h
@@ -91,6 +91,9 @@ boolean_t lzc_exists(const char *);
int lzc_rollback(const char *, char *, int);
int lzc_rollback_to(const char *, const char *);
+int lzc_rename(const char *, const char *);
+int lzc_destroy(const char *);
+
int lzc_channel_program(const char *, const char *, uint64_t,
uint64_t, nvlist_t *, nvlist_t **);
int lzc_channel_program_nosync(const char *, const char *, uint64_t,
diff --git a/usr/src/lib/libzfs_core/common/mapfile-vers b/usr/src/lib/libzfs_core/common/mapfile-vers
index 49c2e1e10c..3ad87ef0d8 100644
--- a/usr/src/lib/libzfs_core/common/mapfile-vers
+++ b/usr/src/lib/libzfs_core/common/mapfile-vers
@@ -37,13 +37,19 @@
$mapfile_version 2
+SYMBOL_VERSION ILLUMOS_0.4 {
+ global:
+
+ lzc_destroy;
+ lzc_rename;
+} ILLUMOS_0.3;
+
SYMBOL_VERSION ILLUMOS_0.3 {
global:
lzc_initialize;
} ILLUMOS_0.2;
-
SYMBOL_VERSION ILLUMOS_0.2 {
global:
@@ -60,7 +66,6 @@ SYMBOL_VERSION ILLUMOS_0.1 {
lzc_channel_program;
lzc_channel_program_nosync;
lzc_clone;
- lzc_promote;
lzc_create;
lzc_destroy_bookmarks;
lzc_destroy_snaps;
@@ -68,6 +73,7 @@ SYMBOL_VERSION ILLUMOS_0.1 {
lzc_get_bookmarks;
lzc_get_holds;
lzc_hold;
+ lzc_promote;
lzc_receive;
lzc_receive_resumable;
lzc_receive_with_header;
diff --git a/usr/src/uts/common/fs/zfs/zfs_ioctl.c b/usr/src/uts/common/fs/zfs/zfs_ioctl.c
index 175938eeb8..0abdbe9bad 100644
--- a/usr/src/uts/common/fs/zfs/zfs_ioctl.c
+++ b/usr/src/uts/common/fs/zfs/zfs_ioctl.c
@@ -3686,7 +3686,6 @@ zfs_ioc_pool_discard_checkpoint(const char *poolname, nvlist_t *innvl,
/*
* inputs:
* zc_name name of dataset to destroy
- * zc_objset_type type of objset
* zc_defer_destroy mark for deferred destroy
*
* outputs: none
@@ -3694,16 +3693,24 @@ zfs_ioc_pool_discard_checkpoint(const char *poolname, nvlist_t *innvl,
static int
zfs_ioc_destroy(zfs_cmd_t *zc)
{
+ objset_t *os;
+ dmu_objset_type_t ost;
int err;
- if (zc->zc_objset_type == DMU_OST_ZFS)
+ err = dmu_objset_hold(zc->zc_name, FTAG, &os);
+ if (err != 0)
+ return (err);
+ ost = dmu_objset_type(os);
+ dmu_objset_rele(os, FTAG);
+
+ if (ost == DMU_OST_ZFS)
zfs_unmount_snap(zc->zc_name);
if (strchr(zc->zc_name, '@'))
err = dsl_destroy_snapshot(zc->zc_name, zc->zc_defer_destroy);
else
err = dsl_destroy_head(zc->zc_name);
- if (zc->zc_objset_type == DMU_OST_ZVOL && err == 0)
+ if (ost == DMU_OST_ZVOL && err == 0)
(void) zvol_remove_minor(zc->zc_name);
return (err);
}
@@ -3854,8 +3861,11 @@ recursive_unmount(const char *fsname, void *arg)
static int
zfs_ioc_rename(zfs_cmd_t *zc)
{
+ objset_t *os;
+ dmu_objset_type_t ost;
boolean_t recursive = zc->zc_cookie & 1;
char *at;
+ int err;
/* "zfs rename" from and to ...%recv datasets should both fail */
zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
@@ -3865,6 +3875,12 @@ zfs_ioc_rename(zfs_cmd_t *zc)
strchr(zc->zc_name, '%') || strchr(zc->zc_value, '%'))
return (SET_ERROR(EINVAL));
+ err = dmu_objset_hold(zc->zc_name, FTAG, &os);
+ if (err != 0)
+ return (err);
+ ost = dmu_objset_type(os);
+ dmu_objset_rele(os, FTAG);
+
at = strchr(zc->zc_name, '@');
if (at != NULL) {
/* snaps must be in same fs */
@@ -3873,7 +3889,7 @@ zfs_ioc_rename(zfs_cmd_t *zc)
if (strncmp(zc->zc_name, zc->zc_value, at - zc->zc_name + 1))
return (SET_ERROR(EXDEV));
*at = '\0';
- if (zc->zc_objset_type == DMU_OST_ZFS) {
+ if (ost == DMU_OST_ZFS) {
error = dmu_objset_find(zc->zc_name,
recursive_unmount, at + 1,
recursive ? DS_FIND_CHILDREN : 0);
@@ -3888,7 +3904,7 @@ zfs_ioc_rename(zfs_cmd_t *zc)
return (error);
} else {
- if (zc->zc_objset_type == DMU_OST_ZVOL)
+ if (ost == DMU_OST_ZVOL)
(void) zvol_remove_minor(zc->zc_name);
return (dsl_dir_rename(zc->zc_name, zc->zc_value));
}