Skip to content

Commit 6added3

Browse files
allanjudeandrewc12
authored andcommitted
Add support for zpool user properties
Usage: zpool set org.freebsd:comment="this is my pool" poolname Tests are based on zfs_set's user property tests. Also stop truncating property values at MAXNAMELEN, use ZFS_MAXPROPLEN. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Allan Jude <[email protected]> Signed-off-by: Mateusz Piotrowski <[email protected]> Sponsored-by: Beckhoff Automation GmbH & Co. KG. Sponsored-by: Klara Inc. Closes openzfs#11680
1 parent 9c6ebe4 commit 6added3

File tree

12 files changed

+688
-109
lines changed

12 files changed

+688
-109
lines changed

cmd/zpool/zpool_main.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6065,11 +6065,14 @@ print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
60656065
zpool_prop_get_feature(zhp, pl->pl_user_prop, property,
60666066
sizeof (property)) == 0) {
60676067
propstr = property;
6068+
} else if (zfs_prop_user(pl->pl_user_prop) &&
6069+
zpool_get_userprop(zhp, pl->pl_user_prop, property,
6070+
sizeof (property), NULL) == 0) {
6071+
propstr = property;
60686072
} else {
60696073
propstr = "-";
60706074
}
60716075

6072-
60736076
/*
60746077
* If this is being called in scripted mode, or if this is the
60756078
* last column and it is left-justified, don't include a width
@@ -10029,7 +10032,7 @@ static int
1002910032
get_callback(zpool_handle_t *zhp, void *data)
1003010033
{
1003110034
zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
10032-
char value[MAXNAMELEN];
10035+
char value[ZFS_MAXPROPLEN];
1003310036
zprop_source_t srctype;
1003410037
zprop_list_t *pl;
1003510038
int vid;
@@ -10064,6 +10067,17 @@ get_callback(zpool_handle_t *zhp, void *data)
1006410067
continue;
1006510068

1006610069
if (pl->pl_prop == ZPROP_INVAL &&
10070+
zfs_prop_user(pl->pl_user_prop)) {
10071+
srctype = ZPROP_SRC_LOCAL;
10072+
10073+
if (zpool_get_userprop(zhp, pl->pl_user_prop,
10074+
value, sizeof (value), &srctype) != 0)
10075+
continue;
10076+
10077+
zprop_print_one_property(zpool_get_name(zhp),
10078+
cbp, pl->pl_user_prop, value, srctype,
10079+
NULL, NULL);
10080+
} else if (pl->pl_prop == ZPROP_INVAL &&
1006710081
(zpool_prop_feature(pl->pl_user_prop) ||
1006810082
zpool_prop_unsupported(pl->pl_user_prop))) {
1006910083
srctype = ZPROP_SRC_LOCAL;

include/libzfs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,8 @@ _LIBZFS_H const char *zpool_get_state_str(zpool_handle_t *);
333333
_LIBZFS_H int zpool_set_prop(zpool_handle_t *, const char *, const char *);
334334
_LIBZFS_H int zpool_get_prop(zpool_handle_t *, zpool_prop_t, char *,
335335
size_t proplen, zprop_source_t *, boolean_t literal);
336+
_LIBZFS_H int zpool_get_userprop(zpool_handle_t *, const char *, char *,
337+
size_t proplen, zprop_source_t *);
336338
_LIBZFS_H uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t,
337339
zprop_source_t *);
338340
_LIBZFS_H int zpool_props_refresh(zpool_handle_t *);

lib/libzfs/libzfs.abi

Lines changed: 70 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,8 @@
259259
<elf-symbol name='tpool_suspend' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
260260
<elf-symbol name='tpool_suspended' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
261261
<elf-symbol name='tpool_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
262-
<elf-symbol name='use_color' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
263262
<elf-symbol name='update_vdev_config_dev_strs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
263+
<elf-symbol name='use_color' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
264264
<elf-symbol name='vdev_expand_proplist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
265265
<elf-symbol name='vdev_name_to_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
266266
<elf-symbol name='vdev_prop_align_right' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -495,6 +495,7 @@
495495
<elf-symbol name='zpool_get_state' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
496496
<elf-symbol name='zpool_get_state_str' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
497497
<elf-symbol name='zpool_get_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
498+
<elf-symbol name='zpool_get_userprop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
498499
<elf-symbol name='zpool_get_vdev_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
499500
<elf-symbol name='zpool_get_vdev_prop_value' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
500501
<elf-symbol name='zpool_history_unpack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -2272,32 +2273,19 @@
22722273
<parameter type-id='58603c44'/>
22732274
<return type-id='9c313c2d'/>
22742275
</function-decl>
2275-
<function-decl name='zfs_iter_children' mangled-name='zfs_iter_children' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_children'>
2276-
<parameter type-id='9200a744' name='zhp'/>
2277-
<parameter type-id='d8e49ab9' name='func'/>
2278-
<parameter type-id='eaa32e2f' name='data'/>
2279-
<return type-id='95e97e5e'/>
2280-
</function-decl>
22812276
<function-decl name='zfs_iter_children_v2' mangled-name='zfs_iter_children_v2' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_children_v2'>
2282-
<parameter type-id='9200a744' name='zhp'/>
2283-
<parameter type-id='95e97e5e' name='flags'/>
2284-
<parameter type-id='d8e49ab9' name='func'/>
2285-
<parameter type-id='eaa32e2f' name='data'/>
2286-
<return type-id='95e97e5e'/>
2287-
</function-decl>
2288-
<function-decl name='zfs_iter_dependents' mangled-name='zfs_iter_dependents' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_dependents'>
2289-
<parameter type-id='9200a744' name='zhp'/>
2290-
<parameter type-id='c19b74c3' name='allowrecursion'/>
2291-
<parameter type-id='d8e49ab9' name='func'/>
2292-
<parameter type-id='eaa32e2f' name='data'/>
2277+
<parameter type-id='9200a744'/>
2278+
<parameter type-id='95e97e5e'/>
2279+
<parameter type-id='d8e49ab9'/>
2280+
<parameter type-id='eaa32e2f'/>
22932281
<return type-id='95e97e5e'/>
22942282
</function-decl>
22952283
<function-decl name='zfs_iter_dependents_v2' mangled-name='zfs_iter_dependents_v2' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_dependents_v2'>
2296-
<parameter type-id='9200a744' name='zhp'/>
2297-
<parameter type-id='95e97e5e' name='flags'/>
2298-
<parameter type-id='c19b74c3' name='allowrecursion'/>
2299-
<parameter type-id='d8e49ab9' name='func'/>
2300-
<parameter type-id='eaa32e2f' name='data'/>
2284+
<parameter type-id='9200a744'/>
2285+
<parameter type-id='95e97e5e'/>
2286+
<parameter type-id='c19b74c3'/>
2287+
<parameter type-id='d8e49ab9'/>
2288+
<parameter type-id='eaa32e2f'/>
23012289
<return type-id='95e97e5e'/>
23022290
</function-decl>
23032291
<function-decl name='zfs_iter_mounted' mangled-name='zfs_iter_mounted' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_mounted'>
@@ -3329,17 +3317,11 @@
33293317
<parameter type-id='58603c44'/>
33303318
<return type-id='80f4b756'/>
33313319
</function-decl>
3332-
<function-decl name='zfs_iter_filesystems' mangled-name='zfs_iter_filesystems' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_filesystems'>
3333-
<parameter type-id='9200a744' name='zhp'/>
3334-
<parameter type-id='d8e49ab9' name='func'/>
3335-
<parameter type-id='eaa32e2f' name='data'/>
3336-
<return type-id='95e97e5e'/>
3337-
</function-decl>
33383320
<function-decl name='zfs_iter_filesystems_v2' mangled-name='zfs_iter_filesystems_v2' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_filesystems_v2'>
3339-
<parameter type-id='9200a744' name='zhp'/>
3340-
<parameter type-id='95e97e5e' name='flags'/>
3341-
<parameter type-id='d8e49ab9' name='func'/>
3342-
<parameter type-id='eaa32e2f' name='data'/>
3321+
<parameter type-id='9200a744'/>
3322+
<parameter type-id='95e97e5e'/>
3323+
<parameter type-id='d8e49ab9'/>
3324+
<parameter type-id='eaa32e2f'/>
33433325
<return type-id='95e97e5e'/>
33443326
</function-decl>
33453327
<function-decl name='zfs_parent_name' mangled-name='zfs_parent_name' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_parent_name'>
@@ -3912,35 +3894,20 @@
39123894
<parameter type-id='b59d7dce'/>
39133895
<return type-id='95e97e5e'/>
39143896
</function-decl>
3915-
<function-decl name='zfs_iter_snapshots' mangled-name='zfs_iter_snapshots' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_snapshots'>
3916-
<parameter type-id='9200a744' name='zhp'/>
3917-
<parameter type-id='c19b74c3' name='simple'/>
3918-
<parameter type-id='d8e49ab9' name='func'/>
3919-
<parameter type-id='eaa32e2f' name='data'/>
3920-
<parameter type-id='9c313c2d' name='min_txg'/>
3921-
<parameter type-id='9c313c2d' name='max_txg'/>
3922-
<return type-id='95e97e5e'/>
3923-
</function-decl>
39243897
<function-decl name='zfs_iter_snapshots_v2' mangled-name='zfs_iter_snapshots_v2' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_snapshots_v2'>
3925-
<parameter type-id='9200a744' name='zhp'/>
3926-
<parameter type-id='95e97e5e' name='flags'/>
3927-
<parameter type-id='d8e49ab9' name='func'/>
3928-
<parameter type-id='eaa32e2f' name='data'/>
3929-
<parameter type-id='9c313c2d' name='min_txg'/>
3930-
<parameter type-id='9c313c2d' name='max_txg'/>
3931-
<return type-id='95e97e5e'/>
3932-
</function-decl>
3933-
<function-decl name='zfs_iter_bookmarks' mangled-name='zfs_iter_bookmarks' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_bookmarks'>
3934-
<parameter type-id='9200a744' name='zhp'/>
3935-
<parameter type-id='d8e49ab9' name='func'/>
3936-
<parameter type-id='eaa32e2f' name='data'/>
3898+
<parameter type-id='9200a744'/>
3899+
<parameter type-id='95e97e5e'/>
3900+
<parameter type-id='d8e49ab9'/>
3901+
<parameter type-id='eaa32e2f'/>
3902+
<parameter type-id='9c313c2d'/>
3903+
<parameter type-id='9c313c2d'/>
39373904
<return type-id='95e97e5e'/>
39383905
</function-decl>
39393906
<function-decl name='zfs_iter_bookmarks_v2' mangled-name='zfs_iter_bookmarks_v2' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_bookmarks_v2'>
3940-
<parameter type-id='9200a744' name='zhp'/>
3941-
<parameter type-id='95e97e5e' name='flags'/>
3942-
<parameter type-id='d8e49ab9' name='func'/>
3943-
<parameter type-id='eaa32e2f' name='data'/>
3907+
<parameter type-id='9200a744'/>
3908+
<parameter type-id='95e97e5e'/>
3909+
<parameter type-id='d8e49ab9'/>
3910+
<parameter type-id='eaa32e2f'/>
39443911
<return type-id='95e97e5e'/>
39453912
</function-decl>
39463913
<function-decl name='zfs_destroy_snaps_nvl_os' mangled-name='zfs_destroy_snaps_nvl_os' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_destroy_snaps_nvl_os'>
@@ -5136,6 +5103,27 @@
51365103
<parameter type-id='5ce45b60'/>
51375104
<return type-id='9200a744'/>
51385105
</function-decl>
5106+
<function-decl name='zfs_iter_filesystems' mangled-name='zfs_iter_filesystems' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_filesystems'>
5107+
<parameter type-id='9200a744' name='zhp'/>
5108+
<parameter type-id='d8e49ab9' name='func'/>
5109+
<parameter type-id='eaa32e2f' name='data'/>
5110+
<return type-id='95e97e5e'/>
5111+
</function-decl>
5112+
<function-decl name='zfs_iter_snapshots' mangled-name='zfs_iter_snapshots' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_snapshots'>
5113+
<parameter type-id='9200a744' name='zhp'/>
5114+
<parameter type-id='c19b74c3' name='simple'/>
5115+
<parameter type-id='d8e49ab9' name='func'/>
5116+
<parameter type-id='eaa32e2f' name='data'/>
5117+
<parameter type-id='9c313c2d' name='min_txg'/>
5118+
<parameter type-id='9c313c2d' name='max_txg'/>
5119+
<return type-id='95e97e5e'/>
5120+
</function-decl>
5121+
<function-decl name='zfs_iter_bookmarks' mangled-name='zfs_iter_bookmarks' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_bookmarks'>
5122+
<parameter type-id='9200a744' name='zhp'/>
5123+
<parameter type-id='d8e49ab9' name='func'/>
5124+
<parameter type-id='eaa32e2f' name='data'/>
5125+
<return type-id='95e97e5e'/>
5126+
</function-decl>
51395127
<function-decl name='zfs_iter_snapshots_sorted' mangled-name='zfs_iter_snapshots_sorted' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_snapshots_sorted'>
51405128
<parameter type-id='9200a744' name='zhp'/>
51415129
<parameter type-id='d8e49ab9' name='callback'/>
@@ -5168,6 +5156,19 @@
51685156
<parameter type-id='eaa32e2f' name='arg'/>
51695157
<return type-id='95e97e5e'/>
51705158
</function-decl>
5159+
<function-decl name='zfs_iter_children' mangled-name='zfs_iter_children' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_children'>
5160+
<parameter type-id='9200a744' name='zhp'/>
5161+
<parameter type-id='d8e49ab9' name='func'/>
5162+
<parameter type-id='eaa32e2f' name='data'/>
5163+
<return type-id='95e97e5e'/>
5164+
</function-decl>
5165+
<function-decl name='zfs_iter_dependents' mangled-name='zfs_iter_dependents' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_dependents'>
5166+
<parameter type-id='9200a744' name='zhp'/>
5167+
<parameter type-id='c19b74c3' name='allowrecursion'/>
5168+
<parameter type-id='d8e49ab9' name='func'/>
5169+
<parameter type-id='eaa32e2f' name='data'/>
5170+
<return type-id='95e97e5e'/>
5171+
</function-decl>
51715172
</abi-instr>
51725173
<abi-instr address-size='64' path='lib/libzfs/libzfs_mount.c' language='LANG_C99'>
51735174
<array-type-def dimensions='1' type-id='6028cbfe' size-in-bits='256' id='b39b9aa7'>
@@ -5400,9 +5401,6 @@
54005401
<parameter type-id='9cf59a50'/>
54015402
<return type-id='48b5725f'/>
54025403
</function-decl>
5403-
<function-decl name='use_color' mangled-name='use_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='use_color'>
5404-
<return type-id='95e97e5e'/>
5405-
</function-decl>
54065404
<function-decl name='mkdirp' mangled-name='mkdirp' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mkdirp'>
54075405
<parameter type-id='80f4b756'/>
54085406
<parameter type-id='d50d396c'/>
@@ -6174,6 +6172,14 @@
61746172
<parameter type-id='4c81de99' name='zhp'/>
61756173
<return type-id='80f4b756'/>
61766174
</function-decl>
6175+
<function-decl name='zpool_get_userprop' mangled-name='zpool_get_userprop' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_userprop'>
6176+
<parameter type-id='4c81de99' name='zhp'/>
6177+
<parameter type-id='80f4b756' name='propname'/>
6178+
<parameter type-id='26a90f95' name='buf'/>
6179+
<parameter type-id='b59d7dce' name='len'/>
6180+
<parameter type-id='debc6aa3' name='srctype'/>
6181+
<return type-id='95e97e5e'/>
6182+
</function-decl>
61776183
<function-decl name='zpool_set_prop' mangled-name='zpool_set_prop' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_set_prop'>
61786184
<parameter type-id='4c81de99' name='zhp'/>
61796185
<parameter type-id='80f4b756' name='propname'/>
@@ -7857,6 +7863,9 @@
78577863
<function-decl name='zfs_version_print' mangled-name='zfs_version_print' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_version_print'>
78587864
<return type-id='95e97e5e'/>
78597865
</function-decl>
7866+
<function-decl name='use_color' mangled-name='use_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='use_color'>
7867+
<return type-id='95e97e5e'/>
7868+
</function-decl>
78607869
<function-decl name='printf_color' mangled-name='printf_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='printf_color'>
78617870
<parameter type-id='80f4b756' name='color'/>
78627871
<parameter type-id='80f4b756' name='format'/>

lib/libzfs/libzfs_pool.c

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,37 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf,
425425
return (0);
426426
}
427427

428+
/*
429+
* Get a zpool property value for 'propname' and return the value in
430+
* a pre-allocated buffer.
431+
*/
432+
int
433+
zpool_get_userprop(zpool_handle_t *zhp, const char *propname, char *buf,
434+
size_t len, zprop_source_t *srctype)
435+
{
436+
nvlist_t *nv, *nvl;
437+
uint64_t ival;
438+
const char *value;
439+
zprop_source_t source = ZPROP_SRC_LOCAL;
440+
441+
nvl = zhp->zpool_props;
442+
if (nvlist_lookup_nvlist(nvl, propname, &nv) == 0) {
443+
if (nvlist_lookup_uint64(nv, ZPROP_SOURCE, &ival) == 0)
444+
source = ival;
445+
verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0);
446+
} else {
447+
source = ZPROP_SRC_DEFAULT;
448+
value = "-";
449+
}
450+
451+
if (srctype)
452+
*srctype = source;
453+
454+
(void) strlcpy(buf, value, len);
455+
456+
return (0);
457+
}
458+
428459
/*
429460
* Check if the bootfs name has the same pool name as it is set to.
430461
* Assuming bootfs is a valid dataset name.
@@ -548,6 +579,44 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
548579
(void) no_memory(hdl);
549580
goto error;
550581
}
582+
continue;
583+
} else if (prop == ZPOOL_PROP_INVAL &&
584+
zfs_prop_user(propname)) {
585+
/*
586+
* This is a user property: make sure it's a
587+
* string, and that it's less than ZAP_MAXNAMELEN.
588+
*/
589+
if (nvpair_type(elem) != DATA_TYPE_STRING) {
590+
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
591+
"'%s' must be a string"), propname);
592+
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
593+
goto error;
594+
}
595+
596+
if (strlen(nvpair_name(elem)) >= ZAP_MAXNAMELEN) {
597+
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
598+
"property name '%s' is too long"),
599+
propname);
600+
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
601+
goto error;
602+
}
603+
604+
(void) nvpair_value_string(elem, &strval);
605+
606+
if (strlen(strval) >= ZFS_MAXPROPLEN) {
607+
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
608+
"property value '%s' is too long"),
609+
strval);
610+
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
611+
goto error;
612+
}
613+
614+
if (nvlist_add_string(retprops, propname,
615+
strval) != 0) {
616+
(void) no_memory(hdl);
617+
goto error;
618+
}
619+
551620
continue;
552621
}
553622

