mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-27 04:32:16 +03:00
Illumos #3464
3464 zfs synctask code needs restructuring Reviewed by: Dan Kimmel <dan.kimmel@delphix.com> Reviewed by: Adam Leventhal <ahl@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Christopher Siden <christopher.siden@delphix.com> Approved by: Garrett D'Amore <garrett@damore.org> References: https://www.illumos.org/issues/3464 illumos/illumos-gate@3b2aab1880 Ported-by: Tim Chase <tim@chase2k.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #1495
This commit is contained in:
committed by
Brian Behlendorf
parent
6f1ffb0665
commit
13fe019870
+214
-142
@@ -313,7 +313,7 @@ get_recvd_props_ioctl(zfs_handle_t *zhp)
|
||||
{
|
||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||
nvlist_t *recvdprops;
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
int err;
|
||||
|
||||
if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
|
||||
@@ -376,7 +376,7 @@ static int
|
||||
get_stats(zfs_handle_t *zhp)
|
||||
{
|
||||
int rc = 0;
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
|
||||
if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
|
||||
return (-1);
|
||||
@@ -439,7 +439,7 @@ make_dataset_handle_common(zfs_handle_t *zhp, zfs_cmd_t *zc)
|
||||
zfs_handle_t *
|
||||
make_dataset_handle(libzfs_handle_t *hdl, const char *path)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
|
||||
zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
|
||||
|
||||
@@ -1427,7 +1427,7 @@ zfs_is_namespace_prop(zfs_prop_t prop)
|
||||
int
|
||||
zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
int ret = -1;
|
||||
prop_changelist_t *cl = NULL;
|
||||
char errbuf[1024];
|
||||
@@ -1553,7 +1553,7 @@ error:
|
||||
int
|
||||
zfs_prop_inherit(zfs_handle_t *zhp, const char *propname, boolean_t received)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
int ret;
|
||||
prop_changelist_t *cl;
|
||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||
@@ -1728,7 +1728,7 @@ static int
|
||||
get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
|
||||
char **source, uint64_t *val)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
nvlist_t *zplprops = NULL;
|
||||
struct mnttab mnt;
|
||||
char *mntopt_on = NULL;
|
||||
@@ -2002,10 +2002,7 @@ get_clones_cb(zfs_handle_t *zhp, void *arg)
|
||||
NULL, NULL, 0, B_TRUE) != 0)
|
||||
goto out;
|
||||
if (strcmp(gca->buf, gca->origin) == 0) {
|
||||
if (nvlist_add_boolean(gca->value, zfs_get_name(zhp)) != 0) {
|
||||
zfs_close(zhp);
|
||||
return (no_memory(zhp->zfs_hdl));
|
||||
}
|
||||
fnvlist_add_boolean(gca->value, zfs_get_name(zhp));
|
||||
gca->numclones--;
|
||||
}
|
||||
|
||||
@@ -2580,7 +2577,7 @@ zfs_prop_get_userquota_common(zfs_handle_t *zhp, const char *propname,
|
||||
uint64_t *propvalue, zfs_userquota_prop_t *typep)
|
||||
{
|
||||
int err;
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
|
||||
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
|
||||
|
||||
@@ -2640,7 +2637,7 @@ zfs_prop_get_written_int(zfs_handle_t *zhp, const char *propname,
|
||||
uint64_t *propvalue)
|
||||
{
|
||||
int err;
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
const char *snapname;
|
||||
|
||||
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
|
||||
@@ -2760,7 +2757,7 @@ static int
|
||||
check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned,
|
||||
boolean_t accept_ancestor, int *prefixlen)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
char parent[ZFS_MAXNAMELEN];
|
||||
char *slash;
|
||||
zfs_handle_t *zhp;
|
||||
@@ -3120,7 +3117,7 @@ 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", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
|
||||
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
|
||||
|
||||
@@ -3200,46 +3197,50 @@ zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname, boolean_t defer)
|
||||
dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"),
|
||||
zhp->zfs_name, snapname);
|
||||
} else {
|
||||
ret = zfs_destroy_snaps_nvl(zhp, dd.nvl, defer);
|
||||
ret = zfs_destroy_snaps_nvl(zhp->zfs_hdl, dd.nvl, defer);
|
||||
}
|
||||
nvlist_free(dd.nvl);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroys all the snapshots named in the nvlist. They must be underneath
|
||||
* the zhp (either snapshots of it, or snapshots of its descendants).
|
||||
* Destroys all the snapshots named in the nvlist.
|
||||
*/
|
||||
int
|
||||
zfs_destroy_snaps_nvl(zfs_handle_t *zhp, nvlist_t *snaps, boolean_t defer)
|
||||
zfs_destroy_snaps_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, boolean_t defer)
|
||||
{
|
||||
int ret;
|
||||
nvlist_t *errlist;
|
||||
nvpair_t *pair;
|
||||
|
||||
ret = lzc_destroy_snaps(snaps, defer, &errlist);
|
||||
|
||||
if (ret != 0) {
|
||||
nvpair_t *pair;
|
||||
for (pair = nvlist_next_nvpair(errlist, NULL);
|
||||
pair != NULL; pair = nvlist_next_nvpair(errlist, pair)) {
|
||||
char errbuf[1024];
|
||||
(void) snprintf(errbuf, sizeof (errbuf),
|
||||
dgettext(TEXT_DOMAIN, "cannot destroy snapshot %s"),
|
||||
nvpair_name(pair));
|
||||
if (ret == 0)
|
||||
return (0);
|
||||
|
||||
switch (fnvpair_value_int32(pair)) {
|
||||
case EEXIST:
|
||||
zfs_error_aux(zhp->zfs_hdl,
|
||||
dgettext(TEXT_DOMAIN,
|
||||
"snapshot is cloned"));
|
||||
ret = zfs_error(zhp->zfs_hdl, EZFS_EXISTS,
|
||||
errbuf);
|
||||
break;
|
||||
default:
|
||||
ret = zfs_standard_error(zhp->zfs_hdl, errno,
|
||||
errbuf);
|
||||
break;
|
||||
}
|
||||
if (nvlist_next_nvpair(errlist, NULL) == NULL) {
|
||||
char errbuf[1024];
|
||||
(void) snprintf(errbuf, sizeof (errbuf),
|
||||
dgettext(TEXT_DOMAIN, "cannot destroy snapshots"));
|
||||
|
||||
ret = zfs_standard_error(hdl, ret, errbuf);
|
||||
}
|
||||
for (pair = nvlist_next_nvpair(errlist, NULL);
|
||||
pair != NULL; pair = nvlist_next_nvpair(errlist, pair)) {
|
||||
char errbuf[1024];
|
||||
(void) snprintf(errbuf, sizeof (errbuf),
|
||||
dgettext(TEXT_DOMAIN, "cannot destroy snapshot %s"),
|
||||
nvpair_name(pair));
|
||||
|
||||
switch (fnvpair_value_int32(pair)) {
|
||||
case EEXIST:
|
||||
zfs_error_aux(hdl,
|
||||
dgettext(TEXT_DOMAIN, "snapshot is cloned"));
|
||||
ret = zfs_error(hdl, EZFS_EXISTS, errbuf);
|
||||
break;
|
||||
default:
|
||||
ret = zfs_standard_error(hdl, errno, errbuf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3388,7 +3389,7 @@ int
|
||||
zfs_promote(zfs_handle_t *zhp)
|
||||
{
|
||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
char parent[MAXPATHLEN];
|
||||
char *cp;
|
||||
int ret;
|
||||
@@ -3726,7 +3727,7 @@ zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
|
||||
{
|
||||
rollback_data_t cb = { 0 };
|
||||
int err;
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
boolean_t restore_resv = 0;
|
||||
uint64_t old_volsize = 0, new_volsize;
|
||||
zfs_prop_t resv_prop = { 0 };
|
||||
@@ -3813,7 +3814,7 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
||||
boolean_t force_unmount)
|
||||
{
|
||||
int ret;
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
char *delim;
|
||||
prop_changelist_t *cl = NULL;
|
||||
zfs_handle_t *zhrp = NULL;
|
||||
@@ -4032,7 +4033,7 @@ zvol_create_link(libzfs_handle_t *hdl, const char *dataset)
|
||||
static int
|
||||
zvol_create_link_common(libzfs_handle_t *hdl, const char *dataset, int ifexists)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
char path[MAXPATHLEN];
|
||||
int error;
|
||||
|
||||
@@ -4096,7 +4097,7 @@ zvol_create_link_common(libzfs_handle_t *hdl, const char *dataset, int ifexists)
|
||||
int
|
||||
zvol_remove_link(libzfs_handle_t *hdl, const char *dataset)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
int timeout = 3000; /* in milliseconds */
|
||||
int error = 0;
|
||||
int i;
|
||||
@@ -4289,7 +4290,7 @@ static int
|
||||
zfs_smb_acl_mgmt(libzfs_handle_t *hdl, char *dataset, char *path,
|
||||
zfs_smb_acl_op_t cmd, char *resource1, char *resource2)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
nvlist_t *nvlist = NULL;
|
||||
int error;
|
||||
|
||||
@@ -4371,7 +4372,7 @@ int
|
||||
zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type,
|
||||
zfs_userspace_cb_t func, void *arg)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
zfs_useracct_t buf[100];
|
||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||
int ret;
|
||||
@@ -4408,37 +4409,83 @@ zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type,
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct holdarg {
|
||||
nvlist_t *nvl;
|
||||
const char *snapname;
|
||||
const char *tag;
|
||||
boolean_t recursive;
|
||||
};
|
||||
|
||||
static int
|
||||
zfs_hold_one(zfs_handle_t *zhp, void *arg)
|
||||
{
|
||||
struct holdarg *ha = arg;
|
||||
zfs_handle_t *szhp;
|
||||
char name[ZFS_MAXNAMELEN];
|
||||
int rv = 0;
|
||||
|
||||
(void) snprintf(name, sizeof (name),
|
||||
"%s@%s", zhp->zfs_name, ha->snapname);
|
||||
|
||||
szhp = make_dataset_handle(zhp->zfs_hdl, name);
|
||||
if (szhp) {
|
||||
fnvlist_add_string(ha->nvl, name, ha->tag);
|
||||
zfs_close(szhp);
|
||||
}
|
||||
|
||||
if (ha->recursive)
|
||||
rv = zfs_iter_filesystems(zhp, zfs_hold_one, ha);
|
||||
zfs_close(zhp);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
|
||||
boolean_t recursive, boolean_t temphold, boolean_t enoent_ok,
|
||||
int cleanup_fd, uint64_t dsobj, uint64_t createtxg)
|
||||
boolean_t recursive, boolean_t enoent_ok, int cleanup_fd)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
int ret;
|
||||
struct holdarg ha;
|
||||
nvlist_t *errors;
|
||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||
char errbuf[1024];
|
||||
nvpair_t *elem;
|
||||
|
||||
ASSERT(!recursive || dsobj == 0);
|
||||
ha.nvl = fnvlist_alloc();
|
||||
ha.snapname = snapname;
|
||||
ha.tag = tag;
|
||||
ha.recursive = recursive;
|
||||
(void) zfs_hold_one(zfs_handle_dup(zhp), &ha);
|
||||
ret = lzc_hold(ha.nvl, cleanup_fd, &errors);
|
||||
fnvlist_free(ha.nvl);
|
||||
|
||||
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
|
||||
(void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
|
||||
if (strlcpy(zc.zc_string, tag, sizeof (zc.zc_string))
|
||||
>= sizeof (zc.zc_string))
|
||||
return (zfs_error(hdl, EZFS_TAGTOOLONG, tag));
|
||||
zc.zc_cookie = recursive;
|
||||
zc.zc_temphold = temphold;
|
||||
zc.zc_cleanup_fd = cleanup_fd;
|
||||
zc.zc_sendobj = dsobj;
|
||||
zc.zc_createtxg = createtxg;
|
||||
if (ret == 0)
|
||||
return (0);
|
||||
|
||||
if (zfs_ioctl(hdl, ZFS_IOC_HOLD, &zc) != 0) {
|
||||
char errbuf[ZFS_MAXNAMELEN+32];
|
||||
if (nvlist_next_nvpair(errors, NULL) == NULL) {
|
||||
/* no hold-specific errors */
|
||||
(void) snprintf(errbuf, sizeof (errbuf),
|
||||
dgettext(TEXT_DOMAIN, "cannot hold"));
|
||||
switch (ret) {
|
||||
case ENOTSUP:
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"pool must be upgraded"));
|
||||
(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
|
||||
break;
|
||||
case EINVAL:
|
||||
(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
|
||||
break;
|
||||
default:
|
||||
(void) zfs_standard_error(hdl, ret, errbuf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* if it was recursive, the one that actually failed will be in
|
||||
* zc.zc_name.
|
||||
*/
|
||||
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
|
||||
"cannot hold '%s@%s'"), zc.zc_name, snapname);
|
||||
switch (errno) {
|
||||
for (elem = nvlist_next_nvpair(errors, NULL);
|
||||
elem != NULL;
|
||||
elem = nvlist_next_nvpair(errors, elem)) {
|
||||
(void) snprintf(errbuf, sizeof (errbuf),
|
||||
dgettext(TEXT_DOMAIN,
|
||||
"cannot hold snapshot '%s'"), nvpair_name(elem));
|
||||
switch (fnvpair_value_int32(elem)) {
|
||||
case E2BIG:
|
||||
/*
|
||||
* Temporary tags wind up having the ds object id
|
||||
@@ -4446,77 +4493,133 @@ zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
|
||||
* above, it's still possible for the tag to wind
|
||||
* up being slightly too long.
|
||||
*/
|
||||
return (zfs_error(hdl, EZFS_TAGTOOLONG, errbuf));
|
||||
case ENOTSUP:
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"pool must be upgraded"));
|
||||
return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
|
||||
(void) zfs_error(hdl, EZFS_TAGTOOLONG, errbuf);
|
||||
break;
|
||||
case EINVAL:
|
||||
return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
|
||||
(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
|
||||
break;
|
||||
case EEXIST:
|
||||
return (zfs_error(hdl, EZFS_REFTAG_HOLD, errbuf));
|
||||
(void) zfs_error(hdl, EZFS_REFTAG_HOLD, errbuf);
|
||||
break;
|
||||
case ENOENT:
|
||||
if (enoent_ok)
|
||||
return (ENOENT);
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
return (zfs_standard_error_fmt(hdl, errno, errbuf));
|
||||
(void) zfs_standard_error(hdl,
|
||||
fnvpair_value_int32(elem), errbuf);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
fnvlist_free(errors);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
struct releasearg {
|
||||
nvlist_t *nvl;
|
||||
const char *snapname;
|
||||
const char *tag;
|
||||
boolean_t recursive;
|
||||
};
|
||||
|
||||
static int
|
||||
zfs_release_one(zfs_handle_t *zhp, void *arg)
|
||||
{
|
||||
struct holdarg *ha = arg;
|
||||
zfs_handle_t *szhp;
|
||||
char name[ZFS_MAXNAMELEN];
|
||||
int rv = 0;
|
||||
|
||||
(void) snprintf(name, sizeof (name),
|
||||
"%s@%s", zhp->zfs_name, ha->snapname);
|
||||
|
||||
szhp = make_dataset_handle(zhp->zfs_hdl, name);
|
||||
if (szhp) {
|
||||
nvlist_t *holds = fnvlist_alloc();
|
||||
fnvlist_add_boolean(holds, ha->tag);
|
||||
fnvlist_add_nvlist(ha->nvl, name, holds);
|
||||
zfs_close(szhp);
|
||||
}
|
||||
|
||||
if (ha->recursive)
|
||||
rv = zfs_iter_filesystems(zhp, zfs_release_one, ha);
|
||||
zfs_close(zhp);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
|
||||
boolean_t recursive)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
int ret;
|
||||
struct holdarg ha;
|
||||
nvlist_t *errors;
|
||||
nvpair_t *elem;
|
||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||
|
||||
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
|
||||
(void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
|
||||
if (strlcpy(zc.zc_string, tag, sizeof (zc.zc_string))
|
||||
>= sizeof (zc.zc_string))
|
||||
return (zfs_error(hdl, EZFS_TAGTOOLONG, tag));
|
||||
zc.zc_cookie = recursive;
|
||||
ha.nvl = fnvlist_alloc();
|
||||
ha.snapname = snapname;
|
||||
ha.tag = tag;
|
||||
ha.recursive = recursive;
|
||||
(void) zfs_release_one(zfs_handle_dup(zhp), &ha);
|
||||
ret = lzc_release(ha.nvl, &errors);
|
||||
fnvlist_free(ha.nvl);
|
||||
|
||||
if (zfs_ioctl(hdl, ZFS_IOC_RELEASE, &zc) != 0) {
|
||||
char errbuf[ZFS_MAXNAMELEN+32];
|
||||
if (ret == 0)
|
||||
return (0);
|
||||
|
||||
if (nvlist_next_nvpair(errors, NULL) == NULL) {
|
||||
/* no hold-specific errors */
|
||||
char errbuf[1024];
|
||||
|
||||
/*
|
||||
* if it was recursive, the one that actually failed will be in
|
||||
* zc.zc_name.
|
||||
*/
|
||||
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
|
||||
"cannot release '%s' from '%s@%s'"), tag, zc.zc_name,
|
||||
snapname);
|
||||
"cannot release"));
|
||||
switch (errno) {
|
||||
case ESRCH:
|
||||
return (zfs_error(hdl, EZFS_REFTAG_RELE, errbuf));
|
||||
case ENOTSUP:
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"pool must be upgraded"));
|
||||
return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
|
||||
case EINVAL:
|
||||
return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
|
||||
(void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
|
||||
break;
|
||||
default:
|
||||
return (zfs_standard_error_fmt(hdl, errno, errbuf));
|
||||
(void) zfs_standard_error_fmt(hdl, errno, errbuf);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
for (elem = nvlist_next_nvpair(errors, NULL);
|
||||
elem != NULL;
|
||||
elem = nvlist_next_nvpair(errors, elem)) {
|
||||
char errbuf[1024];
|
||||
|
||||
(void) snprintf(errbuf, sizeof (errbuf),
|
||||
dgettext(TEXT_DOMAIN,
|
||||
"cannot release hold from snapshot '%s'"),
|
||||
nvpair_name(elem));
|
||||
switch (fnvpair_value_int32(elem)) {
|
||||
case ESRCH:
|
||||
(void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf);
|
||||
break;
|
||||
case EINVAL:
|
||||
(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
|
||||
break;
|
||||
default:
|
||||
(void) zfs_standard_error_fmt(hdl,
|
||||
fnvpair_value_int32(elem), errbuf);
|
||||
}
|
||||
}
|
||||
|
||||
fnvlist_free(errors);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
zfs_get_fsacl(zfs_handle_t *zhp, nvlist_t **nvl)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||
int nvsz = 2048;
|
||||
void *nvbuf;
|
||||
int err = 0;
|
||||
char errbuf[ZFS_MAXNAMELEN+32];
|
||||
char errbuf[1024];
|
||||
|
||||
assert(zhp->zfs_type == ZFS_TYPE_VOLUME ||
|
||||
zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
|
||||
@@ -4578,10 +4681,10 @@ out:
|
||||
int
|
||||
zfs_set_fsacl(zfs_handle_t *zhp, boolean_t un, nvlist_t *nvl)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||
char *nvbuf;
|
||||
char errbuf[ZFS_MAXNAMELEN+32];
|
||||
char errbuf[1024];
|
||||
size_t nvsz;
|
||||
int err;
|
||||
|
||||
@@ -4632,38 +4735,18 @@ zfs_set_fsacl(zfs_handle_t *zhp, boolean_t un, nvlist_t *nvl)
|
||||
int
|
||||
zfs_get_holds(zfs_handle_t *zhp, nvlist_t **nvl)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
|
||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||
int nvsz = 2048;
|
||||
void *nvbuf;
|
||||
int err = 0;
|
||||
char errbuf[ZFS_MAXNAMELEN+32];
|
||||
int err;
|
||||
char errbuf[1024];
|
||||
|
||||
assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
|
||||
err = lzc_get_holds(zhp->zfs_name, nvl);
|
||||
|
||||
tryagain:
|
||||
if (err != 0) {
|
||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||
|
||||
nvbuf = malloc(nvsz);
|
||||
if (nvbuf == NULL) {
|
||||
err = (zfs_error(hdl, EZFS_NOMEM, strerror(errno)));
|
||||
goto out;
|
||||
}
|
||||
|
||||
zc.zc_nvlist_dst_size = nvsz;
|
||||
zc.zc_nvlist_dst = (uintptr_t)nvbuf;
|
||||
|
||||
(void) strlcpy(zc.zc_name, zhp->zfs_name, ZFS_MAXNAMELEN);
|
||||
|
||||
if (zfs_ioctl(hdl, ZFS_IOC_GET_HOLDS, &zc) != 0) {
|
||||
(void) snprintf(errbuf, sizeof (errbuf),
|
||||
dgettext(TEXT_DOMAIN, "cannot get holds for '%s'"),
|
||||
zc.zc_name);
|
||||
switch (errno) {
|
||||
case ENOMEM:
|
||||
free(nvbuf);
|
||||
nvsz = zc.zc_nvlist_dst_size;
|
||||
goto tryagain;
|
||||
|
||||
zhp->zfs_name);
|
||||
switch (err) {
|
||||
case ENOTSUP:
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"pool must be upgraded"));
|
||||
@@ -4679,19 +4762,8 @@ tryagain:
|
||||
err = zfs_standard_error_fmt(hdl, errno, errbuf);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* success */
|
||||
int rc = nvlist_unpack(nvbuf, zc.zc_nvlist_dst_size, nvl, 0);
|
||||
if (rc) {
|
||||
(void) snprintf(errbuf, sizeof (errbuf),
|
||||
dgettext(TEXT_DOMAIN, "cannot get holds for '%s'"),
|
||||
zc.zc_name);
|
||||
err = zfs_standard_error_fmt(hdl, rc, errbuf);
|
||||
}
|
||||
}
|
||||
|
||||
free(nvbuf);
|
||||
out:
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user