Skip to content

Commit 8d14897

Browse files
authored
nvlist: Add nvlist_snprintf() and zfs_dbgmsg_nvlist()
Add nvlist_snprintf() to print a nvlist to a buffer. This is basically the snprintf() version of dump_nvlist(). Along with that, add a zfs_dbgmsg_nvlist() to print out an nvlist to dbgmsg. This will aid in debugging. Reviewed-by: Alexander Motin <[email protected]> Signed-off-by: Tony Hutter <[email protected]> Closes #17215
1 parent ba03054 commit 8d14897

File tree

12 files changed

+488
-332
lines changed

12 files changed

+488
-332
lines changed

include/sys/nvpair.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,8 @@ _SYS_NVPAIR_H int nvlist_lookup_double(const nvlist_t *, const char *,
267267
double *);
268268
#endif
269269

270+
_SYS_NVPAIR_H int nvlist_snprintf(char *, size_t, nvlist_t *, int);
271+
270272
_SYS_NVPAIR_H int nvlist_lookup_nvpair(nvlist_t *, const char *, nvpair_t **);
271273
_SYS_NVPAIR_H int nvlist_lookup_nvpair_embedded_index(nvlist_t *, const char *,
272274
nvpair_t **, int *, const char **);

include/sys/zfs_debug.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ extern "C" {
3939
#define FALSE 0
4040
#endif
4141

42+
#include <sys/nvpair.h>
43+
4244
extern int zfs_flags;
4345
extern int zfs_recover;
4446
extern int zfs_free_leak_on_eio;
@@ -104,6 +106,24 @@ extern void zfs_panic_recover(const char *fmt, ...);
104106
extern void zfs_dbgmsg_init(void);
105107
extern void zfs_dbgmsg_fini(void);
106108

109+
/*
110+
* When printing an nvlist, print one beginning line with the file/func/line
111+
* number and the text "nvlist <var name>:" followed by all the nvlist lines
112+
* without the file/fun/line number. This makes the nvlist lines easy to read.
113+
*/
114+
#define zfs_dbgmsg_nvlist(nv) \
115+
if (zfs_dbgmsg_enable) { \
116+
zfs_dbgmsg("nvlist "#nv":"); \
117+
__zfs_dbgmsg_nvlist(nv); \
118+
}
119+
120+
#define zfs_dbgmsg(...) \
121+
if (zfs_dbgmsg_enable) \
122+
__dprintf(B_FALSE, __FILE__, __func__, __LINE__, __VA_ARGS__)
123+
124+
125+
extern void __zfs_dbgmsg_nvlist(nvlist_t *nv);
126+
107127
#ifndef _KERNEL
108128
extern int dprintf_find_string(const char *string);
109129
extern void zfs_dbgmsg_print(int fd, const char *tag);

lib/libnvpair/libnvpair.abi

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@
196196
<elf-symbol name='nvlist_remove_all' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
197197
<elf-symbol name='nvlist_remove_nvpair' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
198198
<elf-symbol name='nvlist_size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
199+
<elf-symbol name='nvlist_snprintf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
199200
<elf-symbol name='nvlist_unpack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
200201
<elf-symbol name='nvlist_xalloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
201202
<elf-symbol name='nvlist_xdup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -967,6 +968,13 @@
967968
<class-decl name='_IO_marker' is-struct='yes' visibility='default' is-declaration-only='yes' id='010ae0b9'/>
968969
<class-decl name='_IO_wide_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='79bd3751'/>
969970
<class-decl name='re_dfa_t' is-struct='yes' visibility='default' is-declaration-only='yes' id='b48d2441'/>
971+
<function-decl name='nvlist_snprintf' mangled-name='nvlist_snprintf' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvlist_snprintf'>
972+
<parameter type-id='26a90f95'/>
973+
<parameter type-id='b59d7dce'/>
974+
<parameter type-id='5ce45b60'/>
975+
<parameter type-id='95e97e5e'/>
976+
<return type-id='95e97e5e'/>
977+
</function-decl>
970978
<function-decl name='nvlist_next_nvpair' mangled-name='nvlist_next_nvpair' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvlist_next_nvpair'>
971979
<parameter type-id='5ce45b60'/>
972980
<parameter type-id='dace003f'/>
@@ -1126,12 +1134,6 @@
11261134
<parameter type-id='7408d286'/>
11271135
<return type-id='95e97e5e'/>
11281136
</function-decl>
1129-
<function-decl name='dcgettext' visibility='default' binding='global' size-in-bits='64'>
1130-
<parameter type-id='80f4b756'/>
1131-
<parameter type-id='80f4b756'/>
1132-
<parameter type-id='95e97e5e'/>
1133-
<return type-id='26a90f95'/>
1134-
</function-decl>
11351137
<function-decl name='regexec' visibility='default' binding='global' size-in-bits='64'>
11361138
<parameter type-id='a431a9da'/>
11371139
<parameter type-id='9d26089a'/>
@@ -1140,6 +1142,11 @@
11401142
<parameter type-id='95e97e5e'/>
11411143
<return type-id='95e97e5e'/>
11421144
</function-decl>
1145+
<function-decl name='fputs' visibility='default' binding='global' size-in-bits='64'>
1146+
<parameter type-id='9d26089a'/>
1147+
<parameter type-id='e75a27e9'/>
1148+
<return type-id='95e97e5e'/>
1149+
</function-decl>
11431150
<function-decl name='malloc' visibility='default' binding='global' size-in-bits='64'>
11441151
<parameter type-id='b59d7dce'/>
11451152
<return type-id='eaa32e2f'/>
@@ -1180,12 +1187,6 @@
11801187
<parameter is-variadic='yes'/>
11811188
<return type-id='95e97e5e'/>
11821189
</function-decl>
1183-
<function-decl name='__printf_chk' visibility='default' binding='global' size-in-bits='64'>
1184-
<parameter type-id='95e97e5e'/>
1185-
<parameter type-id='80f4b756'/>
1186-
<parameter is-variadic='yes'/>
1187-
<return type-id='95e97e5e'/>
1188-
</function-decl>
11891190
<function-decl name='nvlist_prtctl_setdest' mangled-name='nvlist_prtctl_setdest' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvlist_prtctl_setdest'>
11901191
<parameter type-id='b0c1ff8d' name='pctl'/>
11911192
<parameter type-id='822cd80b' name='fp'/>
@@ -1398,11 +1399,6 @@
13981399
<parameter type-id='b0c1ff8d' name='pctl'/>
13991400
<return type-id='48b5725f'/>
14001401
</function-decl>
1401-
<function-decl name='dump_nvlist' mangled-name='dump_nvlist' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dump_nvlist'>
1402-
<parameter type-id='5ce45b60' name='list'/>
1403-
<parameter type-id='95e97e5e' name='indent'/>
1404-
<return type-id='48b5725f'/>
1405-
</function-decl>
14061402
<function-decl name='nvpair_value_match_regex' mangled-name='nvpair_value_match_regex' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvpair_value_match_regex'>
14071403
<parameter type-id='3fa542f0' name='nvp'/>
14081404
<parameter type-id='95e97e5e' name='ai'/>
@@ -1418,6 +1414,11 @@
14181414
<parameter type-id='7d3cd834' name='ep'/>
14191415
<return type-id='95e97e5e'/>
14201416
</function-decl>
1417+
<function-decl name='dump_nvlist' mangled-name='dump_nvlist' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dump_nvlist'>
1418+
<parameter type-id='5ce45b60' name='list'/>
1419+
<parameter type-id='95e97e5e' name='indent'/>
1420+
<return type-id='48b5725f'/>
1421+
</function-decl>
14211422
<function-type size-in-bits='64' id='9f88f76e'>
14221423
<parameter type-id='196db161'/>
14231424
<parameter type-id='eaa32e2f'/>
@@ -2194,6 +2195,7 @@
21942195
</data-member>
21952196
</class-decl>
21962197
<typedef-decl name='stack_t' type-id='380f9954' id='ac5e685f'/>
2198+
<typedef-decl name='unw_regnum_t' type-id='95e97e5e' id='c53620f0'/>
21972199
<class-decl name='unw_cursor' size-in-bits='8128' is-struct='yes' visibility='default' id='384a1f22'>
21982200
<data-member access='public' layout-offset-in-bits='0'>
21992201
<var-decl name='opaque' type-id='dc70ec0b' visibility='default'/>
@@ -2306,6 +2308,10 @@
23062308
<parameter type-id='b59d7dce'/>
23072309
<return type-id='79a0948f'/>
23082310
</function-decl>
2311+
<function-decl name='_Ux86_64_regname' visibility='default' binding='global' size-in-bits='64'>
2312+
<parameter type-id='c53620f0'/>
2313+
<return type-id='80f4b756'/>
2314+
</function-decl>
23092315
<function-decl name='_ULx86_64_init_local' visibility='default' binding='global' size-in-bits='64'>
23102316
<parameter type-id='3946e4d1'/>
23112317
<parameter type-id='2e408b96'/>

lib/libnvpair/libnvpair.c

Lines changed: 27 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -783,160 +783,6 @@ nvlist_prt(nvlist_t *nvl, nvlist_prtctl_t pctl)
783783
nvlist_print_with_indent(nvl, pctl);
784784
}
785785

786-
#define NVP(elem, type, vtype, ptype, format) { \
787-
vtype value; \
788-
\
789-
(void) nvpair_value_##type(elem, &value); \
790-
(void) printf("%*s%s: " format "\n", indent, "", \
791-
nvpair_name(elem), (ptype)value); \
792-
}
793-
794-
#define NVPA(elem, type, vtype, ptype, format) { \
795-
uint_t i, count; \
796-
vtype *value; \
797-
\
798-
(void) nvpair_value_##type(elem, &value, &count); \
799-
for (i = 0; i < count; i++) { \
800-
(void) printf("%*s%s[%d]: " format "\n", indent, "", \
801-
nvpair_name(elem), i, (ptype)value[i]); \
802-
} \
803-
}
804-
805-
/*
806-
* Similar to nvlist_print() but handles arrays slightly differently.
807-
*/
808-
void
809-
dump_nvlist(nvlist_t *list, int indent)
810-
{
811-
nvpair_t *elem = NULL;
812-
boolean_t bool_value;
813-
nvlist_t *nvlist_value;
814-
nvlist_t **nvlist_array_value;
815-
uint_t i, count;
816-
817-
if (list == NULL) {
818-
return;
819-
}
820-
821-
while ((elem = nvlist_next_nvpair(list, elem)) != NULL) {
822-
switch (nvpair_type(elem)) {
823-
case DATA_TYPE_BOOLEAN:
824-
(void) printf("%*s%s\n", indent, "", nvpair_name(elem));
825-
break;
826-
827-
case DATA_TYPE_BOOLEAN_VALUE:
828-
(void) nvpair_value_boolean_value(elem, &bool_value);
829-
(void) printf("%*s%s: %s\n", indent, "",
830-
nvpair_name(elem), bool_value ? "true" : "false");
831-
break;
832-
833-
case DATA_TYPE_BYTE:
834-
NVP(elem, byte, uchar_t, int, "%u");
835-
break;
836-
837-
case DATA_TYPE_INT8:
838-
NVP(elem, int8, int8_t, int, "%d");
839-
break;
840-
841-
case DATA_TYPE_UINT8:
842-
NVP(elem, uint8, uint8_t, int, "%u");
843-
break;
844-
845-
case DATA_TYPE_INT16:
846-
NVP(elem, int16, int16_t, int, "%d");
847-
break;
848-
849-
case DATA_TYPE_UINT16:
850-
NVP(elem, uint16, uint16_t, int, "%u");
851-
break;
852-
853-
case DATA_TYPE_INT32:
854-
NVP(elem, int32, int32_t, long, "%ld");
855-
break;
856-
857-
case DATA_TYPE_UINT32:
858-
NVP(elem, uint32, uint32_t, ulong_t, "%lu");
859-
break;
860-
861-
case DATA_TYPE_INT64:
862-
NVP(elem, int64, int64_t, longlong_t, "%lld");
863-
break;
864-
865-
case DATA_TYPE_UINT64:
866-
NVP(elem, uint64, uint64_t, u_longlong_t, "%llu");
867-
break;
868-
869-
case DATA_TYPE_STRING:
870-
NVP(elem, string, const char *, const char *, "'%s'");
871-
break;
872-
873-
case DATA_TYPE_BYTE_ARRAY:
874-
NVPA(elem, byte_array, uchar_t, int, "%u");
875-
break;
876-
877-
case DATA_TYPE_INT8_ARRAY:
878-
NVPA(elem, int8_array, int8_t, int, "%d");
879-
break;
880-
881-
case DATA_TYPE_UINT8_ARRAY:
882-
NVPA(elem, uint8_array, uint8_t, int, "%u");
883-
break;
884-
885-
case DATA_TYPE_INT16_ARRAY:
886-
NVPA(elem, int16_array, int16_t, int, "%d");
887-
break;
888-
889-
case DATA_TYPE_UINT16_ARRAY:
890-
NVPA(elem, uint16_array, uint16_t, int, "%u");
891-
break;
892-
893-
case DATA_TYPE_INT32_ARRAY:
894-
NVPA(elem, int32_array, int32_t, long, "%ld");
895-
break;
896-
897-
case DATA_TYPE_UINT32_ARRAY:
898-
NVPA(elem, uint32_array, uint32_t, ulong_t, "%lu");
899-
break;
900-
901-
case DATA_TYPE_INT64_ARRAY:
902-
NVPA(elem, int64_array, int64_t, longlong_t, "%lld");
903-
break;
904-
905-
case DATA_TYPE_UINT64_ARRAY:
906-
NVPA(elem, uint64_array, uint64_t, u_longlong_t,
907-
"%llu");
908-
break;
909-
910-
case DATA_TYPE_STRING_ARRAY:
911-
NVPA(elem, string_array, const char *, const char *,
912-
"'%s'");
913-
break;
914-
915-
case DATA_TYPE_NVLIST:
916-
(void) nvpair_value_nvlist(elem, &nvlist_value);
917-
(void) printf("%*s%s:\n", indent, "",
918-
nvpair_name(elem));
919-
dump_nvlist(nvlist_value, indent + 4);
920-
break;
921-
922-
case DATA_TYPE_NVLIST_ARRAY:
923-
(void) nvpair_value_nvlist_array(elem,
924-
&nvlist_array_value, &count);
925-
for (i = 0; i < count; i++) {
926-
(void) printf("%*s%s[%u]:\n", indent, "",
927-
nvpair_name(elem), i);
928-
dump_nvlist(nvlist_array_value[i], indent + 4);
929-
}
930-
break;
931-
932-
default:
933-
(void) printf(dgettext(TEXT_DOMAIN, "bad config type "
934-
"%d for %s\n"), nvpair_type(elem),
935-
nvpair_name(elem));
936-
}
937-
}
938-
}
939-
940786
/*
941787
* ======================================================================
942788
* | |
@@ -1291,3 +1137,30 @@ nvpair_value_match(nvpair_t *nvp, int ai, const char *value, const char **ep)
12911137
{
12921138
return (nvpair_value_match_regex(nvp, ai, value, NULL, ep));
12931139
}
1140+
1141+
/*
1142+
* Similar to nvlist_print() but handles arrays slightly differently.
1143+
*/
1144+
void
1145+
dump_nvlist(nvlist_t *list, int indent)
1146+
{
1147+
int len;
1148+
char *buf;
1149+
1150+
len = nvlist_snprintf(NULL, 0, list, indent);
1151+
len++; /* Add null terminator */
1152+
1153+
buf = malloc(len);
1154+
if (buf == NULL)
1155+
return;
1156+
1157+
(void) nvlist_snprintf(buf, len, list, indent);
1158+
1159+
/*
1160+
* fputs does not have limitations on the size of the buffer being
1161+
* printed (unlike printf).
1162+
*/
1163+
fputs(buf, stdout);
1164+
1165+
free(buf);
1166+
}

0 commit comments

Comments
 (0)