@@ -854,9 +923,30 @@ zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp,
854923
features = zpool_get_features(zhp);
855924

856925
if ((*plp)->pl_all && firstexpand) {
926+
/* Handle userprops in the all properties case */
927+
if (zhp->zpool_props == NULL && zpool_props_refresh(zhp))
928+
return (-1);
929+
930+
nvp = NULL;
931+
while ((nvp = nvlist_next_nvpair(zhp->zpool_props, nvp)) !=
932+
NULL) {
933+
const char *propname = nvpair_name(nvp);
934+
935+
if (!zfs_prop_user(propname))
936+
continue;
937+
938+
entry = zfs_alloc(hdl, sizeof (zprop_list_t));
939+
entry->pl_prop = ZPROP_USERPROP;
940+
entry->pl_user_prop = zfs_strdup(hdl, propname);
941+
entry->pl_width = strlen(entry->pl_user_prop);
942+
entry->pl_all = B_TRUE;
943+
944+
*last = entry;
945+
last = &entry->pl_next;
946+
}
947+
857948
for (i = 0; i < SPA_FEATURES; i++) {
858-
zprop_list_t *entry = zfs_alloc(hdl,
859-
sizeof (zprop_list_t));
949+
entry = zfs_alloc(hdl, sizeof (zprop_list_t));
860950
entry->pl_prop = ZPROP_USERPROP;
861951
entry->pl_user_prop = zfs_asprintf(hdl, "feature@%s",
862952
spa_feature_table[i].fi_uname);
@@ -873,7 +963,6 @@ zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp,
873963
nvp != NULL; nvp = nvlist_next_nvpair(features, nvp)) {
874964
char *propname;
875965
boolean_t found;
876-
zprop_list_t *entry;
877966

878967
if (zfeature_is_supported(nvpair_name(nvp)))
879968
continue;
@@ -919,6 +1008,12 @@ zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp,
9191008
NULL, literal) == 0) {
9201009
if (strlen(buf) > entry->pl_width)
9211010
entry->pl_width = strlen(buf);
1011+
} else if (entry->pl_prop == ZPROP_INVAL &&
1012+
zfs_prop_user(entry->pl_user_prop) &&
1013+
zpool_get_userprop(zhp, entry->pl_user_prop, buf,
1014+
sizeof (buf), NULL) == 0) {
1015+
if (strlen(buf) > entry->pl_width)
1016+
entry->pl_width = strlen(buf);
9221017
}
9231018
}
9241019

0 commit comments

Comments
 (0)