MFV r289493: 5745 zfs set allows only one dataset property to be set at a time
Reviewed by: Christopher Siden <christopher.siden@delphix.com> Reviewed by: George Wilson <george@delphix.com> Reviewed by: Matthew Ahrens <mahrens@delphix.com> Reviewed by: Bayard Bell <buffer.g.overflow@gmail.com> Reviewed by: Richard PALO <richard@NetBSD.org> Reviewed by: Steven Hartland <killing@multiplay.co.uk> Approved by: Rich Lowe <richlowe@richlowe.net> Author: Chris Williamson <chris.williamson@delphix.com> illumos/illumos-gate@30925561c2
This commit is contained in:
commit
05b1dc3f1f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=289497
@ -18,7 +18,7 @@
|
|||||||
.\" information: Portions Copyright [yyyy] [name of copyright owner]
|
.\" information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2010, Sun Microsystems, Inc. All Rights Reserved.
|
.\" Copyright (c) 2010, Sun Microsystems, Inc. All Rights Reserved.
|
||||||
.\" Copyright (c) 2014 by Delphix. All rights reserved.
|
.\" Copyright (c) 2011, 2014 by Delphix. All rights reserved.
|
||||||
.\" Copyright (c) 2011, Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
.\" Copyright (c) 2011, Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||||
.\" Copyright (c) 2012, Glen Barber <gjb@FreeBSD.org>
|
.\" Copyright (c) 2012, Glen Barber <gjb@FreeBSD.org>
|
||||||
.\" Copyright (c) 2012, Bryan Drewery <bdrewery@FreeBSD.org>
|
.\" Copyright (c) 2012, Bryan Drewery <bdrewery@FreeBSD.org>
|
||||||
@ -117,7 +117,7 @@
|
|||||||
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
|
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
|
||||||
.Nm
|
.Nm
|
||||||
.Cm set
|
.Cm set
|
||||||
.Ar property Ns = Ns Ar value
|
.Ar property Ns = Ns Ar value Oc ...
|
||||||
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
|
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
|
||||||
.Nm
|
.Nm
|
||||||
.Cm get
|
.Cm get
|
||||||
@ -2121,14 +2121,14 @@ option, but sorts by property in descending order.
|
|||||||
.It Xo
|
.It Xo
|
||||||
.Nm
|
.Nm
|
||||||
.Cm set
|
.Cm set
|
||||||
.Ar property Ns = Ns Ar value
|
.Ar property Ns = Ns Ar value Oc ...
|
||||||
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
|
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
|
||||||
.Xc
|
.Xc
|
||||||
.Pp
|
.Pp
|
||||||
Sets the property to the given value for each dataset. Only some properties can
|
Sets the property or list of properties to the given value(s) for each dataset.
|
||||||
be edited. See the "Properties" section for more information on what properties
|
Only some properties can be edited. See the "Properties" section for more
|
||||||
can be set and acceptable values. Numeric values can be specified as exact
|
information on what properties can be set and acceptable values. Numeric values
|
||||||
values, or in a human-readable form with a suffix of
|
can be specified as exact values, or in a human-readable form with a suffix of
|
||||||
.Sy B , K , M , G , T , P , E , Z
|
.Sy B , K , M , G , T , P , E , Z
|
||||||
(for bytes, kilobytes, megabytes, gigabytes, terabytes, petabytes, exabytes, or
|
(for bytes, kilobytes, megabytes, gigabytes, terabytes, petabytes, exabytes, or
|
||||||
zettabytes, respectively). User properties can be set on snapshots. For more
|
zettabytes, respectively). User properties can be set on snapshots. For more
|
||||||
|
@ -283,7 +283,7 @@ get_usage(zfs_help_t idx)
|
|||||||
"<filesystem|volume|snapshot>\n"
|
"<filesystem|volume|snapshot>\n"
|
||||||
"\tsend [-nvPe] -t <receive_resume_token>\n"));
|
"\tsend [-nvPe] -t <receive_resume_token>\n"));
|
||||||
case HELP_SET:
|
case HELP_SET:
|
||||||
return (gettext("\tset <property=value> "
|
return (gettext("\tset <property=value> ... "
|
||||||
"<filesystem|volume|snapshot> ...\n"));
|
"<filesystem|volume|snapshot> ...\n"));
|
||||||
case HELP_SHARE:
|
case HELP_SHARE:
|
||||||
return (gettext("\tshare <-a | filesystem>\n"));
|
return (gettext("\tshare <-a | filesystem>\n"));
|
||||||
@ -498,6 +498,10 @@ usage(boolean_t requested)
|
|||||||
exit(requested ? 0 : 2);
|
exit(requested ? 0 : 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Take a property=value argument string and add it to the given nvlist.
|
||||||
|
* Modifies the argument inplace.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
parseprop(nvlist_t *props, char *propname)
|
parseprop(nvlist_t *props, char *propname)
|
||||||
{
|
{
|
||||||
@ -505,7 +509,7 @@ parseprop(nvlist_t *props, char *propname)
|
|||||||
|
|
||||||
if ((propval = strchr(propname, '=')) == NULL) {
|
if ((propval = strchr(propname, '=')) == NULL) {
|
||||||
(void) fprintf(stderr, gettext("missing "
|
(void) fprintf(stderr, gettext("missing "
|
||||||
"'=' for -o option\n"));
|
"'=' for property=value argument\n"));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
*propval = '\0';
|
*propval = '\0';
|
||||||
@ -632,7 +636,7 @@ zfs_do_clone(int argc, char **argv)
|
|||||||
while ((c = getopt(argc, argv, "o:p")) != -1) {
|
while ((c = getopt(argc, argv, "o:p")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'o':
|
case 'o':
|
||||||
if (parseprop(props, optarg))
|
if (parseprop(props, optarg) != 0)
|
||||||
return (1);
|
return (1);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
@ -3532,21 +3536,17 @@ zfs_do_rollback(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* zfs set property=value { fs | snap | vol } ...
|
* zfs set property=value ... { fs | snap | vol } ...
|
||||||
*
|
*
|
||||||
* Sets the given property for all datasets specified on the command line.
|
* Sets the given properties for all datasets specified on the command line.
|
||||||
*/
|
*/
|
||||||
typedef struct set_cbdata {
|
|
||||||
char *cb_propname;
|
|
||||||
char *cb_value;
|
|
||||||
} set_cbdata_t;
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
set_callback(zfs_handle_t *zhp, void *data)
|
set_callback(zfs_handle_t *zhp, void *data)
|
||||||
{
|
{
|
||||||
set_cbdata_t *cbp = data;
|
nvlist_t *props = data;
|
||||||
|
|
||||||
if (zfs_prop_set(zhp, cbp->cb_propname, cbp->cb_value) != 0) {
|
if (zfs_prop_set_list(zhp, props) != 0) {
|
||||||
switch (libzfs_errno(g_zfs)) {
|
switch (libzfs_errno(g_zfs)) {
|
||||||
case EZFS_MOUNTFAILED:
|
case EZFS_MOUNTFAILED:
|
||||||
(void) fprintf(stderr, gettext("property may be set "
|
(void) fprintf(stderr, gettext("property may be set "
|
||||||
@ -3565,7 +3565,8 @@ set_callback(zfs_handle_t *zhp, void *data)
|
|||||||
static int
|
static int
|
||||||
zfs_do_set(int argc, char **argv)
|
zfs_do_set(int argc, char **argv)
|
||||||
{
|
{
|
||||||
set_cbdata_t cb;
|
nvlist_t *props = NULL;
|
||||||
|
int ds_start = -1; /* argv idx of first dataset arg */
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* check for options */
|
/* check for options */
|
||||||
@ -3577,36 +3578,51 @@ zfs_do_set(int argc, char **argv)
|
|||||||
|
|
||||||
/* check number of arguments */
|
/* check number of arguments */
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
(void) fprintf(stderr, gettext("missing property=value "
|
(void) fprintf(stderr, gettext("missing arguments\n"));
|
||||||
"argument\n"));
|
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
(void) fprintf(stderr, gettext("missing dataset name\n"));
|
if (strchr(argv[1], '=') == NULL) {
|
||||||
|
(void) fprintf(stderr, gettext("missing property=value "
|
||||||
|
"argument(s)\n"));
|
||||||
|
} else {
|
||||||
|
(void) fprintf(stderr, gettext("missing dataset "
|
||||||
|
"name(s)\n"));
|
||||||
|
}
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* validate property=value argument */
|
/* validate argument order: prop=val args followed by dataset args */
|
||||||
cb.cb_propname = argv[1];
|
for (int i = 1; i < argc; i++) {
|
||||||
if (((cb.cb_value = strchr(cb.cb_propname, '=')) == NULL) ||
|
if (strchr(argv[i], '=') != NULL) {
|
||||||
(cb.cb_value[1] == '\0')) {
|
if (ds_start > 0) {
|
||||||
(void) fprintf(stderr, gettext("missing value in "
|
/* out-of-order prop=val argument */
|
||||||
"property=value argument\n"));
|
(void) fprintf(stderr, gettext("invalid "
|
||||||
|
"argument order\n"), i);
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
|
} else if (ds_start < 0) {
|
||||||
|
ds_start = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ds_start < 0) {
|
||||||
|
(void) fprintf(stderr, gettext("missing dataset name(s)\n"));
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
*cb.cb_value = '\0';
|
/* Populate a list of property settings */
|
||||||
cb.cb_value++;
|
if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
|
||||||
|
nomem();
|
||||||
if (*cb.cb_propname == '\0') {
|
for (int i = 1; i < ds_start; i++) {
|
||||||
(void) fprintf(stderr,
|
if ((ret = parseprop(props, argv[i])) != 0)
|
||||||
gettext("missing property in property=value argument\n"));
|
goto error;
|
||||||
usage(B_FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = zfs_for_each(argc - 2, argv + 2, 0,
|
ret = zfs_for_each(argc - ds_start, argv + ds_start, 0,
|
||||||
ZFS_TYPE_DATASET, NULL, NULL, 0, set_callback, &cb);
|
ZFS_TYPE_DATASET, NULL, NULL, 0, set_callback, props);
|
||||||
|
|
||||||
|
error:
|
||||||
|
nvlist_free(props);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright (c) 2013 by Delphix. All rights reserved.
|
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||||
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
||||||
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
||||||
@ -430,6 +430,7 @@ extern nvlist_t *zfs_valid_proplist(libzfs_handle_t *, zfs_type_t,
|
|||||||
|
|
||||||
extern const char *zfs_prop_to_name(zfs_prop_t);
|
extern const char *zfs_prop_to_name(zfs_prop_t);
|
||||||
extern int zfs_prop_set(zfs_handle_t *, const char *, const char *);
|
extern int zfs_prop_set(zfs_handle_t *, const char *, const char *);
|
||||||
|
extern int zfs_prop_set_list(zfs_handle_t *, nvlist_t *);
|
||||||
extern int zfs_prop_get(zfs_handle_t *, zfs_prop_t, char *, size_t,
|
extern int zfs_prop_get(zfs_handle_t *, zfs_prop_t, char *, size_t,
|
||||||
zprop_source_t *, char *, size_t, boolean_t);
|
zprop_source_t *, char *, size_t, boolean_t);
|
||||||
extern int zfs_prop_get_recvd(zfs_handle_t *, const char *, char *, size_t,
|
extern int zfs_prop_get_recvd(zfs_handle_t *, const char *, char *, size_t,
|
||||||
|
@ -1534,15 +1534,10 @@ zfs_setprop_error(libzfs_handle_t *hdl, zfs_prop_t prop, int err,
|
|||||||
int
|
int
|
||||||
zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
|
zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
|
||||||
{
|
{
|
||||||
zfs_cmd_t zc = { 0 };
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
prop_changelist_t *cl = NULL;
|
|
||||||
char errbuf[1024];
|
char errbuf[1024];
|
||||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||||
nvlist_t *nvl = NULL, *realprops;
|
nvlist_t *nvl = NULL;
|
||||||
zfs_prop_t prop;
|
|
||||||
boolean_t do_prefix = B_TRUE;
|
|
||||||
int added_resv;
|
|
||||||
|
|
||||||
(void) snprintf(errbuf, sizeof (errbuf),
|
(void) snprintf(errbuf, sizeof (errbuf),
|
||||||
dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
|
dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
|
||||||
@ -1554,79 +1549,148 @@ zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((realprops = zfs_valid_proplist(hdl, zhp->zfs_type, nvl,
|
ret = zfs_prop_set_list(zhp, nvl);
|
||||||
|
|
||||||
|
error:
|
||||||
|
nvlist_free(nvl);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given an nvlist of property names and values, set the properties for the
|
||||||
|
* given dataset.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
|
||||||
|
{
|
||||||
|
zfs_cmd_t zc = { 0 };
|
||||||
|
int ret = -1;
|
||||||
|
prop_changelist_t **cls = NULL;
|
||||||
|
int cl_idx;
|
||||||
|
char errbuf[1024];
|
||||||
|
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||||
|
nvlist_t *nvl;
|
||||||
|
int nvl_len;
|
||||||
|
int added_resv;
|
||||||
|
|
||||||
|
(void) snprintf(errbuf, sizeof (errbuf),
|
||||||
|
dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
|
||||||
|
zhp->zfs_name);
|
||||||
|
|
||||||
|
if ((nvl = zfs_valid_proplist(hdl, zhp->zfs_type, props,
|
||||||
zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf)) == NULL)
|
zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf)) == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
nvlist_free(nvl);
|
|
||||||
nvl = realprops;
|
|
||||||
|
|
||||||
prop = zfs_name_to_prop(propname);
|
|
||||||
|
|
||||||
/* We don't support those properties on FreeBSD. */
|
|
||||||
switch (prop) {
|
|
||||||
case ZFS_PROP_DEVICES:
|
|
||||||
case ZFS_PROP_ISCSIOPTIONS:
|
|
||||||
case ZFS_PROP_XATTR:
|
|
||||||
case ZFS_PROP_VSCAN:
|
|
||||||
case ZFS_PROP_NBMAND:
|
|
||||||
case ZFS_PROP_MLSLABEL:
|
|
||||||
(void) snprintf(errbuf, sizeof (errbuf),
|
|
||||||
"property '%s' not supported on FreeBSD", propname);
|
|
||||||
ret = zfs_error(hdl, EZFS_PERM, errbuf);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prop == ZFS_PROP_VOLSIZE) {
|
|
||||||
if ((added_resv = zfs_add_synthetic_resv(zhp, nvl)) == -1)
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
|
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
|
||||||
"child dataset with inherited mountpoint is used "
|
|
||||||
"in a non-global zone"));
|
|
||||||
ret = zfs_error(hdl, EZFS_ZONED, errbuf);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't want to unmount & remount the dataset when changing
|
* We have to check for any extra properties which need to be added
|
||||||
* its canmount property to 'on' or 'noauto'. We only use
|
* before computing the length of the nvlist.
|
||||||
* the changelist logic to unmount when setting canmount=off.
|
|
||||||
*/
|
*/
|
||||||
if (prop == ZFS_PROP_CANMOUNT) {
|
for (nvpair_t *elem = nvlist_next_nvpair(nvl, NULL);
|
||||||
uint64_t idx;
|
elem != NULL;
|
||||||
int err = zprop_string_to_index(prop, propval, &idx,
|
elem = nvlist_next_nvpair(nvl, elem)) {
|
||||||
ZFS_TYPE_DATASET);
|
if (zfs_name_to_prop(nvpair_name(elem)) == ZFS_PROP_VOLSIZE &&
|
||||||
if (err == 0 && idx != ZFS_CANMOUNT_OFF)
|
(added_resv = zfs_add_synthetic_resv(zhp, nvl)) == -1) {
|
||||||
do_prefix = B_FALSE;
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
if (do_prefix && (ret = changelist_prefix(cl)) != 0)
|
* Check how many properties we're setting and allocate an array to
|
||||||
|
* store changelist pointers for postfix().
|
||||||
|
*/
|
||||||
|
nvl_len = 0;
|
||||||
|
for (nvpair_t *elem = nvlist_next_nvpair(nvl, NULL);
|
||||||
|
elem != NULL;
|
||||||
|
elem = nvlist_next_nvpair(nvl, elem))
|
||||||
|
nvl_len++;
|
||||||
|
if ((cls = calloc(nvl_len, sizeof (prop_changelist_t *))) == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
cl_idx = 0;
|
||||||
|
for (nvpair_t *elem = nvlist_next_nvpair(nvl, NULL);
|
||||||
|
elem != NULL;
|
||||||
|
elem = nvlist_next_nvpair(nvl, elem)) {
|
||||||
|
|
||||||
|
zfs_prop_t prop = zfs_name_to_prop(nvpair_name(elem));
|
||||||
|
|
||||||
|
assert(cl_idx < nvl_len);
|
||||||
|
/*
|
||||||
|
* We don't want to unmount & remount the dataset when changing
|
||||||
|
* its canmount property to 'on' or 'noauto'. We only use
|
||||||
|
* the changelist logic to unmount when setting canmount=off.
|
||||||
|
*/
|
||||||
|
if (!(prop == ZFS_PROP_CANMOUNT &&
|
||||||
|
fnvpair_value_uint64(elem) != ZFS_CANMOUNT_OFF)) {
|
||||||
|
cls[cl_idx] = changelist_gather(zhp, prop, 0, 0);
|
||||||
|
if (cls[cl_idx] == NULL)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prop == ZFS_PROP_MOUNTPOINT &&
|
||||||
|
changelist_haszonedchild(cls[cl_idx])) {
|
||||||
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
|
"child dataset with inherited mountpoint is used "
|
||||||
|
"in a non-global zone"));
|
||||||
|
ret = zfs_error(hdl, EZFS_ZONED, errbuf);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We don't support those properties on FreeBSD. */
|
||||||
|
switch (prop) {
|
||||||
|
case ZFS_PROP_DEVICES:
|
||||||
|
case ZFS_PROP_ISCSIOPTIONS:
|
||||||
|
case ZFS_PROP_XATTR:
|
||||||
|
case ZFS_PROP_VSCAN:
|
||||||
|
case ZFS_PROP_NBMAND:
|
||||||
|
case ZFS_PROP_MLSLABEL:
|
||||||
|
(void) snprintf(errbuf, sizeof (errbuf),
|
||||||
|
"property '%s' not supported on FreeBSD",
|
||||||
|
nvpair_name(elem));
|
||||||
|
ret = zfs_error(hdl, EZFS_PERM, errbuf);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cls[cl_idx] != NULL &&
|
||||||
|
(ret = changelist_prefix(cls[cl_idx])) != 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
cl_idx++;
|
||||||
|
}
|
||||||
|
assert(cl_idx == nvl_len);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Execute the corresponding ioctl() to set this property.
|
* Execute the corresponding ioctl() to set this list of properties.
|
||||||
*/
|
*/
|
||||||
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
|
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
|
||||||
|
|
||||||
if (zcmd_write_src_nvlist(hdl, &zc, nvl) != 0)
|
if ((ret = zcmd_write_src_nvlist(hdl, &zc, nvl)) != 0 ||
|
||||||
|
(ret = zcmd_alloc_dst_nvlist(hdl, &zc, 0)) != 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
|
ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
zfs_setprop_error(hdl, prop, errno, errbuf);
|
/* Get the list of unset properties back and report them. */
|
||||||
|
nvlist_t *errorprops = NULL;
|
||||||
|
if (zcmd_read_dst_nvlist(hdl, &zc, &errorprops) != 0)
|
||||||
|
goto error;
|
||||||
|
for (nvpair_t *elem = nvlist_next_nvpair(nvl, NULL);
|
||||||
|
elem != NULL;
|
||||||
|
elem = nvlist_next_nvpair(nvl, elem)) {
|
||||||
|
zfs_prop_t prop = zfs_name_to_prop(nvpair_name(elem));
|
||||||
|
zfs_setprop_error(hdl, prop, errno, errbuf);
|
||||||
|
}
|
||||||
|
nvlist_free(errorprops);
|
||||||
|
|
||||||
if (added_resv && errno == ENOSPC) {
|
if (added_resv && errno == ENOSPC) {
|
||||||
/* clean up the volsize property we tried to set */
|
/* clean up the volsize property we tried to set */
|
||||||
uint64_t old_volsize = zfs_prop_get_int(zhp,
|
uint64_t old_volsize = zfs_prop_get_int(zhp,
|
||||||
ZFS_PROP_VOLSIZE);
|
ZFS_PROP_VOLSIZE);
|
||||||
nvlist_free(nvl);
|
nvlist_free(nvl);
|
||||||
|
nvl = NULL;
|
||||||
zcmd_free_nvlists(&zc);
|
zcmd_free_nvlists(&zc);
|
||||||
|
|
||||||
if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
|
if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
|
||||||
goto error;
|
goto error;
|
||||||
if (nvlist_add_uint64(nvl,
|
if (nvlist_add_uint64(nvl,
|
||||||
@ -1638,8 +1702,13 @@ zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
|
|||||||
(void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
|
(void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (do_prefix)
|
for (cl_idx = 0; cl_idx < nvl_len; cl_idx++) {
|
||||||
ret = changelist_postfix(cl);
|
if (cls[cl_idx] != NULL) {
|
||||||
|
int clp_err = changelist_postfix(cls[cl_idx]);
|
||||||
|
if (clp_err != 0)
|
||||||
|
ret = clp_err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Refresh the statistics so the new property value
|
* Refresh the statistics so the new property value
|
||||||
@ -1652,8 +1721,13 @@ zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
|
|||||||
error:
|
error:
|
||||||
nvlist_free(nvl);
|
nvlist_free(nvl);
|
||||||
zcmd_free_nvlists(&zc);
|
zcmd_free_nvlists(&zc);
|
||||||
if (cl)
|
if (cls != NULL) {
|
||||||
changelist_free(cl);
|
for (cl_idx = 0; cl_idx < nvl_len; cl_idx++) {
|
||||||
|
if (cls[cl_idx] != NULL)
|
||||||
|
changelist_free(cls[cl_idx]);
|
||||||
|
}
|
||||||
|
free(cls);
|
||||||
|
}
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4203,7 +4277,7 @@ zfs_smb_acl_mgmt(libzfs_handle_t *hdl, char *dataset, char *path,
|
|||||||
if (cmd == ZFS_SMB_ACL_RENAME) {
|
if (cmd == ZFS_SMB_ACL_RENAME) {
|
||||||
if (nvlist_alloc(&nvlist, NV_UNIQUE_NAME, 0) != 0) {
|
if (nvlist_alloc(&nvlist, NV_UNIQUE_NAME, 0) != 0) {
|
||||||
(void) no_memory(hdl);
|
(void) no_memory(hdl);
|
||||||
return (NULL);
|
return (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -782,8 +782,9 @@ zcmd_alloc_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, size_t len)
|
|||||||
if (len == 0)
|
if (len == 0)
|
||||||
len = 16 * 1024;
|
len = 16 * 1024;
|
||||||
zc->zc_nvlist_dst_size = len;
|
zc->zc_nvlist_dst_size = len;
|
||||||
if ((zc->zc_nvlist_dst = (uint64_t)(uintptr_t)
|
zc->zc_nvlist_dst =
|
||||||
zfs_alloc(hdl, zc->zc_nvlist_dst_size)) == 0)
|
(uint64_t)(uintptr_t)zfs_alloc(hdl, zc->zc_nvlist_dst_size);
|
||||||
|
if (zc->zc_nvlist_dst == 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
@ -798,9 +799,9 @@ int
|
|||||||
zcmd_expand_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc)
|
zcmd_expand_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc)
|
||||||
{
|
{
|
||||||
free((void *)(uintptr_t)zc->zc_nvlist_dst);
|
free((void *)(uintptr_t)zc->zc_nvlist_dst);
|
||||||
if ((zc->zc_nvlist_dst = (uint64_t)(uintptr_t)
|
zc->zc_nvlist_dst =
|
||||||
zfs_alloc(hdl, zc->zc_nvlist_dst_size))
|
(uint64_t)(uintptr_t)zfs_alloc(hdl, zc->zc_nvlist_dst_size);
|
||||||
== 0)
|
if (zc->zc_nvlist_dst == 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
@ -815,6 +816,9 @@ zcmd_free_nvlists(zfs_cmd_t *zc)
|
|||||||
free((void *)(uintptr_t)zc->zc_nvlist_conf);
|
free((void *)(uintptr_t)zc->zc_nvlist_conf);
|
||||||
free((void *)(uintptr_t)zc->zc_nvlist_src);
|
free((void *)(uintptr_t)zc->zc_nvlist_src);
|
||||||
free((void *)(uintptr_t)zc->zc_nvlist_dst);
|
free((void *)(uintptr_t)zc->zc_nvlist_dst);
|
||||||
|
zc->zc_nvlist_conf = NULL;
|
||||||
|
zc->zc_nvlist_src = NULL;
|
||||||
|
zc->zc_nvlist_dst = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
Loading…
Reference in New Issue
Block a user