mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 03:09:34 +03:00
Illumos 5745 - zfs set allows only one dataset property to be set at a time
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> References: https://www.illumos.org/issues/5745 https://github.com/illumos/illumos-gate/commit/3092556 Porting notes: - Fix the missing braces around initializer, zfs_cmd_t zc = {"\0"}; - Remove extra format argument in zfs_do_set() - Declare at the top: - zfs_prop_t prop; - nvpair_t *elem; - nvpair_t *next; - int i; - Additionally initialize: - int added_resv = 0; - zfs_prop_t prop = 0; - Assign 0 install of NULL for uint64_t types. - zc->zc_nvlist_conf = '\0'; - zc->zc_nvlist_src = '\0'; - zc->zc_nvlist_dst = '\0'; Ported-by: kernelOfTruth kerneloftruth@gmail.com Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #3574
This commit is contained in:
parent
f5f087eb88
commit
23de906c72
@ -263,7 +263,7 @@ get_usage(zfs_help_t idx)
|
|||||||
"\tsend [-Le] [-i snapshot|bookmark] "
|
"\tsend [-Le] [-i snapshot|bookmark] "
|
||||||
"<filesystem|volume|snapshot>\n"));
|
"<filesystem|volume|snapshot>\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"));
|
||||||
@ -478,15 +478,18 @@ 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)
|
parseprop(nvlist_t *props, char *propname)
|
||||||
{
|
{
|
||||||
char *propname = optarg;
|
|
||||||
char *propval, *strval;
|
char *propval, *strval;
|
||||||
|
|
||||||
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';
|
||||||
@ -647,7 +650,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))
|
if (parseprop(props, optarg) != 0)
|
||||||
return (1);
|
return (1);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
@ -789,7 +792,7 @@ zfs_do_create(int argc, char **argv)
|
|||||||
nomem();
|
nomem();
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
if (parseprop(props))
|
if (parseprop(props, optarg))
|
||||||
goto error;
|
goto error;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
@ -3472,21 +3475,17 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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 "
|
||||||
@ -3505,8 +3504,10 @@ 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;
|
||||||
|
int i;
|
||||||
|
|
||||||
/* check for options */
|
/* check for options */
|
||||||
if (argc > 1 && argv[1][0] == '-') {
|
if (argc > 1 && argv[1][0] == '-') {
|
||||||
@ -3517,36 +3518,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 (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"));
|
||||||
|
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 (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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3606,7 +3622,7 @@ zfs_do_snapshot(int argc, char **argv)
|
|||||||
while ((c = getopt(argc, argv, "ro:")) != -1) {
|
while ((c = getopt(argc, argv, "ro:")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'o':
|
case 'o':
|
||||||
if (parseprop(props))
|
if (parseprop(props, optarg))
|
||||||
return (1);
|
return (1);
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
|
@ -21,7 +21,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 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) 2013 Steven Hartland. All rights reserved.
|
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
||||||
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
|
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
|
||||||
@ -452,6 +452,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,
|
||||||
|
@ -1523,15 +1523,10 @@ zfs_is_namespace_prop(zfs_prop_t prop)
|
|||||||
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 = 0;
|
|
||||||
|
|
||||||
(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'"),
|
||||||
@ -1543,65 +1538,135 @@ 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 = 0;
|
||||||
|
zfs_prop_t prop = 0;
|
||||||
|
nvpair_t *elem;
|
||||||
|
|
||||||
|
(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);
|
|
||||||
|
|
||||||
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 (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 (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 (elem = nvlist_next_nvpair(nvl, NULL);
|
||||||
|
elem != NULL;
|
||||||
|
elem = nvlist_next_nvpair(nvl, elem)) {
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (elem = nvlist_next_nvpair(nvl, NULL);
|
||||||
|
elem != NULL;
|
||||||
|
elem = nvlist_next_nvpair(nvl, elem)) {
|
||||||
|
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,
|
||||||
@ -1613,8 +1678,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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/*
|
/*
|
||||||
@ -1637,8 +1707,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4094,6 +4169,7 @@ void
|
|||||||
zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props)
|
zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props)
|
||||||
{
|
{
|
||||||
nvpair_t *curr;
|
nvpair_t *curr;
|
||||||
|
nvpair_t *next;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keep a reference to the props-table against which we prune the
|
* Keep a reference to the props-table against which we prune the
|
||||||
@ -4105,7 +4181,7 @@ zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props)
|
|||||||
|
|
||||||
while (curr) {
|
while (curr) {
|
||||||
zfs_prop_t zfs_prop = zfs_name_to_prop(nvpair_name(curr));
|
zfs_prop_t zfs_prop = zfs_name_to_prop(nvpair_name(curr));
|
||||||
nvpair_t *next = nvlist_next_nvpair(zhp->zfs_props, curr);
|
next = nvlist_next_nvpair(zhp->zfs_props, curr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* User properties will result in ZPROP_INVAL, and since we
|
* User properties will result in ZPROP_INVAL, and since we
|
||||||
@ -4136,7 +4212,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 (-1);
|
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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1069,8 +1069,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);
|
||||||
@ -1085,8 +1086,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)) == 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);
|
||||||
@ -1101,6 +1103,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 = 0;
|
||||||
|
zc->zc_nvlist_src = 0;
|
||||||
|
zc->zc_nvlist_dst = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
|
.\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
.\" Copyright 2011 Joshua M. Clulow <josh@sysmgr.org>
|
.\" Copyright 2011 Joshua M. Clulow <josh@sysmgr.org>
|
||||||
.\" Copyright (c) 2014 by Delphix. All rights reserved.
|
.\" Copyright (c) 2011, 2014 by Delphix. All rights reserved.
|
||||||
.\" Copyright (c) 2014, Joyent, Inc. All rights reserved.
|
.\" Copyright (c) 2014, Joyent, Inc. All rights reserved.
|
||||||
.\" Copyright 2012 Nexenta Systems, Inc. All Rights Reserved.
|
.\" Copyright 2012 Nexenta Systems, Inc. All Rights Reserved.
|
||||||
.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||||
@ -106,7 +106,7 @@ zfs \- configures ZFS file systems
|
|||||||
|
|
||||||
.LP
|
.LP
|
||||||
.nf
|
.nf
|
||||||
\fBzfs\fR \fBset\fR \fIproperty\fR=\fIvalue\fR \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR ...
|
+\fBzfs\fR \fBset\fR \fIproperty\fR=\fIvalue\fR... \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR...
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
.LP
|
.LP
|
||||||
@ -2169,11 +2169,19 @@ A comma-separated list of types to display, where \fItype\fR is one of \fBfilesy
|
|||||||
.ne 2
|
.ne 2
|
||||||
.mk
|
.mk
|
||||||
.na
|
.na
|
||||||
\fB\fBzfs set\fR \fIproperty\fR=\fIvalue\fR \fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR ...\fR
|
\fB\fBzfs set\fR \fIproperty\fR=\fIvalue\fR[ \fIproperty\fR=\fIvalue\fR]...
|
||||||
|
\fIfilesystem\fR|\fIvolume\fR|\fIsnapshot\fR ...\fR
|
||||||
.ad
|
.ad
|
||||||
.sp .6
|
.sp .6
|
||||||
.RS 4n
|
.RS 4n
|
||||||
Sets the property to the given value for each dataset. Only some properties can be edited. See the "Properties" section for more information on what properties can be set and acceptable values. Numeric values can be specified as exact values, or in a human-readable form with a suffix of \fBB\fR, \fBK\fR, \fBM\fR, \fBG\fR, \fBT\fR, \fBP\fR, \fBE\fR, \fBZ\fR (for bytes, kilobytes, megabytes, gigabytes, terabytes, petabytes, exabytes, or zettabytes, respectively). User properties can be set on snapshots. For more information, see the "User Properties" section.
|
Sets the property or list of properties to the given value(s) for each dataset.
|
||||||
|
Only some properties can be edited. See the "Properties" section for more
|
||||||
|
information on what properties can be set and acceptable values. Numeric values
|
||||||
|
can be specified as exact values, or in a human-readable form with a suffix of
|
||||||
|
\fBB\fR, \fBK\fR, \fBM\fR, \fBG\fR, \fBT\fR, \fBP\fR, \fBE\fR, \fBZ\fR (for
|
||||||
|
bytes, kilobytes, megabytes, gigabytes, terabytes, petabytes, exabytes, or
|
||||||
|
zettabytes, respectively). User properties can be set on snapshots. For more
|
||||||
|
information, see the "User Properties" section.
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
.sp
|
.sp
|
||||||
|
Loading…
Reference in New Issue
Block a user