Skip to content

Commit bd32b91

Browse files
allanjude0mp
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. Sponsored-by: Beckhoff Automation GmbH & Co. KG. Sponsored-by: Klara Inc. Co-authored-by: Mateusz Piotrowski <[email protected]> Signed-off-by: Allan Jude <[email protected]> Signed-off-by: Mateusz Piotrowski <[email protected]>
1 parent 71d191e commit bd32b91

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
@@ -6071,11 +6071,14 @@ print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
60716071
zpool_prop_get_feature(zhp, pl->pl_user_prop, property,
60726072
sizeof (property)) == 0) {
60736073
propstr = property;
6074+
} else if (zfs_prop_user(pl->pl_user_prop) &&
6075+
zpool_get_userprop(zhp, pl->pl_user_prop, property,
6076+
sizeof (property), NULL) == 0) {
6077+
propstr = property;
60746078
} else {
60756079
propstr = "-";
60766080
}
60776081

6078-
60796082
/*
60806083
* If this is being called in scripted mode, or if this is the
60816084
* last column and it is left-justified, don't include a width
@@ -10035,7 +10038,7 @@ static int
1003510038
get_callback(zpool_handle_t *zhp, void *data)
1003610039
{
1003710040
zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
10038-
char value[MAXNAMELEN];
10041+
char value[ZFS_MAXPROPLEN];
1003910042
zprop_source_t srctype;
1004010043
zprop_list_t *pl;
1004110044
int vid;
@@ -10071,6 +10074,17 @@ get_callback(zpool_handle_t *zhp, void *data)
1007110074
continue;
1007210075

1007310076
if (pl->pl_prop == ZPROP_INVAL &&
10077+
zfs_prop_user(pl->pl_user_prop)) {
10078+
srctype = ZPROP_SRC_LOCAL;
10079+
10080+
if (zpool_get_userprop(zhp, pl->pl_user_prop,
10081+
value, sizeof (value), &srctype) != 0)
10082+
continue;
10083+
10084+
zprop_print_one_property(zpool_get_name(zhp),
10085+
cbp, pl->pl_user_prop, value, srctype,
10086+
NULL, NULL);
10087+
} else if (pl->pl_prop == ZPROP_INVAL &&
1007410088
(zpool_prop_feature(pl->pl_user_prop) ||
1007510089
zpool_prop_unsupported(pl->pl_user_prop))) {
1007610090
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'/>
@@ -492,6 +492,7 @@
492492
<elf-symbol name='zpool_get_state' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
493493
<elf-symbol name='zpool_get_state_str' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
494494
<elf-symbol name='zpool_get_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
495+
<elf-symbol name='zpool_get_userprop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
495496
<elf-symbol name='zpool_get_vdev_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
496497
<elf-symbol name='zpool_get_vdev_prop_value' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
497498
<elf-symbol name='zpool_history_unpack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -2267,32 +2268,19 @@
22672268
<parameter type-id='58603c44'/>
22682269
<return type-id='9c313c2d'/>
22692270
</function-decl>
2270-
<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'>
2271-
<parameter type-id='9200a744' name='zhp'/>
2272-
<parameter type-id='d8e49ab9' name='func'/>
2273-
<parameter type-id='eaa32e2f' name='data'/>
2274-
<return type-id='95e97e5e'/>
2275-
</function-decl>
22762271
<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'>
2277-
<parameter type-id='9200a744' name='zhp'/>
2278-
<parameter type-id='95e97e5e' name='flags'/>
2279-
<parameter type-id='d8e49ab9' name='func'/>
2280-
<parameter type-id='eaa32e2f' name='data'/>
2281-
<return type-id='95e97e5e'/>
2282-
</function-decl>
2283-
<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'>
2284-
<parameter type-id='9200a744' name='zhp'/>
2285-
<parameter type-id='c19b74c3' name='allowrecursion'/>
2286-
<parameter type-id='d8e49ab9' name='func'/>
2287-
<parameter type-id='eaa32e2f' name='data'/>
2272+
<parameter type-id='9200a744'/>
2273+
<parameter type-id='95e97e5e'/>
2274+
<parameter type-id='d8e49ab9'/>
2275+
<parameter type-id='eaa32e2f'/>
22882276
<return type-id='95e97e5e'/>
22892277
</function-decl>
22902278
<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'>
2291-
<parameter type-id='9200a744' name='zhp'/>
2292-
<parameter type-id='95e97e5e' name='flags'/>
2293-
<parameter type-id='c19b74c3' name='allowrecursion'/>
2294-
<parameter type-id='d8e49ab9' name='func'/>
2295-
<parameter type-id='eaa32e2f' name='data'/>
2279+
<parameter type-id='9200a744'/>
2280+
<parameter type-id='95e97e5e'/>
2281+
<parameter type-id='c19b74c3'/>
2282+
<parameter type-id='d8e49ab9'/>
2283+
<parameter type-id='eaa32e2f'/>
22962284
<return type-id='95e97e5e'/>
22972285
</function-decl>
22982286
<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'>
@@ -3324,17 +3312,11 @@
33243312
<parameter type-id='58603c44'/>
33253313
<return type-id='80f4b756'/>
33263314
</function-decl>
3327-
<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'>
3328-
<parameter type-id='9200a744' name='zhp'/>
3329-
<parameter type-id='d8e49ab9' name='func'/>
3330-
<parameter type-id='eaa32e2f' name='data'/>
3331-
<return type-id='95e97e5e'/>
3332-
</function-decl>
33333315
<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'>
3334-
<parameter type-id='9200a744' name='zhp'/>
3335-
<parameter type-id='95e97e5e' name='flags'/>
3336-
<parameter type-id='d8e49ab9' name='func'/>
3337-
<parameter type-id='eaa32e2f' name='data'/>
3316+
<parameter type-id='9200a744'/>
3317+
<parameter type-id='95e97e5e'/>
3318+
<parameter type-id='d8e49ab9'/>
3319+
<parameter type-id='eaa32e2f'/>
33383320
<return type-id='95e97e5e'/>
33393321
</function-decl>
33403322
<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'>
@@ -3907,35 +3889,20 @@
39073889
<parameter type-id='b59d7dce'/>
39083890
<return type-id='95e97e5e'/>
39093891
</function-decl>
3910-
<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'>
3911-
<parameter type-id='9200a744' name='zhp'/>
3912-
<parameter type-id='c19b74c3' name='simple'/>
3913-
<parameter type-id='d8e49ab9' name='func'/>
3914-
<parameter type-id='eaa32e2f' name='data'/>
3915-
<parameter type-id='9c313c2d' name='min_txg'/>
3916-
<parameter type-id='9c313c2d' name='max_txg'/>
3917-
<return type-id='95e97e5e'/>
3918-
</function-decl>
39193892
<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'>
3920-
<parameter type-id='9200a744' name='zhp'/>
3921-
<parameter type-id='95e97e5e' name='flags'/>
3922-
<parameter type-id='d8e49ab9' name='func'/>
3923-
<parameter type-id='eaa32e2f' name='data'/>
3924-
<parameter type-id='9c313c2d' name='min_txg'/>
3925-
<parameter type-id='9c313c2d' name='max_txg'/>
3926-
<return type-id='95e97e5e'/>
3927-
</function-decl>
3928-
<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'>
3929-
<parameter type-id='9200a744' name='zhp'/>
3930-
<parameter type-id='d8e49ab9' name='func'/>
3931-
<parameter type-id='eaa32e2f' name='data'/>
3893+
<parameter type-id='9200a744'/>
3894+
<parameter type-id='95e97e5e'/>
3895+
<parameter type-id='d8e49ab9'/>
3896+
<parameter type-id='eaa32e2f'/>
3897+
<parameter type-id='9c313c2d'/>
3898+
<parameter type-id='9c313c2d'/>
39323899
<return type-id='95e97e5e'/>
39333900
</function-decl>
39343901
<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'>
3935-
<parameter type-id='9200a744' name='zhp'/>
3936-
<parameter type-id='95e97e5e' name='flags'/>
3937-
<parameter type-id='d8e49ab9' name='func'/>
3938-
<parameter type-id='eaa32e2f' name='data'/>
3902+
<parameter type-id='9200a744'/>
3903+
<parameter type-id='95e97e5e'/>
3904+
<parameter type-id='d8e49ab9'/>
3905+
<parameter type-id='eaa32e2f'/>
39393906
<return type-id='95e97e5e'/>
39403907
</function-decl>
39413908
<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'>
@@ -5131,6 +5098,27 @@
51315098
<parameter type-id='5ce45b60'/>
51325099
<return type-id='9200a744'/>
51335100
</function-decl>
5101+
<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'>
5102+
<parameter type-id='9200a744' name='zhp'/>
5103+
<parameter type-id='d8e49ab9' name='func'/>
5104+
<parameter type-id='eaa32e2f' name='data'/>
5105+
<return type-id='95e97e5e'/>
5106+
</function-decl>
5107+
<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'>
5108+
<parameter type-id='9200a744' name='zhp'/>
5109+
<parameter type-id='c19b74c3' name='simple'/>
5110+
<parameter type-id='d8e49ab9' name='func'/>
5111+
<parameter type-id='eaa32e2f' name='data'/>
5112+
<parameter type-id='9c313c2d' name='min_txg'/>
5113+
<parameter type-id='9c313c2d' name='max_txg'/>
5114+
<return type-id='95e97e5e'/>
5115+
</function-decl>
5116+
<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'>
5117+
<parameter type-id='9200a744' name='zhp'/>
5118+
<parameter type-id='d8e49ab9' name='func'/>
5119+
<parameter type-id='eaa32e2f' name='data'/>
5120+
<return type-id='95e97e5e'/>
5121+
</function-decl>
51345122
<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'>
51355123
<parameter type-id='9200a744' name='zhp'/>
51365124
<parameter type-id='d8e49ab9' name='callback'/>
@@ -5163,6 +5151,19 @@
51635151
<parameter type-id='eaa32e2f' name='arg'/>
51645152
<return type-id='95e97e5e'/>
51655153
</function-decl>
5154+
<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'>
5155+
<parameter type-id='9200a744' name='zhp'/>
5156+
<parameter type-id='d8e49ab9' name='func'/>
5157+
<parameter type-id='eaa32e2f' name='data'/>
5158+
<return type-id='95e97e5e'/>
5159+
</function-decl>
5160+
<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'>
5161+
<parameter type-id='9200a744' name='zhp'/>
5162+
<parameter type-id='c19b74c3' name='allowrecursion'/>
5163+
<parameter type-id='d8e49ab9' name='func'/>
5164+
<parameter type-id='eaa32e2f' name='data'/>
5165+
<return type-id='95e97e5e'/>
5166+
</function-decl>
51665167
</abi-instr>
51675168
<abi-instr address-size='64' path='lib/libzfs/libzfs_mount.c' language='LANG_C99'>
51685169
<array-type-def dimensions='1' type-id='6028cbfe' size-in-bits='256' id='b39b9aa7'>
@@ -5395,9 +5396,6 @@
53955396
<parameter type-id='9cf59a50'/>
53965397
<return type-id='48b5725f'/>
53975398
</function-decl>
5398-
<function-decl name='use_color' mangled-name='use_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='use_color'>
5399-
<return type-id='95e97e5e'/>
5400-
</function-decl>
54015399
<function-decl name='mkdirp' mangled-name='mkdirp' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mkdirp'>
54025400
<parameter type-id='80f4b756'/>
54035401
<parameter type-id='d50d396c'/>
@@ -6168,6 +6166,14 @@
61686166
<parameter type-id='4c81de99' name='zhp'/>
61696167
<return type-id='80f4b756'/>
61706168
</function-decl>
6169+
<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'>
6170+
<parameter type-id='4c81de99' name='zhp'/>
6171+
<parameter type-id='80f4b756' name='propname'/>
6172+
<parameter type-id='26a90f95' name='buf'/>
6173+
<parameter type-id='b59d7dce' name='len'/>
6174+
<parameter type-id='debc6aa3' name='srctype'/>
6175+
<return type-id='95e97e5e'/>
6176+
</function-decl>
61716177
<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'>
61726178
<parameter type-id='4c81de99' name='zhp'/>
61736179
<parameter type-id='80f4b756' name='propname'/>
@@ -7851,6 +7857,9 @@
78517857
<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'>
78527858
<return type-id='95e97e5e'/>
78537859
</function-decl>
7860+
<function-decl name='use_color' mangled-name='use_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='use_color'>
7861+
<return type-id='95e97e5e'/>
7862+
</function-decl>
78547863
<function-decl name='printf_color' mangled-name='printf_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='printf_color'>
78557864
<parameter type-id='80f4b756' name='color'/>
78567865
<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
@@ -426,6 +426,37 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf,
426426
return (0);
427427
}
428428

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

@@ -855,9 +924,30 @@ zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp,
855924
features = zpool_get_features(zhp);
856925

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

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

0 commit comments

Comments
 (0)