Print this page
2619 asynchronous destruction of ZFS file systems
2747 SPA versioning with zfs feature flags
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <gwilson@delphix.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com>
Approved by: Dan McDonald <danmcd@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/libnvpair/libnvpair.c
+++ new/usr/src/lib/libnvpair/libnvpair.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
23 + * Copyright (c) 2012 by Delphix. All rights reserved.
23 24 */
24 25
25 26 #include <unistd.h>
26 27 #include <strings.h>
27 28 #include <libintl.h>
28 29 #include <sys/types.h>
29 30 #include <sys/inttypes.h>
30 31 #include <stdarg.h>
31 32 #include <note.h>
32 33 #include "libnvpair.h"
33 34
34 35 /*
35 36 * libnvpair - A tools library for manipulating <name, value> pairs.
36 37 *
37 38 * This library provides routines packing an unpacking nv pairs
38 39 * for transporting data across process boundaries, transporting
39 40 * between kernel and userland, and possibly saving onto disk files.
40 41 */
41 42
42 43 /*
43 44 * Print control structure.
44 45 */
45 46
46 47 #define DEFINEOP(opname, vtype) \
47 48 struct { \
48 49 int (*op)(struct nvlist_prtctl *, void *, nvlist_t *, \
49 50 const char *, vtype); \
50 51 void *arg; \
51 52 } opname
52 53
53 54 #define DEFINEARROP(opname, vtype) \
54 55 struct { \
55 56 int (*op)(struct nvlist_prtctl *, void *, nvlist_t *, \
56 57 const char *, vtype, uint_t); \
57 58 void *arg; \
58 59 } opname
59 60
60 61 struct nvlist_printops {
61 62 DEFINEOP(print_boolean, int);
62 63 DEFINEOP(print_boolean_value, boolean_t);
63 64 DEFINEOP(print_byte, uchar_t);
64 65 DEFINEOP(print_int8, int8_t);
65 66 DEFINEOP(print_uint8, uint8_t);
66 67 DEFINEOP(print_int16, int16_t);
67 68 DEFINEOP(print_uint16, uint16_t);
68 69 DEFINEOP(print_int32, int32_t);
69 70 DEFINEOP(print_uint32, uint32_t);
70 71 DEFINEOP(print_int64, int64_t);
71 72 DEFINEOP(print_uint64, uint64_t);
72 73 DEFINEOP(print_double, double);
73 74 DEFINEOP(print_string, char *);
74 75 DEFINEOP(print_hrtime, hrtime_t);
75 76 DEFINEOP(print_nvlist, nvlist_t *);
76 77 DEFINEARROP(print_boolean_array, boolean_t *);
77 78 DEFINEARROP(print_byte_array, uchar_t *);
78 79 DEFINEARROP(print_int8_array, int8_t *);
79 80 DEFINEARROP(print_uint8_array, uint8_t *);
80 81 DEFINEARROP(print_int16_array, int16_t *);
81 82 DEFINEARROP(print_uint16_array, uint16_t *);
82 83 DEFINEARROP(print_int32_array, int32_t *);
83 84 DEFINEARROP(print_uint32_array, uint32_t *);
84 85 DEFINEARROP(print_int64_array, int64_t *);
85 86 DEFINEARROP(print_uint64_array, uint64_t *);
86 87 DEFINEARROP(print_string_array, char **);
87 88 DEFINEARROP(print_nvlist_array, nvlist_t **);
88 89 };
89 90
90 91 struct nvlist_prtctl {
91 92 FILE *nvprt_fp; /* output destination */
92 93 enum nvlist_indent_mode nvprt_indent_mode; /* see above */
93 94 int nvprt_indent; /* absolute indent, or tab depth */
94 95 int nvprt_indentinc; /* indent or tab increment */
95 96 const char *nvprt_nmfmt; /* member name format, max one %s */
96 97 const char *nvprt_eomfmt; /* after member format, e.g. "\n" */
97 98 const char *nvprt_btwnarrfmt; /* between array members */
98 99 int nvprt_btwnarrfmt_nl; /* nvprt_eoamfmt includes newline? */
99 100 struct nvlist_printops *nvprt_dfltops;
100 101 struct nvlist_printops *nvprt_custops;
101 102 };
102 103
103 104 #define DFLTPRTOP(pctl, type) \
104 105 ((pctl)->nvprt_dfltops->print_##type.op)
105 106
106 107 #define DFLTPRTOPARG(pctl, type) \
107 108 ((pctl)->nvprt_dfltops->print_##type.arg)
108 109
109 110 #define CUSTPRTOP(pctl, type) \
110 111 ((pctl)->nvprt_custops->print_##type.op)
111 112
112 113 #define CUSTPRTOPARG(pctl, type) \
113 114 ((pctl)->nvprt_custops->print_##type.arg)
114 115
115 116 #define RENDER(pctl, type, nvl, name, val) \
116 117 { \
117 118 int done = 0; \
118 119 if ((pctl)->nvprt_custops && CUSTPRTOP(pctl, type)) { \
119 120 done = CUSTPRTOP(pctl, type)(pctl, \
120 121 CUSTPRTOPARG(pctl, type), nvl, name, val); \
121 122 } \
122 123 if (!done) { \
123 124 (void) DFLTPRTOP(pctl, type)(pctl, \
124 125 DFLTPRTOPARG(pctl, type), nvl, name, val); \
125 126 } \
126 127 (void) fprintf(pctl->nvprt_fp, pctl->nvprt_eomfmt); \
127 128 }
128 129
129 130 #define ARENDER(pctl, type, nvl, name, arrp, count) \
130 131 { \
131 132 int done = 0; \
132 133 if ((pctl)->nvprt_custops && CUSTPRTOP(pctl, type)) { \
133 134 done = CUSTPRTOP(pctl, type)(pctl, \
134 135 CUSTPRTOPARG(pctl, type), nvl, name, arrp, count); \
135 136 } \
136 137 if (!done) { \
137 138 (void) DFLTPRTOP(pctl, type)(pctl, \
138 139 DFLTPRTOPARG(pctl, type), nvl, name, arrp, count); \
139 140 } \
140 141 (void) fprintf(pctl->nvprt_fp, pctl->nvprt_eomfmt); \
141 142 }
142 143
143 144 static void nvlist_print_with_indent(nvlist_t *, nvlist_prtctl_t);
144 145
145 146 /*
146 147 * ======================================================================
147 148 * | |
148 149 * | Indentation |
149 150 * | |
150 151 * ======================================================================
151 152 */
152 153
153 154 static void
154 155 indent(nvlist_prtctl_t pctl, int onemore)
155 156 {
156 157 int depth;
157 158
158 159 switch (pctl->nvprt_indent_mode) {
159 160 case NVLIST_INDENT_ABS:
160 161 (void) fprintf(pctl->nvprt_fp, "%*s",
161 162 pctl->nvprt_indent + onemore * pctl->nvprt_indentinc, "");
162 163 break;
163 164
164 165 case NVLIST_INDENT_TABBED:
165 166 depth = pctl->nvprt_indent + onemore;
166 167 while (depth-- > 0)
167 168 (void) fprintf(pctl->nvprt_fp, "\t");
168 169 }
169 170 }
170 171
171 172 /*
172 173 * ======================================================================
173 174 * | |
174 175 * | Default nvlist member rendering functions. |
175 176 * | |
176 177 * ======================================================================
177 178 */
178 179
179 180 /*
180 181 * Generate functions to print single-valued nvlist members.
181 182 *
182 183 * type_and_variant - suffix to form function name
183 184 * vtype - C type for the member value
184 185 * ptype - C type to cast value to for printing
185 186 * vfmt - format string for pair value, e.g "%d" or "0x%llx"
186 187 */
187 188
188 189 #define NVLIST_PRTFUNC(type_and_variant, vtype, ptype, vfmt) \
189 190 static int \
190 191 nvprint_##type_and_variant(nvlist_prtctl_t pctl, void *private, \
191 192 nvlist_t *nvl, const char *name, vtype value) \
192 193 { \
193 194 FILE *fp = pctl->nvprt_fp; \
194 195 NOTE(ARGUNUSED(private)) \
195 196 NOTE(ARGUNUSED(nvl)) \
196 197 indent(pctl, 1); \
197 198 (void) fprintf(fp, pctl->nvprt_nmfmt, name); \
198 199 (void) fprintf(fp, vfmt, (ptype)value); \
199 200 return (1); \
200 201 }
201 202
202 203 NVLIST_PRTFUNC(boolean, int, int, "%d")
203 204 NVLIST_PRTFUNC(boolean_value, boolean_t, int, "%d")
204 205 NVLIST_PRTFUNC(byte, uchar_t, uchar_t, "0x%2.2x")
205 206 NVLIST_PRTFUNC(int8, int8_t, int, "%d")
206 207 NVLIST_PRTFUNC(uint8, uint8_t, uint8_t, "0x%x")
207 208 NVLIST_PRTFUNC(int16, int16_t, int16_t, "%d")
208 209 NVLIST_PRTFUNC(uint16, uint16_t, uint16_t, "0x%x")
209 210 NVLIST_PRTFUNC(int32, int32_t, int32_t, "%d")
210 211 NVLIST_PRTFUNC(uint32, uint32_t, uint32_t, "0x%x")
211 212 NVLIST_PRTFUNC(int64, int64_t, longlong_t, "%lld")
212 213 NVLIST_PRTFUNC(uint64, uint64_t, u_longlong_t, "0x%llx")
213 214 NVLIST_PRTFUNC(double, double, double, "0x%llf")
214 215 NVLIST_PRTFUNC(string, char *, char *, "%s")
215 216 NVLIST_PRTFUNC(hrtime, hrtime_t, hrtime_t, "0x%llx")
216 217
217 218 /*
218 219 * Generate functions to print array-valued nvlist members.
219 220 */
220 221
221 222 #define NVLIST_ARRPRTFUNC(type_and_variant, vtype, ptype, vfmt) \
222 223 static int \
223 224 nvaprint_##type_and_variant(nvlist_prtctl_t pctl, void *private, \
224 225 nvlist_t *nvl, const char *name, vtype *valuep, uint_t count) \
225 226 { \
226 227 FILE *fp = pctl->nvprt_fp; \
227 228 uint_t i; \
228 229 NOTE(ARGUNUSED(private)) \
229 230 NOTE(ARGUNUSED(nvl)) \
230 231 for (i = 0; i < count; i++) { \
231 232 if (i == 0 || pctl->nvprt_btwnarrfmt_nl) { \
232 233 indent(pctl, 1); \
233 234 (void) fprintf(fp, pctl->nvprt_nmfmt, name); \
234 235 if (pctl->nvprt_btwnarrfmt_nl) \
235 236 (void) fprintf(fp, "[%d]: ", i); \
236 237 } \
237 238 if (i != 0) \
238 239 (void) fprintf(fp, pctl->nvprt_btwnarrfmt); \
239 240 (void) fprintf(fp, vfmt, (ptype)valuep[i]); \
240 241 } \
241 242 return (1); \
242 243 }
243 244
244 245 NVLIST_ARRPRTFUNC(boolean_array, boolean_t, boolean_t, "%d")
245 246 NVLIST_ARRPRTFUNC(byte_array, uchar_t, uchar_t, "0x%2.2x")
246 247 NVLIST_ARRPRTFUNC(int8_array, int8_t, int8_t, "%d")
247 248 NVLIST_ARRPRTFUNC(uint8_array, uint8_t, uint8_t, "0x%x")
248 249 NVLIST_ARRPRTFUNC(int16_array, int16_t, int16_t, "%d")
249 250 NVLIST_ARRPRTFUNC(uint16_array, uint16_t, uint16_t, "0x%x")
250 251 NVLIST_ARRPRTFUNC(int32_array, int32_t, int32_t, "%d")
251 252 NVLIST_ARRPRTFUNC(uint32_array, uint32_t, uint32_t, "0x%x")
252 253 NVLIST_ARRPRTFUNC(int64_array, int64_t, longlong_t, "%lld")
253 254 NVLIST_ARRPRTFUNC(uint64_array, uint64_t, u_longlong_t, "0x%llx")
254 255 NVLIST_ARRPRTFUNC(string_array, char *, char *, "%s")
255 256
256 257 /*ARGSUSED*/
257 258 static int
258 259 nvprint_nvlist(nvlist_prtctl_t pctl, void *private,
259 260 nvlist_t *nvl, const char *name, nvlist_t *value)
260 261 {
261 262 FILE *fp = pctl->nvprt_fp;
262 263
263 264 indent(pctl, 1);
264 265 (void) fprintf(fp, "%s = (embedded nvlist)\n", name);
265 266
266 267 pctl->nvprt_indent += pctl->nvprt_indentinc;
267 268 nvlist_print_with_indent(value, pctl);
268 269 pctl->nvprt_indent -= pctl->nvprt_indentinc;
269 270
270 271 indent(pctl, 1);
271 272 (void) fprintf(fp, "(end %s)\n", name);
272 273
273 274 return (1);
274 275 }
275 276
276 277 /*ARGSUSED*/
277 278 static int
278 279 nvaprint_nvlist_array(nvlist_prtctl_t pctl, void *private,
279 280 nvlist_t *nvl, const char *name, nvlist_t **valuep, uint_t count)
280 281 {
281 282 FILE *fp = pctl->nvprt_fp;
282 283 uint_t i;
283 284
284 285 indent(pctl, 1);
285 286 (void) fprintf(fp, "%s = (array of embedded nvlists)\n", name);
286 287
287 288 for (i = 0; i < count; i++) {
288 289 indent(pctl, 1);
289 290 (void) fprintf(fp, "(start %s[%d])\n", name, i);
290 291
291 292 pctl->nvprt_indent += pctl->nvprt_indentinc;
292 293 nvlist_print_with_indent(valuep[i], pctl);
293 294 pctl->nvprt_indent -= pctl->nvprt_indentinc;
294 295
295 296 indent(pctl, 1);
296 297 (void) fprintf(fp, "(end %s[%d])\n", name, i);
297 298 }
298 299
299 300 return (1);
300 301 }
301 302
302 303 /*
303 304 * ======================================================================
304 305 * | |
305 306 * | Interfaces that allow control over formatting. |
306 307 * | |
307 308 * ======================================================================
308 309 */
309 310
310 311 void
311 312 nvlist_prtctl_setdest(nvlist_prtctl_t pctl, FILE *fp)
312 313 {
313 314 pctl->nvprt_fp = fp;
314 315 }
315 316
316 317 FILE *
317 318 nvlist_prtctl_getdest(nvlist_prtctl_t pctl)
318 319 {
319 320 return (pctl->nvprt_fp);
320 321 }
321 322
322 323
323 324 void
324 325 nvlist_prtctl_setindent(nvlist_prtctl_t pctl, enum nvlist_indent_mode mode,
325 326 int start, int inc)
326 327 {
327 328 if (mode < NVLIST_INDENT_ABS || mode > NVLIST_INDENT_TABBED)
328 329 mode = NVLIST_INDENT_TABBED;
329 330
330 331 if (start < 0)
331 332 start = 0;
332 333
333 334 if (inc < 0)
334 335 inc = 1;
335 336
336 337 pctl->nvprt_indent_mode = mode;
337 338 pctl->nvprt_indent = start;
338 339 pctl->nvprt_indentinc = inc;
339 340 }
340 341
341 342 void
342 343 nvlist_prtctl_doindent(nvlist_prtctl_t pctl, int onemore)
343 344 {
344 345 indent(pctl, onemore);
345 346 }
346 347
347 348
348 349 void
349 350 nvlist_prtctl_setfmt(nvlist_prtctl_t pctl, enum nvlist_prtctl_fmt which,
350 351 const char *fmt)
351 352 {
352 353 switch (which) {
353 354 case NVLIST_FMT_MEMBER_NAME:
354 355 if (fmt == NULL)
355 356 fmt = "%s = ";
356 357 pctl->nvprt_nmfmt = fmt;
357 358 break;
358 359
359 360 case NVLIST_FMT_MEMBER_POSTAMBLE:
360 361 if (fmt == NULL)
361 362 fmt = "\n";
362 363 pctl->nvprt_eomfmt = fmt;
363 364 break;
364 365
365 366 case NVLIST_FMT_BTWN_ARRAY:
366 367 if (fmt == NULL) {
367 368 pctl->nvprt_btwnarrfmt = " ";
368 369 pctl->nvprt_btwnarrfmt_nl = 0;
369 370 } else {
370 371 pctl->nvprt_btwnarrfmt = fmt;
371 372 pctl->nvprt_btwnarrfmt_nl = (strstr(fmt, "\n") != NULL);
372 373 }
373 374 break;
374 375
375 376 default:
376 377 break;
377 378 }
378 379 }
379 380
380 381
381 382 void
382 383 nvlist_prtctl_dofmt(nvlist_prtctl_t pctl, enum nvlist_prtctl_fmt which, ...)
383 384 {
384 385 FILE *fp = pctl->nvprt_fp;
385 386 va_list ap;
386 387 char *name;
387 388
388 389 va_start(ap, which);
389 390
390 391 switch (which) {
391 392 case NVLIST_FMT_MEMBER_NAME:
392 393 name = va_arg(ap, char *);
393 394 (void) fprintf(fp, pctl->nvprt_nmfmt, name);
394 395 break;
395 396
396 397 case NVLIST_FMT_MEMBER_POSTAMBLE:
397 398 (void) fprintf(fp, pctl->nvprt_eomfmt);
398 399 break;
399 400
400 401 case NVLIST_FMT_BTWN_ARRAY:
401 402 (void) fprintf(fp, pctl->nvprt_btwnarrfmt); \
402 403 break;
403 404
404 405 default:
405 406 break;
406 407 }
407 408
408 409 va_end(ap);
409 410 }
410 411
411 412 /*
412 413 * ======================================================================
413 414 * | |
414 415 * | Interfaces to allow appointment of replacement rendering functions.|
415 416 * | |
416 417 * ======================================================================
417 418 */
418 419
419 420 #define NVLIST_PRINTCTL_REPLACE(type, vtype) \
420 421 void \
421 422 nvlist_prtctlop_##type(nvlist_prtctl_t pctl, \
422 423 int (*func)(nvlist_prtctl_t, void *, nvlist_t *, const char *, vtype), \
423 424 void *private) \
424 425 { \
425 426 CUSTPRTOP(pctl, type) = func; \
426 427 CUSTPRTOPARG(pctl, type) = private; \
427 428 }
428 429
429 430 NVLIST_PRINTCTL_REPLACE(boolean, int)
430 431 NVLIST_PRINTCTL_REPLACE(boolean_value, boolean_t)
431 432 NVLIST_PRINTCTL_REPLACE(byte, uchar_t)
432 433 NVLIST_PRINTCTL_REPLACE(int8, int8_t)
433 434 NVLIST_PRINTCTL_REPLACE(uint8, uint8_t)
434 435 NVLIST_PRINTCTL_REPLACE(int16, int16_t)
435 436 NVLIST_PRINTCTL_REPLACE(uint16, uint16_t)
436 437 NVLIST_PRINTCTL_REPLACE(int32, int32_t)
437 438 NVLIST_PRINTCTL_REPLACE(uint32, uint32_t)
438 439 NVLIST_PRINTCTL_REPLACE(int64, int64_t)
439 440 NVLIST_PRINTCTL_REPLACE(uint64, uint64_t)
440 441 NVLIST_PRINTCTL_REPLACE(double, double)
441 442 NVLIST_PRINTCTL_REPLACE(string, char *)
442 443 NVLIST_PRINTCTL_REPLACE(hrtime, hrtime_t)
443 444 NVLIST_PRINTCTL_REPLACE(nvlist, nvlist_t *)
444 445
445 446 #define NVLIST_PRINTCTL_AREPLACE(type, vtype) \
446 447 void \
447 448 nvlist_prtctlop_##type(nvlist_prtctl_t pctl, \
448 449 int (*func)(nvlist_prtctl_t, void *, nvlist_t *, const char *, vtype, \
449 450 uint_t), void *private) \
450 451 { \
451 452 CUSTPRTOP(pctl, type) = func; \
452 453 CUSTPRTOPARG(pctl, type) = private; \
453 454 }
454 455
455 456 NVLIST_PRINTCTL_AREPLACE(boolean_array, boolean_t *)
456 457 NVLIST_PRINTCTL_AREPLACE(byte_array, uchar_t *)
457 458 NVLIST_PRINTCTL_AREPLACE(int8_array, int8_t *)
458 459 NVLIST_PRINTCTL_AREPLACE(uint8_array, uint8_t *)
459 460 NVLIST_PRINTCTL_AREPLACE(int16_array, int16_t *)
460 461 NVLIST_PRINTCTL_AREPLACE(uint16_array, uint16_t *)
461 462 NVLIST_PRINTCTL_AREPLACE(int32_array, int32_t *)
462 463 NVLIST_PRINTCTL_AREPLACE(uint32_array, uint32_t *)
463 464 NVLIST_PRINTCTL_AREPLACE(int64_array, int64_t *)
464 465 NVLIST_PRINTCTL_AREPLACE(uint64_array, uint64_t *)
465 466 NVLIST_PRINTCTL_AREPLACE(string_array, char **)
466 467 NVLIST_PRINTCTL_AREPLACE(nvlist_array, nvlist_t **)
467 468
468 469 /*
469 470 * ======================================================================
470 471 * | |
471 472 * | Interfaces to manage nvlist_prtctl_t cookies. |
472 473 * | |
473 474 * ======================================================================
474 475 */
475 476
476 477
477 478 static const struct nvlist_printops defprtops = {
478 479 { nvprint_boolean, NULL },
479 480 { nvprint_boolean_value, NULL },
480 481 { nvprint_byte, NULL },
481 482 { nvprint_int8, NULL },
482 483 { nvprint_uint8, NULL },
483 484 { nvprint_int16, NULL },
484 485 { nvprint_uint16, NULL },
485 486 { nvprint_int32, NULL },
486 487 { nvprint_uint32, NULL },
487 488 { nvprint_int64, NULL },
488 489 { nvprint_uint64, NULL },
489 490 { nvprint_double, NULL },
490 491 { nvprint_string, NULL },
491 492 { nvprint_hrtime, NULL },
492 493 { nvprint_nvlist, NULL },
493 494 { nvaprint_boolean_array, NULL },
494 495 { nvaprint_byte_array, NULL },
495 496 { nvaprint_int8_array, NULL },
496 497 { nvaprint_uint8_array, NULL },
497 498 { nvaprint_int16_array, NULL },
498 499 { nvaprint_uint16_array, NULL },
499 500 { nvaprint_int32_array, NULL },
500 501 { nvaprint_uint32_array, NULL },
501 502 { nvaprint_int64_array, NULL },
502 503 { nvaprint_uint64_array, NULL },
503 504 { nvaprint_string_array, NULL },
504 505 { nvaprint_nvlist_array, NULL },
505 506 };
506 507
507 508 static void
508 509 prtctl_defaults(FILE *fp, struct nvlist_prtctl *pctl,
509 510 struct nvlist_printops *ops)
510 511 {
511 512 pctl->nvprt_fp = fp;
512 513 pctl->nvprt_indent_mode = NVLIST_INDENT_TABBED;
513 514 pctl->nvprt_indent = 0;
514 515 pctl->nvprt_indentinc = 1;
515 516 pctl->nvprt_nmfmt = "%s = ";
516 517 pctl->nvprt_eomfmt = "\n";
517 518 pctl->nvprt_btwnarrfmt = " ";
518 519 pctl->nvprt_btwnarrfmt_nl = 0;
519 520
520 521 pctl->nvprt_dfltops = (struct nvlist_printops *)&defprtops;
521 522 pctl->nvprt_custops = ops;
522 523 }
523 524
524 525 nvlist_prtctl_t
525 526 nvlist_prtctl_alloc(void)
526 527 {
527 528 struct nvlist_prtctl *pctl;
528 529 struct nvlist_printops *ops;
529 530
530 531 if ((pctl = malloc(sizeof (*pctl))) == NULL)
531 532 return (NULL);
532 533
533 534 if ((ops = calloc(1, sizeof (*ops))) == NULL) {
534 535 free(pctl);
535 536 return (NULL);
536 537 }
537 538
538 539 prtctl_defaults(stdout, pctl, ops);
539 540
540 541 return (pctl);
541 542 }
542 543
543 544 void
544 545 nvlist_prtctl_free(nvlist_prtctl_t pctl)
545 546 {
546 547 if (pctl != NULL) {
547 548 free(pctl->nvprt_custops);
548 549 free(pctl);
549 550 }
550 551 }
551 552
552 553 /*
553 554 * ======================================================================
554 555 * | |
555 556 * | Top-level print request interfaces. |
556 557 * | |
557 558 * ======================================================================
558 559 */
559 560
560 561 /*
561 562 * nvlist_print - Prints elements in an event buffer
562 563 */
563 564 static void
564 565 nvlist_print_with_indent(nvlist_t *nvl, nvlist_prtctl_t pctl)
565 566 {
566 567 FILE *fp = pctl->nvprt_fp;
567 568 char *name;
568 569 uint_t nelem;
569 570 nvpair_t *nvp;
570 571
571 572 if (nvl == NULL)
572 573 return;
573 574
574 575 indent(pctl, 0);
575 576 (void) fprintf(fp, "nvlist version: %d\n", NVL_VERSION(nvl));
576 577
577 578 nvp = nvlist_next_nvpair(nvl, NULL);
578 579
579 580 while (nvp) {
580 581 data_type_t type = nvpair_type(nvp);
581 582
582 583 name = nvpair_name(nvp);
583 584 nelem = 0;
584 585
585 586 switch (type) {
586 587 case DATA_TYPE_BOOLEAN: {
587 588 RENDER(pctl, boolean, nvl, name, 1);
588 589 break;
589 590 }
590 591 case DATA_TYPE_BOOLEAN_VALUE: {
591 592 boolean_t val;
592 593 (void) nvpair_value_boolean_value(nvp, &val);
593 594 RENDER(pctl, boolean_value, nvl, name, val);
594 595 break;
595 596 }
596 597 case DATA_TYPE_BYTE: {
597 598 uchar_t val;
598 599 (void) nvpair_value_byte(nvp, &val);
599 600 RENDER(pctl, byte, nvl, name, val);
600 601 break;
601 602 }
602 603 case DATA_TYPE_INT8: {
603 604 int8_t val;
604 605 (void) nvpair_value_int8(nvp, &val);
605 606 RENDER(pctl, int8, nvl, name, val);
606 607 break;
607 608 }
608 609 case DATA_TYPE_UINT8: {
609 610 uint8_t val;
610 611 (void) nvpair_value_uint8(nvp, &val);
611 612 RENDER(pctl, uint8, nvl, name, val);
612 613 break;
613 614 }
614 615 case DATA_TYPE_INT16: {
615 616 int16_t val;
616 617 (void) nvpair_value_int16(nvp, &val);
617 618 RENDER(pctl, int16, nvl, name, val);
618 619 break;
619 620 }
620 621 case DATA_TYPE_UINT16: {
621 622 uint16_t val;
622 623 (void) nvpair_value_uint16(nvp, &val);
623 624 RENDER(pctl, uint16, nvl, name, val);
624 625 break;
625 626 }
626 627 case DATA_TYPE_INT32: {
627 628 int32_t val;
628 629 (void) nvpair_value_int32(nvp, &val);
629 630 RENDER(pctl, int32, nvl, name, val);
630 631 break;
631 632 }
632 633 case DATA_TYPE_UINT32: {
633 634 uint32_t val;
634 635 (void) nvpair_value_uint32(nvp, &val);
635 636 RENDER(pctl, uint32, nvl, name, val);
636 637 break;
637 638 }
638 639 case DATA_TYPE_INT64: {
639 640 int64_t val;
640 641 (void) nvpair_value_int64(nvp, &val);
641 642 RENDER(pctl, int64, nvl, name, val);
642 643 break;
643 644 }
644 645 case DATA_TYPE_UINT64: {
645 646 uint64_t val;
646 647 (void) nvpair_value_uint64(nvp, &val);
647 648 RENDER(pctl, uint64, nvl, name, val);
648 649 break;
649 650 }
650 651 case DATA_TYPE_DOUBLE: {
651 652 double val;
652 653 (void) nvpair_value_double(nvp, &val);
653 654 RENDER(pctl, double, nvl, name, val);
654 655 break;
655 656 }
656 657 case DATA_TYPE_STRING: {
657 658 char *val;
658 659 (void) nvpair_value_string(nvp, &val);
659 660 RENDER(pctl, string, nvl, name, val);
660 661 break;
661 662 }
662 663 case DATA_TYPE_BOOLEAN_ARRAY: {
663 664 boolean_t *val;
664 665 (void) nvpair_value_boolean_array(nvp, &val, &nelem);
665 666 ARENDER(pctl, boolean_array, nvl, name, val, nelem);
666 667 break;
667 668 }
668 669 case DATA_TYPE_BYTE_ARRAY: {
669 670 uchar_t *val;
670 671 (void) nvpair_value_byte_array(nvp, &val, &nelem);
671 672 ARENDER(pctl, byte_array, nvl, name, val, nelem);
672 673 break;
673 674 }
674 675 case DATA_TYPE_INT8_ARRAY: {
675 676 int8_t *val;
676 677 (void) nvpair_value_int8_array(nvp, &val, &nelem);
677 678 ARENDER(pctl, int8_array, nvl, name, val, nelem);
678 679 break;
679 680 }
680 681 case DATA_TYPE_UINT8_ARRAY: {
681 682 uint8_t *val;
682 683 (void) nvpair_value_uint8_array(nvp, &val, &nelem);
683 684 ARENDER(pctl, uint8_array, nvl, name, val, nelem);
684 685 break;
685 686 }
686 687 case DATA_TYPE_INT16_ARRAY: {
687 688 int16_t *val;
688 689 (void) nvpair_value_int16_array(nvp, &val, &nelem);
689 690 ARENDER(pctl, int16_array, nvl, name, val, nelem);
690 691 break;
691 692 }
692 693 case DATA_TYPE_UINT16_ARRAY: {
693 694 uint16_t *val;
694 695 (void) nvpair_value_uint16_array(nvp, &val, &nelem);
695 696 ARENDER(pctl, uint16_array, nvl, name, val, nelem);
696 697 break;
697 698 }
698 699 case DATA_TYPE_INT32_ARRAY: {
699 700 int32_t *val;
700 701 (void) nvpair_value_int32_array(nvp, &val, &nelem);
701 702 ARENDER(pctl, int32_array, nvl, name, val, nelem);
702 703 break;
703 704 }
704 705 case DATA_TYPE_UINT32_ARRAY: {
705 706 uint32_t *val;
706 707 (void) nvpair_value_uint32_array(nvp, &val, &nelem);
707 708 ARENDER(pctl, uint32_array, nvl, name, val, nelem);
708 709 break;
709 710 }
710 711 case DATA_TYPE_INT64_ARRAY: {
711 712 int64_t *val;
712 713 (void) nvpair_value_int64_array(nvp, &val, &nelem);
713 714 ARENDER(pctl, int64_array, nvl, name, val, nelem);
714 715 break;
715 716 }
716 717 case DATA_TYPE_UINT64_ARRAY: {
717 718 uint64_t *val;
718 719 (void) nvpair_value_uint64_array(nvp, &val, &nelem);
719 720 ARENDER(pctl, uint64_array, nvl, name, val, nelem);
720 721 break;
721 722 }
722 723 case DATA_TYPE_STRING_ARRAY: {
723 724 char **val;
724 725 (void) nvpair_value_string_array(nvp, &val, &nelem);
725 726 ARENDER(pctl, string_array, nvl, name, val, nelem);
726 727 break;
727 728 }
728 729 case DATA_TYPE_HRTIME: {
729 730 hrtime_t val;
730 731 (void) nvpair_value_hrtime(nvp, &val);
731 732 RENDER(pctl, hrtime, nvl, name, val);
732 733 break;
733 734 }
734 735 case DATA_TYPE_NVLIST: {
735 736 nvlist_t *val;
736 737 (void) nvpair_value_nvlist(nvp, &val);
737 738 RENDER(pctl, nvlist, nvl, name, val);
738 739 break;
739 740 }
740 741 case DATA_TYPE_NVLIST_ARRAY: {
741 742 nvlist_t **val;
742 743 (void) nvpair_value_nvlist_array(nvp, &val, &nelem);
743 744 ARENDER(pctl, nvlist_array, nvl, name, val, nelem);
744 745 break;
745 746 }
746 747 default:
747 748 (void) fprintf(fp, " unknown data type (%d)", type);
748 749 break;
749 750 }
750 751 nvp = nvlist_next_nvpair(nvl, nvp);
751 752 }
752 753 }
753 754
754 755 void
755 756 nvlist_print(FILE *fp, nvlist_t *nvl)
756 757 {
757 758 struct nvlist_prtctl pc;
758 759
759 760 prtctl_defaults(fp, &pc, NULL);
760 761 nvlist_print_with_indent(nvl, &pc);
761 762 }
762 763
763 764 void
764 765 nvlist_prt(nvlist_t *nvl, nvlist_prtctl_t pctl)
765 766 {
766 767 nvlist_print_with_indent(nvl, pctl);
767 768 }
768 769
769 770 #define NVP(elem, type, vtype, ptype, format) { \
770 771 vtype value; \
771 772 \
772 773 (void) nvpair_value_##type(elem, &value); \
773 774 (void) printf("%*s%s: " format "\n", indent, "", \
774 775 nvpair_name(elem), (ptype)value); \
775 776 }
776 777
777 778 #define NVPA(elem, type, vtype, ptype, format) { \
778 779 uint_t i, count; \
779 780 vtype *value; \
780 781 \
781 782 (void) nvpair_value_##type(elem, &value, &count); \
782 783 for (i = 0; i < count; i++) { \
783 784 (void) printf("%*s%s[%d]: " format "\n", indent, "", \
784 785 nvpair_name(elem), i, (ptype)value[i]); \
785 786 } \
786 787 }
787 788
788 789 /*
789 790 * Similar to nvlist_print() but handles arrays slightly differently.
790 791 */
791 792 void
792 793 dump_nvlist(nvlist_t *list, int indent)
793 794 {
794 795 nvpair_t *elem = NULL;
795 796 boolean_t bool_value;
|
↓ open down ↓ |
763 lines elided |
↑ open up ↑ |
796 797 nvlist_t *nvlist_value;
797 798 nvlist_t **nvlist_array_value;
798 799 uint_t i, count;
799 800
800 801 if (list == NULL) {
801 802 return;
802 803 }
803 804
804 805 while ((elem = nvlist_next_nvpair(list, elem)) != NULL) {
805 806 switch (nvpair_type(elem)) {
807 + case DATA_TYPE_BOOLEAN:
808 + (void) printf("%*s%s\n", indent, "", nvpair_name(elem));
809 + break;
810 +
806 811 case DATA_TYPE_BOOLEAN_VALUE:
807 812 (void) nvpair_value_boolean_value(elem, &bool_value);
808 813 (void) printf("%*s%s: %s\n", indent, "",
809 814 nvpair_name(elem), bool_value ? "true" : "false");
810 815 break;
811 816
812 817 case DATA_TYPE_BYTE:
813 818 NVP(elem, byte, uchar_t, int, "%u");
814 819 break;
815 820
816 821 case DATA_TYPE_INT8:
817 822 NVP(elem, int8, int8_t, int, "%d");
818 823 break;
819 824
820 825 case DATA_TYPE_UINT8:
821 826 NVP(elem, uint8, uint8_t, int, "%u");
822 827 break;
823 828
824 829 case DATA_TYPE_INT16:
825 830 NVP(elem, int16, int16_t, int, "%d");
826 831 break;
827 832
828 833 case DATA_TYPE_UINT16:
829 834 NVP(elem, uint16, uint16_t, int, "%u");
830 835 break;
831 836
832 837 case DATA_TYPE_INT32:
833 838 NVP(elem, int32, int32_t, long, "%ld");
834 839 break;
835 840
836 841 case DATA_TYPE_UINT32:
837 842 NVP(elem, uint32, uint32_t, ulong_t, "%lu");
838 843 break;
839 844
840 845 case DATA_TYPE_INT64:
841 846 NVP(elem, int64, int64_t, longlong_t, "%lld");
842 847 break;
843 848
844 849 case DATA_TYPE_UINT64:
845 850 NVP(elem, uint64, uint64_t, u_longlong_t, "%llu");
846 851 break;
847 852
848 853 case DATA_TYPE_STRING:
849 854 NVP(elem, string, char *, char *, "'%s'");
850 855 break;
851 856
852 857 case DATA_TYPE_BYTE_ARRAY:
853 858 NVPA(elem, byte_array, uchar_t, int, "%u");
854 859 break;
855 860
856 861 case DATA_TYPE_INT8_ARRAY:
857 862 NVPA(elem, int8_array, int8_t, int, "%d");
858 863 break;
859 864
860 865 case DATA_TYPE_UINT8_ARRAY:
861 866 NVPA(elem, uint8_array, uint8_t, int, "%u");
862 867 break;
863 868
864 869 case DATA_TYPE_INT16_ARRAY:
865 870 NVPA(elem, int16_array, int16_t, int, "%d");
866 871 break;
867 872
868 873 case DATA_TYPE_UINT16_ARRAY:
869 874 NVPA(elem, uint16_array, uint16_t, int, "%u");
870 875 break;
871 876
872 877 case DATA_TYPE_INT32_ARRAY:
873 878 NVPA(elem, int32_array, int32_t, long, "%ld");
874 879 break;
875 880
876 881 case DATA_TYPE_UINT32_ARRAY:
877 882 NVPA(elem, uint32_array, uint32_t, ulong_t, "%lu");
878 883 break;
879 884
880 885 case DATA_TYPE_INT64_ARRAY:
881 886 NVPA(elem, int64_array, int64_t, longlong_t, "%lld");
882 887 break;
883 888
884 889 case DATA_TYPE_UINT64_ARRAY:
885 890 NVPA(elem, uint64_array, uint64_t, u_longlong_t,
886 891 "%llu");
887 892 break;
888 893
889 894 case DATA_TYPE_STRING_ARRAY:
890 895 NVPA(elem, string_array, char *, char *, "'%s'");
891 896 break;
892 897
893 898 case DATA_TYPE_NVLIST:
894 899 (void) nvpair_value_nvlist(elem, &nvlist_value);
895 900 (void) printf("%*s%s:\n", indent, "",
896 901 nvpair_name(elem));
897 902 dump_nvlist(nvlist_value, indent + 4);
898 903 break;
899 904
900 905 case DATA_TYPE_NVLIST_ARRAY:
901 906 (void) nvpair_value_nvlist_array(elem,
902 907 &nvlist_array_value, &count);
903 908 for (i = 0; i < count; i++) {
904 909 (void) printf("%*s%s[%u]:\n", indent, "",
905 910 nvpair_name(elem), i);
906 911 dump_nvlist(nvlist_array_value[i], indent + 4);
907 912 }
908 913 break;
909 914
910 915 default:
911 916 (void) printf(dgettext(TEXT_DOMAIN, "bad config type "
912 917 "%d for %s\n"), nvpair_type(elem),
913 918 nvpair_name(elem));
914 919 }
915 920 }
916 921 }
917 922
918 923 /*
919 924 * ======================================================================
920 925 * | |
921 926 * | Misc private interface. |
922 927 * | |
923 928 * ======================================================================
924 929 */
925 930
926 931 /*
927 932 * Determine if string 'value' matches 'nvp' value. The 'value' string is
928 933 * converted, depending on the type of 'nvp', prior to match. For numeric
929 934 * types, a radix independent sscanf conversion of 'value' is used. If 'nvp'
930 935 * is an array type, 'ai' is the index into the array against which we are
931 936 * checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass
932 937 * in a regex_t compilation of value in 'value_regex' to trigger regular
933 938 * expression string match instead of simple strcmp().
934 939 *
935 940 * Return 1 on match, 0 on no-match, and -1 on error. If the error is
936 941 * related to value syntax error and 'ep' is non-NULL, *ep will point into
937 942 * the 'value' string at the location where the error exists.
938 943 *
939 944 * NOTE: It may be possible to move the non-regex_t version of this into
940 945 * common code used by library/kernel/boot.
941 946 */
942 947 int
943 948 nvpair_value_match_regex(nvpair_t *nvp, int ai,
944 949 char *value, regex_t *value_regex, char **ep)
945 950 {
946 951 char *evalue;
947 952 uint_t a_len;
948 953 int sr;
949 954
950 955 if (ep)
951 956 *ep = NULL;
952 957
953 958 if ((nvp == NULL) || (value == NULL))
954 959 return (-1); /* error fail match - invalid args */
955 960
956 961 /* make sure array and index combination make sense */
957 962 if ((nvpair_type_is_array(nvp) && (ai < 0)) ||
958 963 (!nvpair_type_is_array(nvp) && (ai >= 0)))
959 964 return (-1); /* error fail match - bad index */
960 965
961 966 /* non-string values should be single 'chunk' */
962 967 if ((nvpair_type(nvp) != DATA_TYPE_STRING) &&
963 968 (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) {
964 969 value += strspn(value, " \t");
965 970 evalue = value + strcspn(value, " \t");
966 971 if (*evalue) {
967 972 if (ep)
968 973 *ep = evalue;
969 974 return (-1); /* error fail match - syntax */
970 975 }
971 976 }
972 977
973 978 sr = EOF;
974 979 switch (nvpair_type(nvp)) {
975 980 case DATA_TYPE_STRING: {
976 981 char *val;
977 982
978 983 /* check string value for match */
979 984 if (nvpair_value_string(nvp, &val) == 0) {
980 985 if (value_regex) {
981 986 if (regexec(value_regex, val,
982 987 (size_t)0, NULL, 0) == 0)
983 988 return (1); /* match */
984 989 } else {
985 990 if (strcmp(value, val) == 0)
986 991 return (1); /* match */
987 992 }
988 993 }
989 994 break;
990 995 }
991 996 case DATA_TYPE_STRING_ARRAY: {
992 997 char **val_array;
993 998
994 999 /* check indexed string value of array for match */
995 1000 if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) &&
996 1001 (ai < a_len)) {
997 1002 if (value_regex) {
998 1003 if (regexec(value_regex, val_array[ai],
999 1004 (size_t)0, NULL, 0) == 0)
1000 1005 return (1);
1001 1006 } else {
1002 1007 if (strcmp(value, val_array[ai]) == 0)
1003 1008 return (1);
1004 1009 }
1005 1010 }
1006 1011 break;
1007 1012 }
1008 1013 case DATA_TYPE_BYTE: {
1009 1014 uchar_t val, val_arg;
1010 1015
1011 1016 /* scanf uchar_t from value and check for match */
1012 1017 sr = sscanf(value, "%c", &val_arg);
1013 1018 if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) &&
1014 1019 (val == val_arg))
1015 1020 return (1);
1016 1021 break;
1017 1022 }
1018 1023 case DATA_TYPE_BYTE_ARRAY: {
1019 1024 uchar_t *val_array, val_arg;
1020 1025
1021 1026
1022 1027 /* check indexed value of array for match */
1023 1028 sr = sscanf(value, "%c", &val_arg);
1024 1029 if ((sr == 1) &&
1025 1030 (nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) &&
1026 1031 (ai < a_len) &&
1027 1032 (val_array[ai] == val_arg))
1028 1033 return (1);
1029 1034 break;
1030 1035 }
1031 1036 case DATA_TYPE_INT8: {
1032 1037 int8_t val, val_arg;
1033 1038
1034 1039 /* scanf int8_t from value and check for match */
1035 1040 sr = sscanf(value, "%"SCNi8, &val_arg);
1036 1041 if ((sr == 1) &&
1037 1042 (nvpair_value_int8(nvp, &val) == 0) &&
1038 1043 (val == val_arg))
1039 1044 return (1);
1040 1045 break;
1041 1046 }
1042 1047 case DATA_TYPE_INT8_ARRAY: {
1043 1048 int8_t *val_array, val_arg;
1044 1049
1045 1050 /* check indexed value of array for match */
1046 1051 sr = sscanf(value, "%"SCNi8, &val_arg);
1047 1052 if ((sr == 1) &&
1048 1053 (nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) &&
1049 1054 (ai < a_len) &&
1050 1055 (val_array[ai] == val_arg))
1051 1056 return (1);
1052 1057 break;
1053 1058 }
1054 1059 case DATA_TYPE_UINT8: {
1055 1060 uint8_t val, val_arg;
1056 1061
1057 1062 /* scanf uint8_t from value and check for match */
1058 1063 sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
1059 1064 if ((sr == 1) &&
1060 1065 (nvpair_value_uint8(nvp, &val) == 0) &&
1061 1066 (val == val_arg))
1062 1067 return (1);
1063 1068 break;
1064 1069 }
1065 1070 case DATA_TYPE_UINT8_ARRAY: {
1066 1071 uint8_t *val_array, val_arg;
1067 1072
1068 1073 /* check indexed value of array for match */
1069 1074 sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
1070 1075 if ((sr == 1) &&
1071 1076 (nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) &&
1072 1077 (ai < a_len) &&
1073 1078 (val_array[ai] == val_arg))
1074 1079 return (1);
1075 1080 break;
1076 1081 }
1077 1082 case DATA_TYPE_INT16: {
1078 1083 int16_t val, val_arg;
1079 1084
1080 1085 /* scanf int16_t from value and check for match */
1081 1086 sr = sscanf(value, "%"SCNi16, &val_arg);
1082 1087 if ((sr == 1) &&
1083 1088 (nvpair_value_int16(nvp, &val) == 0) &&
1084 1089 (val == val_arg))
1085 1090 return (1);
1086 1091 break;
1087 1092 }
1088 1093 case DATA_TYPE_INT16_ARRAY: {
1089 1094 int16_t *val_array, val_arg;
1090 1095
1091 1096 /* check indexed value of array for match */
1092 1097 sr = sscanf(value, "%"SCNi16, &val_arg);
1093 1098 if ((sr == 1) &&
1094 1099 (nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) &&
1095 1100 (ai < a_len) &&
1096 1101 (val_array[ai] == val_arg))
1097 1102 return (1);
1098 1103 break;
1099 1104 }
1100 1105 case DATA_TYPE_UINT16: {
1101 1106 uint16_t val, val_arg;
1102 1107
1103 1108 /* scanf uint16_t from value and check for match */
1104 1109 sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
1105 1110 if ((sr == 1) &&
1106 1111 (nvpair_value_uint16(nvp, &val) == 0) &&
1107 1112 (val == val_arg))
1108 1113 return (1);
1109 1114 break;
1110 1115 }
1111 1116 case DATA_TYPE_UINT16_ARRAY: {
1112 1117 uint16_t *val_array, val_arg;
1113 1118
1114 1119 /* check indexed value of array for match */
1115 1120 sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
1116 1121 if ((sr == 1) &&
1117 1122 (nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) &&
1118 1123 (ai < a_len) &&
1119 1124 (val_array[ai] == val_arg))
1120 1125 return (1);
1121 1126 break;
1122 1127 }
1123 1128 case DATA_TYPE_INT32: {
1124 1129 int32_t val, val_arg;
1125 1130
1126 1131 /* scanf int32_t from value and check for match */
1127 1132 sr = sscanf(value, "%"SCNi32, &val_arg);
1128 1133 if ((sr == 1) &&
1129 1134 (nvpair_value_int32(nvp, &val) == 0) &&
1130 1135 (val == val_arg))
1131 1136 return (1);
1132 1137 break;
1133 1138 }
1134 1139 case DATA_TYPE_INT32_ARRAY: {
1135 1140 int32_t *val_array, val_arg;
1136 1141
1137 1142 /* check indexed value of array for match */
1138 1143 sr = sscanf(value, "%"SCNi32, &val_arg);
1139 1144 if ((sr == 1) &&
1140 1145 (nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) &&
1141 1146 (ai < a_len) &&
1142 1147 (val_array[ai] == val_arg))
1143 1148 return (1);
1144 1149 break;
1145 1150 }
1146 1151 case DATA_TYPE_UINT32: {
1147 1152 uint32_t val, val_arg;
1148 1153
1149 1154 /* scanf uint32_t from value and check for match */
1150 1155 sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
1151 1156 if ((sr == 1) &&
1152 1157 (nvpair_value_uint32(nvp, &val) == 0) &&
1153 1158 (val == val_arg))
1154 1159 return (1);
1155 1160 break;
1156 1161 }
1157 1162 case DATA_TYPE_UINT32_ARRAY: {
1158 1163 uint32_t *val_array, val_arg;
1159 1164
1160 1165 /* check indexed value of array for match */
1161 1166 sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
1162 1167 if ((sr == 1) &&
1163 1168 (nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) &&
1164 1169 (ai < a_len) &&
1165 1170 (val_array[ai] == val_arg))
1166 1171 return (1);
1167 1172 break;
1168 1173 }
1169 1174 case DATA_TYPE_INT64: {
1170 1175 int64_t val, val_arg;
1171 1176
1172 1177 /* scanf int64_t from value and check for match */
1173 1178 sr = sscanf(value, "%"SCNi64, &val_arg);
1174 1179 if ((sr == 1) &&
1175 1180 (nvpair_value_int64(nvp, &val) == 0) &&
1176 1181 (val == val_arg))
1177 1182 return (1);
1178 1183 break;
1179 1184 }
1180 1185 case DATA_TYPE_INT64_ARRAY: {
1181 1186 int64_t *val_array, val_arg;
1182 1187
1183 1188 /* check indexed value of array for match */
1184 1189 sr = sscanf(value, "%"SCNi64, &val_arg);
1185 1190 if ((sr == 1) &&
1186 1191 (nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) &&
1187 1192 (ai < a_len) &&
1188 1193 (val_array[ai] == val_arg))
1189 1194 return (1);
1190 1195 break;
1191 1196 }
1192 1197 case DATA_TYPE_UINT64: {
1193 1198 uint64_t val_arg, val;
1194 1199
1195 1200 /* scanf uint64_t from value and check for match */
1196 1201 sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
1197 1202 if ((sr == 1) &&
1198 1203 (nvpair_value_uint64(nvp, &val) == 0) &&
1199 1204 (val == val_arg))
1200 1205 return (1);
1201 1206 break;
1202 1207 }
1203 1208 case DATA_TYPE_UINT64_ARRAY: {
1204 1209 uint64_t *val_array, val_arg;
1205 1210
1206 1211 /* check indexed value of array for match */
1207 1212 sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
1208 1213 if ((sr == 1) &&
1209 1214 (nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) &&
1210 1215 (ai < a_len) &&
1211 1216 (val_array[ai] == val_arg))
1212 1217 return (1);
1213 1218 break;
1214 1219 }
1215 1220 case DATA_TYPE_BOOLEAN_VALUE: {
1216 1221 boolean_t val, val_arg;
1217 1222
1218 1223 /* scanf boolean_t from value and check for match */
1219 1224 sr = sscanf(value, "%"SCNi32, &val_arg);
1220 1225 if ((sr == 1) &&
1221 1226 (nvpair_value_boolean_value(nvp, &val) == 0) &&
1222 1227 (val == val_arg))
1223 1228 return (1);
1224 1229 break;
1225 1230 }
1226 1231 case DATA_TYPE_BOOLEAN_ARRAY: {
1227 1232 boolean_t *val_array, val_arg;
1228 1233
1229 1234 /* check indexed value of array for match */
1230 1235 sr = sscanf(value, "%"SCNi32, &val_arg);
1231 1236 if ((sr == 1) &&
1232 1237 (nvpair_value_boolean_array(nvp,
1233 1238 &val_array, &a_len) == 0) &&
1234 1239 (ai < a_len) &&
1235 1240 (val_array[ai] == val_arg))
1236 1241 return (1);
1237 1242 break;
1238 1243 }
1239 1244 case DATA_TYPE_HRTIME:
1240 1245 case DATA_TYPE_NVLIST:
1241 1246 case DATA_TYPE_NVLIST_ARRAY:
1242 1247 case DATA_TYPE_BOOLEAN:
1243 1248 case DATA_TYPE_DOUBLE:
1244 1249 case DATA_TYPE_UNKNOWN:
1245 1250 default:
1246 1251 /*
1247 1252 * unknown/unsupported data type
1248 1253 */
1249 1254 return (-1); /* error fail match */
1250 1255 }
1251 1256
1252 1257 /*
1253 1258 * check to see if sscanf failed conversion, return approximate
1254 1259 * pointer to problem
1255 1260 */
1256 1261 if (sr != 1) {
1257 1262 if (ep)
1258 1263 *ep = value;
1259 1264 return (-1); /* error fail match - syntax */
1260 1265 }
1261 1266
1262 1267 return (0); /* fail match */
1263 1268 }
1264 1269
1265 1270 int
1266 1271 nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep)
1267 1272 {
1268 1273 return (nvpair_value_match_regex(nvp, ai, value, NULL, ep));
1269 1274 }
|
↓ open down ↓ |
454 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX