Home | History | Annotate | Line # | Download | only in libnvpair
libnvpair.c revision 1.1.1.2.12.2
      1           1.1  haad /*
      2           1.1  haad  * CDDL HEADER START
      3           1.1  haad  *
      4           1.1  haad  * The contents of this file are subject to the terms of the
      5           1.1  haad  * Common Development and Distribution License (the "License").
      6           1.1  haad  * You may not use this file except in compliance with the License.
      7           1.1  haad  *
      8           1.1  haad  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9           1.1  haad  * or http://www.opensolaris.org/os/licensing.
     10           1.1  haad  * See the License for the specific language governing permissions
     11           1.1  haad  * and limitations under the License.
     12           1.1  haad  *
     13           1.1  haad  * When distributing Covered Code, include this CDDL HEADER in each
     14           1.1  haad  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15           1.1  haad  * If applicable, add the following below this CDDL HEADER, with the
     16           1.1  haad  * fields enclosed by brackets "[]" replaced with your own identifying
     17           1.1  haad  * information: Portions Copyright [yyyy] [name of copyright owner]
     18           1.1  haad  *
     19           1.1  haad  * CDDL HEADER END
     20           1.1  haad  */
     21           1.1  haad /*
     22       1.1.1.2  haad  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23           1.1  haad  * Use is subject to license terms.
     24           1.1  haad  */
     25           1.1  haad 
     26           1.1  haad #include <unistd.h>
     27           1.1  haad #include <strings.h>
     28       1.1.1.2  haad #include <libintl.h>
     29           1.1  haad #include <sys/types.h>
     30           1.1  haad #include <sys/inttypes.h>
     31           1.1  haad #include "libnvpair.h"
     32           1.1  haad 
     33           1.1  haad /*
     34           1.1  haad  * libnvpair - A tools library for manipulating <name, value> pairs.
     35           1.1  haad  *
     36           1.1  haad  *	This library provides routines packing an unpacking nv pairs
     37           1.1  haad  *	for transporting data across process boundaries, transporting
     38           1.1  haad  *	between kernel and userland, and possibly saving onto disk files.
     39           1.1  haad  */
     40           1.1  haad 
     41           1.1  haad static void
     42           1.1  haad indent(FILE *fp, int depth)
     43           1.1  haad {
     44           1.1  haad 	while (depth-- > 0)
     45           1.1  haad 		(void) fprintf(fp, "\t");
     46           1.1  haad }
     47           1.1  haad 
     48           1.1  haad /*
     49           1.1  haad  * nvlist_print - Prints elements in an event buffer
     50           1.1  haad  */
     51           1.1  haad static
     52           1.1  haad void
     53           1.1  haad nvlist_print_with_indent(FILE *fp, nvlist_t *nvl, int depth)
     54           1.1  haad {
     55           1.1  haad 	int i;
     56           1.1  haad 	char *name;
     57           1.1  haad 	uint_t nelem;
     58           1.1  haad 	nvpair_t *nvp;
     59           1.1  haad 
     60           1.1  haad 	if (nvl == NULL)
     61           1.1  haad 		return;
     62           1.1  haad 
     63           1.1  haad 	indent(fp, depth);
     64           1.1  haad 	(void) fprintf(fp, "nvlist version: %d\n", NVL_VERSION(nvl));
     65           1.1  haad 
     66           1.1  haad 	nvp = nvlist_next_nvpair(nvl, NULL);
     67           1.1  haad 
     68           1.1  haad 	while (nvp) {
     69           1.1  haad 		data_type_t type = nvpair_type(nvp);
     70           1.1  haad 
     71           1.1  haad 		indent(fp, depth);
     72           1.1  haad 		name = nvpair_name(nvp);
     73           1.1  haad 		(void) fprintf(fp, "\t%s =", name);
     74           1.1  haad 		nelem = 0;
     75           1.1  haad 		switch (type) {
     76           1.1  haad 		case DATA_TYPE_BOOLEAN: {
     77           1.1  haad 			(void) fprintf(fp, " 1");
     78           1.1  haad 			break;
     79           1.1  haad 		}
     80           1.1  haad 		case DATA_TYPE_BOOLEAN_VALUE: {
     81           1.1  haad 			boolean_t val;
     82           1.1  haad 			(void) nvpair_value_boolean_value(nvp, &val);
     83           1.1  haad 			(void) fprintf(fp, " %d", val);
     84           1.1  haad 			break;
     85           1.1  haad 		}
     86           1.1  haad 		case DATA_TYPE_BYTE: {
     87           1.1  haad 			uchar_t val;
     88           1.1  haad 			(void) nvpair_value_byte(nvp, &val);
     89           1.1  haad 			(void) fprintf(fp, " 0x%2.2x", val);
     90           1.1  haad 			break;
     91           1.1  haad 		}
     92           1.1  haad 		case DATA_TYPE_INT8: {
     93           1.1  haad 			int8_t val;
     94           1.1  haad 			(void) nvpair_value_int8(nvp, &val);
     95           1.1  haad 			(void) fprintf(fp, " %d", val);
     96           1.1  haad 			break;
     97           1.1  haad 		}
     98           1.1  haad 		case DATA_TYPE_UINT8: {
     99           1.1  haad 			uint8_t val;
    100           1.1  haad 			(void) nvpair_value_uint8(nvp, &val);
    101           1.1  haad 			(void) fprintf(fp, " 0x%x", val);
    102           1.1  haad 			break;
    103           1.1  haad 		}
    104           1.1  haad 		case DATA_TYPE_INT16: {
    105           1.1  haad 			int16_t val;
    106           1.1  haad 			(void) nvpair_value_int16(nvp, &val);
    107           1.1  haad 			(void) fprintf(fp, " %d", val);
    108           1.1  haad 			break;
    109           1.1  haad 		}
    110           1.1  haad 		case DATA_TYPE_UINT16: {
    111           1.1  haad 			uint16_t val;
    112           1.1  haad 			(void) nvpair_value_uint16(nvp, &val);
    113           1.1  haad 			(void) fprintf(fp, " 0x%x", val);
    114           1.1  haad 			break;
    115           1.1  haad 		}
    116           1.1  haad 		case DATA_TYPE_INT32: {
    117           1.1  haad 			int32_t val;
    118           1.1  haad 			(void) nvpair_value_int32(nvp, &val);
    119           1.1  haad 			(void) fprintf(fp, " %d", val);
    120           1.1  haad 			break;
    121           1.1  haad 		}
    122           1.1  haad 		case DATA_TYPE_UINT32: {
    123           1.1  haad 			uint32_t val;
    124           1.1  haad 			(void) nvpair_value_uint32(nvp, &val);
    125           1.1  haad 			(void) fprintf(fp, " 0x%x", val);
    126           1.1  haad 			break;
    127           1.1  haad 		}
    128           1.1  haad 		case DATA_TYPE_INT64: {
    129           1.1  haad 			int64_t val;
    130           1.1  haad 			(void) nvpair_value_int64(nvp, &val);
    131  1.1.1.2.12.2   tls 			(void) fprintf(fp, " %" PRId64 , val);
    132           1.1  haad 			break;
    133           1.1  haad 		}
    134           1.1  haad 		case DATA_TYPE_UINT64: {
    135           1.1  haad 			uint64_t val;
    136           1.1  haad 			(void) nvpair_value_uint64(nvp, &val);
    137  1.1.1.2.12.2   tls 			(void) fprintf(fp, " 0x%" PRIx64, val);
    138           1.1  haad 			break;
    139           1.1  haad 		}
    140           1.1  haad 		case DATA_TYPE_DOUBLE: {
    141           1.1  haad 			double val;
    142           1.1  haad 			(void) nvpair_value_double(nvp, &val);
    143  1.1.1.2.12.1   tls 			(void) fprintf(fp, " 0x%f", val);
    144           1.1  haad 			break;
    145           1.1  haad 		}
    146           1.1  haad 		case DATA_TYPE_STRING: {
    147           1.1  haad 			char *val;
    148           1.1  haad 			(void) nvpair_value_string(nvp, &val);
    149           1.1  haad 			(void) fprintf(fp, " %s", val);
    150           1.1  haad 			break;
    151           1.1  haad 		}
    152           1.1  haad 		case DATA_TYPE_BOOLEAN_ARRAY: {
    153           1.1  haad 			boolean_t *val;
    154           1.1  haad 			(void) nvpair_value_boolean_array(nvp, &val, &nelem);
    155           1.1  haad 			for (i = 0; i < nelem; i++)
    156           1.1  haad 				(void) fprintf(fp, " %d", val[i]);
    157           1.1  haad 			break;
    158           1.1  haad 		}
    159           1.1  haad 		case DATA_TYPE_BYTE_ARRAY: {
    160           1.1  haad 			uchar_t *val;
    161           1.1  haad 			(void) nvpair_value_byte_array(nvp, &val, &nelem);
    162           1.1  haad 			for (i = 0; i < nelem; i++)
    163           1.1  haad 				(void) fprintf(fp, " 0x%2.2x", val[i]);
    164           1.1  haad 			break;
    165           1.1  haad 		}
    166           1.1  haad 		case DATA_TYPE_INT8_ARRAY: {
    167           1.1  haad 			int8_t *val;
    168           1.1  haad 			(void) nvpair_value_int8_array(nvp, &val, &nelem);
    169           1.1  haad 			for (i = 0; i < nelem; i++)
    170           1.1  haad 				(void) fprintf(fp, " %d", val[i]);
    171           1.1  haad 			break;
    172           1.1  haad 		}
    173           1.1  haad 		case DATA_TYPE_UINT8_ARRAY: {
    174           1.1  haad 			uint8_t *val;
    175           1.1  haad 			(void) nvpair_value_uint8_array(nvp, &val, &nelem);
    176           1.1  haad 			for (i = 0; i < nelem; i++)
    177           1.1  haad 				(void) fprintf(fp, " 0x%x", val[i]);
    178           1.1  haad 			break;
    179           1.1  haad 		}
    180           1.1  haad 		case DATA_TYPE_INT16_ARRAY: {
    181           1.1  haad 			int16_t *val;
    182           1.1  haad 			(void) nvpair_value_int16_array(nvp, &val, &nelem);
    183           1.1  haad 			for (i = 0; i < nelem; i++)
    184           1.1  haad 				(void) fprintf(fp, " %d", val[i]);
    185           1.1  haad 			break;
    186           1.1  haad 		}
    187           1.1  haad 		case DATA_TYPE_UINT16_ARRAY: {
    188           1.1  haad 			uint16_t *val;
    189           1.1  haad 			(void) nvpair_value_uint16_array(nvp, &val, &nelem);
    190           1.1  haad 			for (i = 0; i < nelem; i++)
    191           1.1  haad 				(void) fprintf(fp, " 0x%x", val[i]);
    192           1.1  haad 			break;
    193           1.1  haad 		}
    194           1.1  haad 		case DATA_TYPE_INT32_ARRAY: {
    195           1.1  haad 			int32_t *val;
    196           1.1  haad 			(void) nvpair_value_int32_array(nvp, &val, &nelem);
    197           1.1  haad 			for (i = 0; i < nelem; i++)
    198           1.1  haad 				(void) fprintf(fp, " %d", val[i]);
    199           1.1  haad 			break;
    200           1.1  haad 		}
    201           1.1  haad 		case DATA_TYPE_UINT32_ARRAY: {
    202           1.1  haad 			uint32_t *val;
    203           1.1  haad 			(void) nvpair_value_uint32_array(nvp, &val, &nelem);
    204           1.1  haad 			for (i = 0; i < nelem; i++)
    205           1.1  haad 				(void) fprintf(fp, " 0x%x", val[i]);
    206           1.1  haad 			break;
    207           1.1  haad 		}
    208           1.1  haad 		case DATA_TYPE_INT64_ARRAY: {
    209           1.1  haad 			int64_t *val;
    210           1.1  haad 			(void) nvpair_value_int64_array(nvp, &val, &nelem);
    211           1.1  haad 			for (i = 0; i < nelem; i++)
    212  1.1.1.2.12.2   tls 				(void) fprintf(fp, " %" PRId64, val[i]);
    213           1.1  haad 			break;
    214           1.1  haad 		}
    215           1.1  haad 		case DATA_TYPE_UINT64_ARRAY: {
    216           1.1  haad 			uint64_t *val;
    217           1.1  haad 			(void) nvpair_value_uint64_array(nvp, &val, &nelem);
    218           1.1  haad 			for (i = 0; i < nelem; i++)
    219  1.1.1.2.12.2   tls 				(void) fprintf(fp, " 0x%" PRIx64, val[i]);
    220           1.1  haad 			break;
    221           1.1  haad 		}
    222           1.1  haad 		case DATA_TYPE_STRING_ARRAY: {
    223           1.1  haad 			char **val;
    224           1.1  haad 			(void) nvpair_value_string_array(nvp, &val, &nelem);
    225           1.1  haad 			for (i = 0; i < nelem; i++)
    226           1.1  haad 				(void) fprintf(fp, " %s", val[i]);
    227           1.1  haad 			break;
    228           1.1  haad 		}
    229           1.1  haad 		case DATA_TYPE_HRTIME: {
    230           1.1  haad 			hrtime_t val;
    231           1.1  haad 			(void) nvpair_value_hrtime(nvp, &val);
    232  1.1.1.2.12.2   tls 			(void) fprintf(fp, " 0x%jx", (intmax_t)val);
    233           1.1  haad 			break;
    234           1.1  haad 		}
    235           1.1  haad 		case DATA_TYPE_NVLIST: {
    236           1.1  haad 			nvlist_t *val;
    237           1.1  haad 			(void) nvpair_value_nvlist(nvp, &val);
    238           1.1  haad 			(void) fprintf(fp, " (embedded nvlist)\n");
    239           1.1  haad 			nvlist_print_with_indent(fp, val, depth + 1);
    240           1.1  haad 			indent(fp, depth + 1);
    241           1.1  haad 			(void) fprintf(fp, "(end %s)\n", name);
    242           1.1  haad 			break;
    243           1.1  haad 		}
    244           1.1  haad 		case DATA_TYPE_NVLIST_ARRAY: {
    245           1.1  haad 			nvlist_t **val;
    246           1.1  haad 			(void) nvpair_value_nvlist_array(nvp, &val, &nelem);
    247           1.1  haad 			(void) fprintf(fp, " (array of embedded nvlists)\n");
    248           1.1  haad 			for (i = 0; i < nelem; i++) {
    249           1.1  haad 				indent(fp, depth + 1);
    250           1.1  haad 				(void) fprintf(fp,
    251           1.1  haad 				    "(start %s[%d])\n", name, i);
    252           1.1  haad 				nvlist_print_with_indent(fp, val[i], depth + 1);
    253           1.1  haad 				indent(fp, depth + 1);
    254           1.1  haad 				(void) fprintf(fp, "(end %s[%d])\n", name, i);
    255           1.1  haad 			}
    256           1.1  haad 			break;
    257           1.1  haad 		}
    258           1.1  haad 		default:
    259           1.1  haad 			(void) fprintf(fp, " unknown data type (%d)", type);
    260           1.1  haad 			break;
    261           1.1  haad 		}
    262           1.1  haad 		(void) fprintf(fp, "\n");
    263           1.1  haad 		nvp = nvlist_next_nvpair(nvl, nvp);
    264           1.1  haad 	}
    265           1.1  haad }
    266           1.1  haad 
    267           1.1  haad void
    268           1.1  haad nvlist_print(FILE *fp, nvlist_t *nvl)
    269           1.1  haad {
    270           1.1  haad 	nvlist_print_with_indent(fp, nvl, 0);
    271           1.1  haad }
    272           1.1  haad 
    273       1.1.1.2  haad 
    274       1.1.1.2  haad #define	NVP(elem, type, vtype, ptype, format) { \
    275       1.1.1.2  haad 	vtype	value; \
    276       1.1.1.2  haad \
    277       1.1.1.2  haad 	(void) nvpair_value_##type(elem, &value); \
    278       1.1.1.2  haad 	(void) printf("%*s%s: " format "\n", indent, "", \
    279       1.1.1.2  haad 	    nvpair_name(elem), (ptype)value); \
    280       1.1.1.2  haad }
    281       1.1.1.2  haad 
    282       1.1.1.2  haad #define	NVPA(elem, type, vtype, ptype, format) { \
    283       1.1.1.2  haad 	uint_t	i, count; \
    284       1.1.1.2  haad 	vtype	*value;  \
    285       1.1.1.2  haad \
    286       1.1.1.2  haad 	(void) nvpair_value_##type(elem, &value, &count); \
    287       1.1.1.2  haad 	for (i = 0; i < count; i++) { \
    288       1.1.1.2  haad 		(void) printf("%*s%s[%d]: " format "\n", indent, "", \
    289       1.1.1.2  haad 		    nvpair_name(elem), i, (ptype)value[i]); \
    290       1.1.1.2  haad 	} \
    291       1.1.1.2  haad }
    292       1.1.1.2  haad 
    293       1.1.1.2  haad /*
    294       1.1.1.2  haad  * Similar to nvlist_print() but handles arrays slightly differently.
    295       1.1.1.2  haad  */
    296       1.1.1.2  haad void
    297       1.1.1.2  haad dump_nvlist(nvlist_t *list, int indent)
    298       1.1.1.2  haad {
    299       1.1.1.2  haad 	nvpair_t	*elem = NULL;
    300       1.1.1.2  haad 	boolean_t	bool_value;
    301       1.1.1.2  haad 	nvlist_t	*nvlist_value;
    302       1.1.1.2  haad 	nvlist_t	**nvlist_array_value;
    303       1.1.1.2  haad 	uint_t		i, count;
    304       1.1.1.2  haad 
    305       1.1.1.2  haad 	if (list == NULL) {
    306       1.1.1.2  haad 		return;
    307       1.1.1.2  haad 	}
    308       1.1.1.2  haad 
    309       1.1.1.2  haad 	while ((elem = nvlist_next_nvpair(list, elem)) != NULL) {
    310       1.1.1.2  haad 		switch (nvpair_type(elem)) {
    311       1.1.1.2  haad 		case DATA_TYPE_BOOLEAN_VALUE:
    312       1.1.1.2  haad 			(void) nvpair_value_boolean_value(elem, &bool_value);
    313       1.1.1.2  haad 			(void) printf("%*s%s: %s\n", indent, "",
    314       1.1.1.2  haad 			    nvpair_name(elem), bool_value ? "true" : "false");
    315       1.1.1.2  haad 			break;
    316       1.1.1.2  haad 
    317       1.1.1.2  haad 		case DATA_TYPE_BYTE:
    318       1.1.1.2  haad 			NVP(elem, byte, uchar_t, int, "%u");
    319       1.1.1.2  haad 			break;
    320       1.1.1.2  haad 
    321       1.1.1.2  haad 		case DATA_TYPE_INT8:
    322       1.1.1.2  haad 			NVP(elem, int8, int8_t, int, "%d");
    323       1.1.1.2  haad 			break;
    324       1.1.1.2  haad 
    325       1.1.1.2  haad 		case DATA_TYPE_UINT8:
    326       1.1.1.2  haad 			NVP(elem, uint8, uint8_t, int, "%u");
    327       1.1.1.2  haad 			break;
    328       1.1.1.2  haad 
    329       1.1.1.2  haad 		case DATA_TYPE_INT16:
    330       1.1.1.2  haad 			NVP(elem, int16, int16_t, int, "%d");
    331       1.1.1.2  haad 			break;
    332       1.1.1.2  haad 
    333       1.1.1.2  haad 		case DATA_TYPE_UINT16:
    334       1.1.1.2  haad 			NVP(elem, uint16, uint16_t, int, "%u");
    335       1.1.1.2  haad 			break;
    336       1.1.1.2  haad 
    337       1.1.1.2  haad 		case DATA_TYPE_INT32:
    338       1.1.1.2  haad 			NVP(elem, int32, int32_t, long, "%ld");
    339       1.1.1.2  haad 			break;
    340       1.1.1.2  haad 
    341       1.1.1.2  haad 		case DATA_TYPE_UINT32:
    342       1.1.1.2  haad 			NVP(elem, uint32, uint32_t, ulong_t, "%lu");
    343       1.1.1.2  haad 			break;
    344       1.1.1.2  haad 
    345       1.1.1.2  haad 		case DATA_TYPE_INT64:
    346  1.1.1.2.12.2   tls 			NVP(elem, int64, int64_t, int64_t, "%" PRIx64);
    347       1.1.1.2  haad 			break;
    348       1.1.1.2  haad 
    349       1.1.1.2  haad 		case DATA_TYPE_UINT64:
    350  1.1.1.2.12.2   tls 			NVP(elem, uint64, uint64_t, uint64_t, "%" PRIu64);
    351       1.1.1.2  haad 			break;
    352       1.1.1.2  haad 
    353       1.1.1.2  haad 		case DATA_TYPE_STRING:
    354       1.1.1.2  haad 			NVP(elem, string, char *, char *, "'%s'");
    355       1.1.1.2  haad 			break;
    356       1.1.1.2  haad 
    357       1.1.1.2  haad 		case DATA_TYPE_BYTE_ARRAY:
    358       1.1.1.2  haad 			NVPA(elem, byte_array, uchar_t, int, "%u");
    359       1.1.1.2  haad 			break;
    360       1.1.1.2  haad 
    361       1.1.1.2  haad 		case DATA_TYPE_INT8_ARRAY:
    362       1.1.1.2  haad 			NVPA(elem, int8_array, int8_t, int, "%d");
    363       1.1.1.2  haad 			break;
    364       1.1.1.2  haad 
    365       1.1.1.2  haad 		case DATA_TYPE_UINT8_ARRAY:
    366       1.1.1.2  haad 			NVPA(elem, uint8_array, uint8_t, int, "%u");
    367       1.1.1.2  haad 			break;
    368       1.1.1.2  haad 
    369       1.1.1.2  haad 		case DATA_TYPE_INT16_ARRAY:
    370       1.1.1.2  haad 			NVPA(elem, int16_array, int16_t, int, "%d");
    371       1.1.1.2  haad 			break;
    372       1.1.1.2  haad 
    373       1.1.1.2  haad 		case DATA_TYPE_UINT16_ARRAY:
    374       1.1.1.2  haad 			NVPA(elem, uint16_array, uint16_t, int, "%u");
    375       1.1.1.2  haad 			break;
    376       1.1.1.2  haad 
    377       1.1.1.2  haad 		case DATA_TYPE_INT32_ARRAY:
    378       1.1.1.2  haad 			NVPA(elem, int32_array, int32_t, long, "%ld");
    379       1.1.1.2  haad 			break;
    380       1.1.1.2  haad 
    381       1.1.1.2  haad 		case DATA_TYPE_UINT32_ARRAY:
    382       1.1.1.2  haad 			NVPA(elem, uint32_array, uint32_t, ulong_t, "%lu");
    383       1.1.1.2  haad 			break;
    384       1.1.1.2  haad 
    385       1.1.1.2  haad 		case DATA_TYPE_INT64_ARRAY:
    386  1.1.1.2.12.2   tls 			NVPA(elem, int64_array, int64_t, int64_t, "%" PRId64);
    387       1.1.1.2  haad 			break;
    388       1.1.1.2  haad 
    389       1.1.1.2  haad 		case DATA_TYPE_UINT64_ARRAY:
    390  1.1.1.2.12.2   tls 			NVPA(elem, uint64_array, uint64_t, uint64_t,
    391  1.1.1.2.12.2   tls 			    "%" PRIu64);
    392       1.1.1.2  haad 			break;
    393       1.1.1.2  haad 
    394       1.1.1.2  haad 		case DATA_TYPE_STRING_ARRAY:
    395       1.1.1.2  haad 			NVPA(elem, string_array, char *, char *, "'%s'");
    396       1.1.1.2  haad 			break;
    397       1.1.1.2  haad 
    398       1.1.1.2  haad 		case DATA_TYPE_NVLIST:
    399       1.1.1.2  haad 			(void) nvpair_value_nvlist(elem, &nvlist_value);
    400       1.1.1.2  haad 			(void) printf("%*s%s:\n", indent, "",
    401       1.1.1.2  haad 			    nvpair_name(elem));
    402       1.1.1.2  haad 			dump_nvlist(nvlist_value, indent + 4);
    403       1.1.1.2  haad 			break;
    404       1.1.1.2  haad 
    405       1.1.1.2  haad 		case DATA_TYPE_NVLIST_ARRAY:
    406       1.1.1.2  haad 			(void) nvpair_value_nvlist_array(elem,
    407       1.1.1.2  haad 			    &nvlist_array_value, &count);
    408       1.1.1.2  haad 			for (i = 0; i < count; i++) {
    409       1.1.1.2  haad 				(void) printf("%*s%s[%u]:\n", indent, "",
    410       1.1.1.2  haad 				    nvpair_name(elem), i);
    411       1.1.1.2  haad 				dump_nvlist(nvlist_array_value[i], indent + 4);
    412       1.1.1.2  haad 			}
    413       1.1.1.2  haad 			break;
    414       1.1.1.2  haad 
    415       1.1.1.2  haad 		default:
    416       1.1.1.2  haad 			(void) printf(dgettext(TEXT_DOMAIN, "bad config type "
    417       1.1.1.2  haad 			    "%d for %s\n"), nvpair_type(elem),
    418       1.1.1.2  haad 			    nvpair_name(elem));
    419       1.1.1.2  haad 		}
    420       1.1.1.2  haad 	}
    421       1.1.1.2  haad }
    422       1.1.1.2  haad 
    423           1.1  haad /*
    424           1.1  haad  * Determine if string 'value' matches 'nvp' value.  The 'value' string is
    425           1.1  haad  * converted, depending on the type of 'nvp', prior to match.  For numeric
    426           1.1  haad  * types, a radix independent sscanf conversion of 'value' is used. If 'nvp'
    427           1.1  haad  * is an array type, 'ai' is the index into the array against which we are
    428           1.1  haad  * checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass
    429           1.1  haad  * in a regex_t compilation of value in 'value_regex' to trigger regular
    430           1.1  haad  * expression string match instead of simple strcmp().
    431           1.1  haad  *
    432           1.1  haad  * Return 1 on match, 0 on no-match, and -1 on error.  If the error is
    433           1.1  haad  * related to value syntax error and 'ep' is non-NULL, *ep will point into
    434           1.1  haad  * the 'value' string at the location where the error exists.
    435           1.1  haad  *
    436           1.1  haad  * NOTE: It may be possible to move the non-regex_t version of this into
    437           1.1  haad  * common code used by library/kernel/boot.
    438           1.1  haad  */
    439           1.1  haad int
    440           1.1  haad nvpair_value_match_regex(nvpair_t *nvp, int ai,
    441           1.1  haad     char *value, regex_t *value_regex, char **ep)
    442           1.1  haad {
    443           1.1  haad 	char	*evalue;
    444           1.1  haad 	uint_t	a_len;
    445           1.1  haad 	int	sr;
    446           1.1  haad 
    447           1.1  haad 	if (ep)
    448           1.1  haad 		*ep = NULL;
    449           1.1  haad 
    450           1.1  haad 	if ((nvp == NULL) || (value == NULL))
    451           1.1  haad 		return (-1);		/* error fail match - invalid args */
    452           1.1  haad 
    453           1.1  haad 	/* make sure array and index combination make sense */
    454           1.1  haad 	if ((nvpair_type_is_array(nvp) && (ai < 0)) ||
    455           1.1  haad 	    (!nvpair_type_is_array(nvp) && (ai >= 0)))
    456           1.1  haad 		return (-1);		/* error fail match - bad index */
    457           1.1  haad 
    458           1.1  haad 	/* non-string values should be single 'chunk' */
    459           1.1  haad 	if ((nvpair_type(nvp) != DATA_TYPE_STRING) &&
    460           1.1  haad 	    (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) {
    461           1.1  haad 		value += strspn(value, " \t");
    462           1.1  haad 		evalue = value + strcspn(value, " \t");
    463           1.1  haad 		if (*evalue) {
    464           1.1  haad 			if (ep)
    465           1.1  haad 				*ep = evalue;
    466           1.1  haad 			return (-1);	/* error fail match - syntax */
    467           1.1  haad 		}
    468           1.1  haad 	}
    469           1.1  haad 
    470           1.1  haad 	sr = EOF;
    471           1.1  haad 	switch (nvpair_type(nvp)) {
    472           1.1  haad 	case DATA_TYPE_STRING: {
    473           1.1  haad 		char	*val;
    474           1.1  haad 
    475           1.1  haad 		/* check string value for match */
    476           1.1  haad 		if (nvpair_value_string(nvp, &val) == 0) {
    477           1.1  haad 			if (value_regex) {
    478           1.1  haad 				if (regexec(value_regex, val,
    479           1.1  haad 				    (size_t)0, NULL, 0) == 0)
    480           1.1  haad 					return (1);	/* match */
    481           1.1  haad 			} else {
    482           1.1  haad 				if (strcmp(value, val) == 0)
    483           1.1  haad 					return (1);	/* match */
    484           1.1  haad 			}
    485           1.1  haad 		}
    486           1.1  haad 		break;
    487           1.1  haad 	}
    488           1.1  haad 	case DATA_TYPE_STRING_ARRAY: {
    489           1.1  haad 		char **val_array;
    490           1.1  haad 
    491           1.1  haad 		/* check indexed string value of array for match */
    492           1.1  haad 		if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) &&
    493           1.1  haad 		    (ai < a_len)) {
    494           1.1  haad 			if (value_regex) {
    495           1.1  haad 				if (regexec(value_regex, val_array[ai],
    496           1.1  haad 				    (size_t)0, NULL, 0) == 0)
    497           1.1  haad 					return (1);
    498           1.1  haad 			} else {
    499           1.1  haad 				if (strcmp(value, val_array[ai]) == 0)
    500           1.1  haad 					return (1);
    501           1.1  haad 			}
    502           1.1  haad 		}
    503           1.1  haad 		break;
    504           1.1  haad 	}
    505           1.1  haad 	case DATA_TYPE_BYTE: {
    506           1.1  haad 		uchar_t val, val_arg;
    507           1.1  haad 
    508           1.1  haad 		/* scanf uchar_t from value and check for match */
    509           1.1  haad 		sr = sscanf(value, "%c", &val_arg);
    510           1.1  haad 		if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) &&
    511           1.1  haad 		    (val == val_arg))
    512           1.1  haad 			return (1);
    513           1.1  haad 		break;
    514           1.1  haad 	}
    515           1.1  haad 	case DATA_TYPE_BYTE_ARRAY: {
    516           1.1  haad 		uchar_t *val_array, val_arg;
    517           1.1  haad 
    518           1.1  haad 
    519           1.1  haad 		/* check indexed value of array for match */
    520           1.1  haad 		sr = sscanf(value, "%c", &val_arg);
    521           1.1  haad 		if ((sr == 1) &&
    522           1.1  haad 		    (nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) &&
    523           1.1  haad 		    (ai < a_len) &&
    524           1.1  haad 		    (val_array[ai] == val_arg))
    525           1.1  haad 			return (1);
    526           1.1  haad 		break;
    527           1.1  haad 	}
    528           1.1  haad 	case DATA_TYPE_INT8: {
    529           1.1  haad 		int8_t val, val_arg;
    530           1.1  haad 
    531           1.1  haad 		/* scanf int8_t from value and check for match */
    532           1.1  haad 		sr = sscanf(value, "%"SCNi8, &val_arg);
    533           1.1  haad 		if ((sr == 1) &&
    534           1.1  haad 		    (nvpair_value_int8(nvp, &val) == 0) &&
    535           1.1  haad 		    (val == val_arg))
    536           1.1  haad 			return (1);
    537           1.1  haad 		break;
    538           1.1  haad 	}
    539           1.1  haad 	case DATA_TYPE_INT8_ARRAY: {
    540           1.1  haad 		int8_t *val_array, val_arg;
    541           1.1  haad 
    542           1.1  haad 		/* check indexed value of array for match */
    543           1.1  haad 		sr = sscanf(value, "%"SCNi8, &val_arg);
    544           1.1  haad 		if ((sr == 1) &&
    545           1.1  haad 		    (nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) &&
    546           1.1  haad 		    (ai < a_len) &&
    547           1.1  haad 		    (val_array[ai] == val_arg))
    548           1.1  haad 			return (1);
    549           1.1  haad 		break;
    550           1.1  haad 	}
    551           1.1  haad 	case DATA_TYPE_UINT8: {
    552           1.1  haad 		uint8_t val, val_arg;
    553           1.1  haad 
    554           1.1  haad 		/* scanf uint8_t from value and check for match */
    555           1.1  haad 		sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
    556           1.1  haad 		if ((sr == 1) &&
    557           1.1  haad 		    (nvpair_value_uint8(nvp, &val) == 0) &&
    558           1.1  haad 		    (val == val_arg))
    559           1.1  haad 			return (1);
    560           1.1  haad 		break;
    561           1.1  haad 	}
    562           1.1  haad 	case DATA_TYPE_UINT8_ARRAY: {
    563           1.1  haad 		uint8_t *val_array, val_arg;
    564           1.1  haad 
    565           1.1  haad 		/* check indexed value of array for match */
    566           1.1  haad 		sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
    567           1.1  haad 		if ((sr == 1) &&
    568           1.1  haad 		    (nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) &&
    569           1.1  haad 		    (ai < a_len) &&
    570           1.1  haad 		    (val_array[ai] == val_arg))
    571           1.1  haad 			return (1);
    572           1.1  haad 		break;
    573           1.1  haad 	}
    574           1.1  haad 	case DATA_TYPE_INT16: {
    575           1.1  haad 		int16_t val, val_arg;
    576           1.1  haad 
    577           1.1  haad 		/* scanf int16_t from value and check for match */
    578           1.1  haad 		sr = sscanf(value, "%"SCNi16, &val_arg);
    579           1.1  haad 		if ((sr == 1) &&
    580           1.1  haad 		    (nvpair_value_int16(nvp, &val) == 0) &&
    581           1.1  haad 		    (val == val_arg))
    582           1.1  haad 			return (1);
    583           1.1  haad 		break;
    584           1.1  haad 	}
    585           1.1  haad 	case DATA_TYPE_INT16_ARRAY: {
    586           1.1  haad 		int16_t *val_array, val_arg;
    587           1.1  haad 
    588           1.1  haad 		/* check indexed value of array for match */
    589           1.1  haad 		sr = sscanf(value, "%"SCNi16, &val_arg);
    590           1.1  haad 		if ((sr == 1) &&
    591           1.1  haad 		    (nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) &&
    592           1.1  haad 		    (ai < a_len) &&
    593           1.1  haad 		    (val_array[ai] == val_arg))
    594           1.1  haad 			return (1);
    595           1.1  haad 		break;
    596           1.1  haad 	}
    597           1.1  haad 	case DATA_TYPE_UINT16: {
    598           1.1  haad 		uint16_t val, val_arg;
    599           1.1  haad 
    600           1.1  haad 		/* scanf uint16_t from value and check for match */
    601           1.1  haad 		sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
    602           1.1  haad 		if ((sr == 1) &&
    603           1.1  haad 		    (nvpair_value_uint16(nvp, &val) == 0) &&
    604           1.1  haad 		    (val == val_arg))
    605           1.1  haad 			return (1);
    606           1.1  haad 		break;
    607           1.1  haad 	}
    608           1.1  haad 	case DATA_TYPE_UINT16_ARRAY: {
    609           1.1  haad 		uint16_t *val_array, val_arg;
    610           1.1  haad 
    611           1.1  haad 		/* check indexed value of array for match */
    612           1.1  haad 		sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
    613           1.1  haad 		if ((sr == 1) &&
    614           1.1  haad 		    (nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) &&
    615           1.1  haad 		    (ai < a_len) &&
    616           1.1  haad 		    (val_array[ai] == val_arg))
    617           1.1  haad 			return (1);
    618           1.1  haad 		break;
    619           1.1  haad 	}
    620           1.1  haad 	case DATA_TYPE_INT32: {
    621           1.1  haad 		int32_t val, val_arg;
    622           1.1  haad 
    623           1.1  haad 		/* scanf int32_t from value and check for match */
    624           1.1  haad 		sr = sscanf(value, "%"SCNi32, &val_arg);
    625           1.1  haad 		if ((sr == 1) &&
    626           1.1  haad 		    (nvpair_value_int32(nvp, &val) == 0) &&
    627           1.1  haad 		    (val == val_arg))
    628           1.1  haad 			return (1);
    629           1.1  haad 		break;
    630           1.1  haad 	}
    631           1.1  haad 	case DATA_TYPE_INT32_ARRAY: {
    632           1.1  haad 		int32_t *val_array, val_arg;
    633           1.1  haad 
    634           1.1  haad 		/* check indexed value of array for match */
    635           1.1  haad 		sr = sscanf(value, "%"SCNi32, &val_arg);
    636           1.1  haad 		if ((sr == 1) &&
    637           1.1  haad 		    (nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) &&
    638           1.1  haad 		    (ai < a_len) &&
    639           1.1  haad 		    (val_array[ai] == val_arg))
    640           1.1  haad 			return (1);
    641           1.1  haad 		break;
    642           1.1  haad 	}
    643           1.1  haad 	case DATA_TYPE_UINT32: {
    644           1.1  haad 		uint32_t val, val_arg;
    645           1.1  haad 
    646           1.1  haad 		/* scanf uint32_t from value and check for match */
    647           1.1  haad 		sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
    648           1.1  haad 		if ((sr == 1) &&
    649           1.1  haad 		    (nvpair_value_uint32(nvp, &val) == 0) &&
    650           1.1  haad 		    (val == val_arg))
    651           1.1  haad 			return (1);
    652           1.1  haad 		break;
    653           1.1  haad 	}
    654           1.1  haad 	case DATA_TYPE_UINT32_ARRAY: {
    655           1.1  haad 		uint32_t *val_array, val_arg;
    656           1.1  haad 
    657           1.1  haad 		/* check indexed value of array for match */
    658           1.1  haad 		sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
    659           1.1  haad 		if ((sr == 1) &&
    660           1.1  haad 		    (nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) &&
    661           1.1  haad 		    (ai < a_len) &&
    662           1.1  haad 		    (val_array[ai] == val_arg))
    663           1.1  haad 			return (1);
    664           1.1  haad 		break;
    665           1.1  haad 	}
    666           1.1  haad 	case DATA_TYPE_INT64: {
    667           1.1  haad 		int64_t val, val_arg;
    668           1.1  haad 
    669           1.1  haad 		/* scanf int64_t from value and check for match */
    670           1.1  haad 		sr = sscanf(value, "%"SCNi64, &val_arg);
    671           1.1  haad 		if ((sr == 1) &&
    672           1.1  haad 		    (nvpair_value_int64(nvp, &val) == 0) &&
    673           1.1  haad 		    (val == val_arg))
    674           1.1  haad 			return (1);
    675           1.1  haad 		break;
    676           1.1  haad 	}
    677           1.1  haad 	case DATA_TYPE_INT64_ARRAY: {
    678           1.1  haad 		int64_t *val_array, val_arg;
    679           1.1  haad 
    680           1.1  haad 		/* check indexed value of array for match */
    681           1.1  haad 		sr = sscanf(value, "%"SCNi64, &val_arg);
    682           1.1  haad 		if ((sr == 1) &&
    683           1.1  haad 		    (nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) &&
    684           1.1  haad 		    (ai < a_len) &&
    685           1.1  haad 		    (val_array[ai] == val_arg))
    686           1.1  haad 				return (1);
    687           1.1  haad 		break;
    688           1.1  haad 	}
    689           1.1  haad 	case DATA_TYPE_UINT64: {
    690           1.1  haad 		uint64_t val_arg, val;
    691           1.1  haad 
    692           1.1  haad 		/* scanf uint64_t from value and check for match */
    693           1.1  haad 		sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
    694           1.1  haad 		if ((sr == 1) &&
    695           1.1  haad 		    (nvpair_value_uint64(nvp, &val) == 0) &&
    696           1.1  haad 		    (val == val_arg))
    697           1.1  haad 			return (1);
    698           1.1  haad 		break;
    699           1.1  haad 	}
    700           1.1  haad 	case DATA_TYPE_UINT64_ARRAY: {
    701           1.1  haad 		uint64_t *val_array, val_arg;
    702           1.1  haad 
    703           1.1  haad 		/* check indexed value of array for match */
    704           1.1  haad 		sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
    705           1.1  haad 		if ((sr == 1) &&
    706           1.1  haad 		    (nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) &&
    707           1.1  haad 		    (ai < a_len) &&
    708           1.1  haad 		    (val_array[ai] == val_arg))
    709           1.1  haad 			return (1);
    710           1.1  haad 		break;
    711           1.1  haad 	}
    712           1.1  haad 	case DATA_TYPE_BOOLEAN_VALUE: {
    713           1.1  haad 		boolean_t val, val_arg;
    714           1.1  haad 
    715           1.1  haad 		/* scanf boolean_t from value and check for match */
    716           1.1  haad 		sr = sscanf(value, "%"SCNi32, &val_arg);
    717           1.1  haad 		if ((sr == 1) &&
    718           1.1  haad 		    (nvpair_value_boolean_value(nvp, &val) == 0) &&
    719           1.1  haad 		    (val == val_arg))
    720           1.1  haad 			return (1);
    721           1.1  haad 		break;
    722           1.1  haad 	}
    723           1.1  haad 	case DATA_TYPE_BOOLEAN_ARRAY: {
    724           1.1  haad 		boolean_t *val_array, val_arg;
    725           1.1  haad 
    726           1.1  haad 		/* check indexed value of array for match */
    727           1.1  haad 		sr = sscanf(value, "%"SCNi32, &val_arg);
    728           1.1  haad 		if ((sr == 1) &&
    729           1.1  haad 		    (nvpair_value_boolean_array(nvp,
    730           1.1  haad 		    &val_array, &a_len) == 0) &&
    731           1.1  haad 		    (ai < a_len) &&
    732           1.1  haad 		    (val_array[ai] == val_arg))
    733           1.1  haad 			return (1);
    734           1.1  haad 		break;
    735           1.1  haad 	}
    736           1.1  haad 	case DATA_TYPE_HRTIME:
    737           1.1  haad 	case DATA_TYPE_NVLIST:
    738           1.1  haad 	case DATA_TYPE_NVLIST_ARRAY:
    739           1.1  haad 	case DATA_TYPE_BOOLEAN:
    740           1.1  haad 	case DATA_TYPE_DOUBLE:
    741           1.1  haad 	case DATA_TYPE_UNKNOWN:
    742           1.1  haad 	default:
    743           1.1  haad 		/*
    744           1.1  haad 		 * unknown/unsupported data type
    745           1.1  haad 		 */
    746           1.1  haad 		return (-1);		/* error fail match */
    747           1.1  haad 	}
    748           1.1  haad 
    749           1.1  haad 	/*
    750           1.1  haad 	 * check to see if sscanf failed conversion, return approximate
    751           1.1  haad 	 * pointer to problem
    752           1.1  haad 	 */
    753           1.1  haad 	if (sr != 1) {
    754           1.1  haad 		if (ep)
    755           1.1  haad 			*ep = value;
    756           1.1  haad 		return (-1);		/* error fail match  - syntax */
    757           1.1  haad 	}
    758           1.1  haad 
    759           1.1  haad 	return (0);			/* fail match */
    760           1.1  haad }
    761           1.1  haad 
    762           1.1  haad int
    763           1.1  haad nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep)
    764           1.1  haad {
    765           1.1  haad 	return (nvpair_value_match_regex(nvp, ai, value, NULL, ep));
    766           1.1  haad }
    767