xref: /onnv-gate/usr/src/cmd/mdb/common/modules/genunix/nvpair.c (revision 789:b348f31ed315)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <sys/sysinfo.h>
300Sstevel@tonic-gate #include <sys/nvpair.h>
310Sstevel@tonic-gate #include <sys/nvpair_impl.h>
320Sstevel@tonic-gate 
330Sstevel@tonic-gate #include <ctype.h>
340Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
350Sstevel@tonic-gate 
360Sstevel@tonic-gate #include "nvpair.h"
370Sstevel@tonic-gate 
380Sstevel@tonic-gate #define	NVPAIR_VALUE_INDENT	4
390Sstevel@tonic-gate #define	NELEM(a)		(sizeof (a) / sizeof ((a)[0]))
400Sstevel@tonic-gate 
410Sstevel@tonic-gate /*
420Sstevel@tonic-gate  * nvpair walker
430Sstevel@tonic-gate  */
440Sstevel@tonic-gate int
450Sstevel@tonic-gate nvpair_walk_init(mdb_walk_state_t *wsp)
460Sstevel@tonic-gate {
470Sstevel@tonic-gate 	nvlist_t nvlist;
480Sstevel@tonic-gate 	nvpriv_t nvpriv;
490Sstevel@tonic-gate 	i_nvp_t *tmp;
500Sstevel@tonic-gate 
510Sstevel@tonic-gate 	if (wsp->walk_addr == NULL) {
520Sstevel@tonic-gate 		mdb_warn("nvpair does not support global walks\n");
530Sstevel@tonic-gate 		return (WALK_ERR);
540Sstevel@tonic-gate 	}
550Sstevel@tonic-gate 
560Sstevel@tonic-gate 	if (mdb_vread(&nvlist, sizeof (nvlist), wsp->walk_addr) == -1) {
570Sstevel@tonic-gate 		mdb_warn("failed to read nvlist at %p", wsp->walk_addr);
580Sstevel@tonic-gate 		return (WALK_ERR);
590Sstevel@tonic-gate 	}
600Sstevel@tonic-gate 
610Sstevel@tonic-gate 	if (mdb_vread(&nvpriv, sizeof (nvpriv), nvlist.nvl_priv) == -1) {
620Sstevel@tonic-gate 		mdb_warn("failed to read nvpriv at %p", nvlist.nvl_priv);
630Sstevel@tonic-gate 		return (WALK_ERR);
640Sstevel@tonic-gate 	}
650Sstevel@tonic-gate 
660Sstevel@tonic-gate 	tmp = (i_nvp_t *)nvpriv.nvp_list;
670Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)tmp;
680Sstevel@tonic-gate 	return (WALK_NEXT);
690Sstevel@tonic-gate }
700Sstevel@tonic-gate 
710Sstevel@tonic-gate int
720Sstevel@tonic-gate nvpair_walk_step(mdb_walk_state_t *wsp)
730Sstevel@tonic-gate {
740Sstevel@tonic-gate 	int	status;
750Sstevel@tonic-gate 	nvpair_t *nvpair;
760Sstevel@tonic-gate 	i_nvp_t i_nvp, *tmp;
770Sstevel@tonic-gate 
780Sstevel@tonic-gate 	if (wsp->walk_addr == NULL)
790Sstevel@tonic-gate 		return (WALK_DONE);
800Sstevel@tonic-gate 
810Sstevel@tonic-gate 	if (mdb_vread(&i_nvp, sizeof (i_nvp), wsp->walk_addr) == -1) {
820Sstevel@tonic-gate 		mdb_warn("failed to read i_nvp at %p", wsp->walk_addr);
830Sstevel@tonic-gate 		return (WALK_ERR);
840Sstevel@tonic-gate 	}
850Sstevel@tonic-gate 
860Sstevel@tonic-gate 	nvpair = &((i_nvp_t *)wsp->walk_addr)->nvi_nvp;
870Sstevel@tonic-gate 	status = wsp->walk_callback((uintptr_t)nvpair, NULL, wsp->walk_cbdata);
880Sstevel@tonic-gate 
890Sstevel@tonic-gate 	tmp = i_nvp.nvi_next;
900Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)tmp;
910Sstevel@tonic-gate 	return (status);
920Sstevel@tonic-gate }
930Sstevel@tonic-gate 
94*789Sahrens /*
95*789Sahrens  * ::nvlist [-v]
96*789Sahrens  *
97*789Sahrens  * Print out an entire nvlist.  This is shorthand for '::walk nvpair |
98*789Sahrens  * ::nvpair -rq'.  The '-v' option invokes '::nvpair' without the "-q" option.
99*789Sahrens  */
100*789Sahrens /*ARGSUSED*/
101*789Sahrens int
102*789Sahrens nvlist_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
103*789Sahrens {
104*789Sahrens 	int verbose = B_FALSE;
105*789Sahrens 	mdb_arg_t v;
106*789Sahrens 
107*789Sahrens 	if (!(flags & DCMD_ADDRSPEC))
108*789Sahrens 		return (DCMD_USAGE);
109*789Sahrens 
110*789Sahrens 	if (mdb_getopts(argc, argv,
111*789Sahrens 	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
112*789Sahrens 	    NULL) != argc)
113*789Sahrens 		return (DCMD_USAGE);
114*789Sahrens 
115*789Sahrens 	v.a_type = MDB_TYPE_STRING;
116*789Sahrens 	if (verbose)
117*789Sahrens 		v.a_un.a_str = "-r";
118*789Sahrens 	else
119*789Sahrens 		v.a_un.a_str = "-rq";
120*789Sahrens 
121*789Sahrens 	return (mdb_pwalk_dcmd("nvpair", "nvpair", 1, &v, addr));
122*789Sahrens }
1230Sstevel@tonic-gate 
1240Sstevel@tonic-gate /*
125*789Sahrens  * ::nvpair [-rq]
126*789Sahrens  *
127*789Sahrens  * 	-r	Recursively print any nvlist elements
128*789Sahrens  * 	-q	Quiet mode; print members only as "name=value"
129*789Sahrens  *
130*789Sahrens  * Prints out a single nvpair.  By default, all information is printed.  When
131*789Sahrens  * given the '-q' option, the type of elements is hidden, and elements are
132*789Sahrens  * instead printed simply as 'name=value'.
1330Sstevel@tonic-gate  */
1340Sstevel@tonic-gate typedef struct {
1350Sstevel@tonic-gate 	data_type_t	type;
1360Sstevel@tonic-gate 	int		elem_size;
1370Sstevel@tonic-gate 	char		*type_name;
1380Sstevel@tonic-gate } nvpair_info_t;
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate nvpair_info_t nvpair_info[] =  {
1410Sstevel@tonic-gate 	{ DATA_TYPE_BOOLEAN,		1, "boolean" },
1420Sstevel@tonic-gate 	{ DATA_TYPE_BOOLEAN_VALUE,	4, "boolean_value" },
1430Sstevel@tonic-gate 	{ DATA_TYPE_BYTE,		1, "byte" },
1440Sstevel@tonic-gate 	{ DATA_TYPE_INT8,		1, "int8" },
1450Sstevel@tonic-gate 	{ DATA_TYPE_UINT8,		1, "uint8" },
1460Sstevel@tonic-gate 	{ DATA_TYPE_INT16,		2, "int16" },
1470Sstevel@tonic-gate 	{ DATA_TYPE_UINT16,		2, "uint16" },
1480Sstevel@tonic-gate 	{ DATA_TYPE_INT32,		4, "int32" },
1490Sstevel@tonic-gate 	{ DATA_TYPE_UINT32,		4, "uint32" },
1500Sstevel@tonic-gate 	{ DATA_TYPE_INT64,		8, "int64" },
1510Sstevel@tonic-gate 	{ DATA_TYPE_UINT64,		8, "uint64" },
1520Sstevel@tonic-gate 	{ DATA_TYPE_STRING,		0, "string" },
1530Sstevel@tonic-gate 	{ DATA_TYPE_NVLIST,		0, "nvpair_list" },
1540Sstevel@tonic-gate 	{ DATA_TYPE_HRTIME,		8, "hrtime" },
1550Sstevel@tonic-gate 	{ DATA_TYPE_BOOLEAN_ARRAY,	4, "boolean_array" },
1560Sstevel@tonic-gate 	{ DATA_TYPE_BYTE_ARRAY,		1, "byte_array" },
1570Sstevel@tonic-gate 	{ DATA_TYPE_INT8_ARRAY,		1, "int8_array" },
1580Sstevel@tonic-gate 	{ DATA_TYPE_UINT8_ARRAY,	1, "uint8_array" },
1590Sstevel@tonic-gate 	{ DATA_TYPE_INT16_ARRAY,	2, "int16_array" },
1600Sstevel@tonic-gate 	{ DATA_TYPE_UINT16_ARRAY,	2, "uint16_array" },
1610Sstevel@tonic-gate 	{ DATA_TYPE_INT32_ARRAY,	4, "int32_array" },
1620Sstevel@tonic-gate 	{ DATA_TYPE_UINT32_ARRAY,	4, "uint32_array" },
1630Sstevel@tonic-gate 	{ DATA_TYPE_INT64_ARRAY, 	8, "int64_array" },
1640Sstevel@tonic-gate 	{ DATA_TYPE_UINT64_ARRAY,	8, "uint64_array" },
1650Sstevel@tonic-gate 	{ DATA_TYPE_STRING_ARRAY,	0, "string_array" },
1660Sstevel@tonic-gate 	{ DATA_TYPE_NVLIST_ARRAY,	0, "nvpair list_array" }
1670Sstevel@tonic-gate };
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate static void
1700Sstevel@tonic-gate nvpair_print_value(char *data, int32_t elem_size, int32_t nelem,
1710Sstevel@tonic-gate     data_type_t type)
1720Sstevel@tonic-gate {
1730Sstevel@tonic-gate 	int32_t i;
1740Sstevel@tonic-gate 
1750Sstevel@tonic-gate 	if (elem_size == 0) {
1760Sstevel@tonic-gate 		char *p = data;
1770Sstevel@tonic-gate 
1780Sstevel@tonic-gate 		/* print out all the strings */
1790Sstevel@tonic-gate 		for (i = 0; i < nelem - 1; i++) {
1800Sstevel@tonic-gate 			mdb_printf("'%s' + ", p);
1810Sstevel@tonic-gate 			p += strlen(p) + 1;
1820Sstevel@tonic-gate 		}
1830Sstevel@tonic-gate 		mdb_printf("'%s'", p);
1840Sstevel@tonic-gate 	} else if (type == DATA_TYPE_BOOLEAN_VALUE ||
1850Sstevel@tonic-gate 	    type == DATA_TYPE_BOOLEAN_ARRAY) {
1860Sstevel@tonic-gate 		/* LINTED - pointer alignment */
1870Sstevel@tonic-gate 		boolean_t *p = (boolean_t *)data;
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate 		for (i = 0; i < nelem; i++) {
1900Sstevel@tonic-gate 			if (i > 0)
1910Sstevel@tonic-gate 				mdb_printf(".");
1920Sstevel@tonic-gate 			mdb_printf("%d", p[i]);
1930Sstevel@tonic-gate 		}
1940Sstevel@tonic-gate 	} else {
1950Sstevel@tonic-gate 		unsigned char	*p = (unsigned char *)data;
1960Sstevel@tonic-gate 		int		size = elem_size * nelem;
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate 		/*
1990Sstevel@tonic-gate 		 * if elem_size != 0 then we are printing out an array
2000Sstevel@tonic-gate 		 * where each element is of elem_size
2010Sstevel@tonic-gate 		 */
2020Sstevel@tonic-gate 		mdb_nhconvert(p, p, elem_size);
2030Sstevel@tonic-gate 		mdb_printf("%02x", *p);
2040Sstevel@tonic-gate 		for (i = 1; i < size; i++) {
2050Sstevel@tonic-gate 			if ((i % elem_size) == 0) {
2060Sstevel@tonic-gate 				mdb_nhconvert(&p[i], &p[i], elem_size);
2070Sstevel@tonic-gate 				mdb_printf(".");
2080Sstevel@tonic-gate 			}
2090Sstevel@tonic-gate 			mdb_printf("%02x", p[i]);
2100Sstevel@tonic-gate 		}
2110Sstevel@tonic-gate 	}
2120Sstevel@tonic-gate 	mdb_printf("\n");
2130Sstevel@tonic-gate }
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate /*ARGSUSED*/
2160Sstevel@tonic-gate int
2170Sstevel@tonic-gate nvpair_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2180Sstevel@tonic-gate {
2190Sstevel@tonic-gate 	nvpair_t	nvpair_tmp, *nvpair;
2200Sstevel@tonic-gate 	int32_t		i, size, nelem, elem_size = 0;
2210Sstevel@tonic-gate 	char		*data = NULL, *data_end = NULL;
2220Sstevel@tonic-gate 	char		*type_name = NULL;
2230Sstevel@tonic-gate 	data_type_t	type = DATA_TYPE_UNKNOWN;
224*789Sahrens 	int		quiet = FALSE;
225*789Sahrens 	int		recurse = FALSE;
2260Sstevel@tonic-gate 
227*789Sahrens 	if (!(flags & DCMD_ADDRSPEC))
228*789Sahrens 		return (DCMD_USAGE);
229*789Sahrens 
230*789Sahrens 	if (mdb_getopts(argc, argv,
231*789Sahrens 	    'r', MDB_OPT_SETBITS, TRUE, &recurse,
232*789Sahrens 	    'q', MDB_OPT_SETBITS, TRUE, &quiet,
233*789Sahrens 	    NULL) != argc)
2340Sstevel@tonic-gate 		return (DCMD_USAGE);
2350Sstevel@tonic-gate 
2360Sstevel@tonic-gate 	/* read in the nvpair header so we can get the size */
2370Sstevel@tonic-gate 	if (mdb_vread(&nvpair_tmp, sizeof (nvpair), addr) == -1) {
2380Sstevel@tonic-gate 		mdb_warn("failed to read nvpair at %p", addr);
2390Sstevel@tonic-gate 		return (DCMD_ERR);
2400Sstevel@tonic-gate 	}
2410Sstevel@tonic-gate 	size = NVP_SIZE(&nvpair_tmp);
2420Sstevel@tonic-gate 	if (size == 0) {
2430Sstevel@tonic-gate 		mdb_warn("nvpair of size zero at %p", addr);
2440Sstevel@tonic-gate 		return (DCMD_OK);
2450Sstevel@tonic-gate 	}
2460Sstevel@tonic-gate 
2470Sstevel@tonic-gate 	/* read in the entire nvpair */
2480Sstevel@tonic-gate 	nvpair = mdb_alloc(size, UM_SLEEP | UM_GC);
2490Sstevel@tonic-gate 	if (mdb_vread(nvpair, size, addr) == -1) {
2500Sstevel@tonic-gate 		mdb_warn("failed to read nvpair and data at %p", addr);
2510Sstevel@tonic-gate 		return (DCMD_ERR);
2520Sstevel@tonic-gate 	}
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate 	/* lookup type decoding information for this nvpair */
2550Sstevel@tonic-gate 	type = NVP_TYPE(nvpair);
2560Sstevel@tonic-gate 	nelem = NVP_NELEM(nvpair);
2570Sstevel@tonic-gate 	for (i = 0; i < NELEM(nvpair_info); i++) {
2580Sstevel@tonic-gate 		if (nvpair_info[i].type == type) {
2590Sstevel@tonic-gate 			elem_size = nvpair_info[i].elem_size;
2600Sstevel@tonic-gate 			type_name = nvpair_info[i].type_name;
2610Sstevel@tonic-gate 			break;
2620Sstevel@tonic-gate 		}
2630Sstevel@tonic-gate 	}
264*789Sahrens 
265*789Sahrens 	if (quiet) {
266*789Sahrens 		mdb_printf("%s", NVP_NAME(nvpair));
2670Sstevel@tonic-gate 	} else {
268*789Sahrens 		/* print out the first line of nvpair info */
269*789Sahrens 		mdb_printf("name='%s'", NVP_NAME(nvpair));
270*789Sahrens 		if (type_name != NULL) {
271*789Sahrens 			mdb_printf(" type=%s", type_name);
272*789Sahrens 		} else {
273*789Sahrens 			/*
274*789Sahrens 			 * If the nvpair type is unknown we print the type
275*789Sahrens 			 * number
276*789Sahrens 			 */
277*789Sahrens 			mdb_printf(" type=0x%x", type);
278*789Sahrens 		}
279*789Sahrens 		mdb_printf(" items=%d\n", nelem);
2800Sstevel@tonic-gate 	}
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate 	/* if there is no data and the type is known then we're done */
283*789Sahrens 	if ((nelem == 0) && (type_name != NULL)) {
284*789Sahrens 		if (quiet)
285*789Sahrens 			mdb_printf("(unknown)\n");
2860Sstevel@tonic-gate 		return (DCMD_OK);
287*789Sahrens 	}
2880Sstevel@tonic-gate 
2890Sstevel@tonic-gate 	/* get pointers to the data to print out */
2900Sstevel@tonic-gate 	data = (char *)NVP_VALUE(nvpair);
2910Sstevel@tonic-gate 	data_end = (char *)nvpair + NVP_SIZE(nvpair);
2920Sstevel@tonic-gate 
2930Sstevel@tonic-gate 	/*
2940Sstevel@tonic-gate 	 * The value of the name-value pair for a single embedded
2950Sstevel@tonic-gate 	 * list is the nvlist_t structure for the embedded list.
2960Sstevel@tonic-gate 	 * So we print that address out (computed as an offset from
2970Sstevel@tonic-gate 	 * the nvpair address we received as addr).
2980Sstevel@tonic-gate 	 *
2990Sstevel@tonic-gate 	 * The value of the name-value pair for an array of embedded
3000Sstevel@tonic-gate 	 * lists is nelem pointers to nvlist_t structures followed
3010Sstevel@tonic-gate 	 * by the structures themselves.  We display the list
3020Sstevel@tonic-gate 	 * of pointers as the pair's value.
3030Sstevel@tonic-gate 	 */
3040Sstevel@tonic-gate 	if (type == DATA_TYPE_NVLIST) {
3050Sstevel@tonic-gate 		char *p = (char *)addr + (data - (char *)nvpair);
306*789Sahrens 		if (recurse) {
307*789Sahrens 			if (quiet)
308*789Sahrens 				mdb_printf("\n");
309*789Sahrens 			mdb_inc_indent(NVPAIR_VALUE_INDENT);
310*789Sahrens 			if (mdb_pwalk_dcmd("nvpair", "nvpair", argc, argv,
311*789Sahrens 			    (uintptr_t)p) != DCMD_OK)
312*789Sahrens 				return (DCMD_ERR);
313*789Sahrens 			mdb_dec_indent(NVPAIR_VALUE_INDENT);
314*789Sahrens 		} else {
315*789Sahrens 			if (!quiet) {
316*789Sahrens 				mdb_inc_indent(NVPAIR_VALUE_INDENT);
317*789Sahrens 				mdb_printf("value", p);
318*789Sahrens 			}
319*789Sahrens 			mdb_printf("=%p\n", p);
320*789Sahrens 			if (!quiet)
321*789Sahrens 				mdb_dec_indent(NVPAIR_VALUE_INDENT);
322*789Sahrens 		}
3230Sstevel@tonic-gate 		return (DCMD_OK);
3240Sstevel@tonic-gate 
3250Sstevel@tonic-gate 	} else if (type == DATA_TYPE_NVLIST_ARRAY) {
326*789Sahrens 		if (recurse) {
327*789Sahrens 			for (i = 0; i < nelem; i++,
328*789Sahrens 			    data += sizeof (nvlist_t *)) {
329*789Sahrens 				nvlist_t **nl = (nvlist_t **)(void *)data;
330*789Sahrens 				if (quiet && i != 0)
331*789Sahrens 					mdb_printf("%s", NVP_NAME(nvpair));
332*789Sahrens 				mdb_printf("[%d]\n", i);
333*789Sahrens 				mdb_inc_indent(NVPAIR_VALUE_INDENT);
334*789Sahrens 				if (mdb_pwalk_dcmd("nvpair", "nvpair", argc,
335*789Sahrens 				    argv, (uintptr_t)*nl) != DCMD_OK)
336*789Sahrens 					return (DCMD_ERR);
337*789Sahrens 				mdb_dec_indent(NVPAIR_VALUE_INDENT);
338*789Sahrens 			}
339*789Sahrens 		} else {
340*789Sahrens 			if (!quiet) {
341*789Sahrens 				mdb_inc_indent(NVPAIR_VALUE_INDENT);
342*789Sahrens 				mdb_printf("value");
343*789Sahrens 			}
344*789Sahrens 			mdb_printf("=");
345*789Sahrens 			for (i = 0; i < nelem; i++,
346*789Sahrens 			    data += sizeof (nvlist_t *)) {
347*789Sahrens 				nvlist_t **nl = (nvlist_t **)(void *)data;
348*789Sahrens 				mdb_printf("%c%p", " "[i == 0], *nl);
349*789Sahrens 			}
350*789Sahrens 			mdb_printf("\n");
351*789Sahrens 			if (!quiet)
352*789Sahrens 				mdb_dec_indent(NVPAIR_VALUE_INDENT);
3530Sstevel@tonic-gate 		}
3540Sstevel@tonic-gate 		return (DCMD_OK);
3550Sstevel@tonic-gate 	}
3560Sstevel@tonic-gate 
3570Sstevel@tonic-gate 	/* if it's a string array, skip the index pointers */
3580Sstevel@tonic-gate 	if (type == DATA_TYPE_STRING_ARRAY)
3590Sstevel@tonic-gate 		data += (sizeof (int64_t) * nelem);
3600Sstevel@tonic-gate 
3610Sstevel@tonic-gate 	/* if the type is unknown, treat the data as a byte array */
3620Sstevel@tonic-gate 	if (type_name == NULL) {
3630Sstevel@tonic-gate 		elem_size = 1;
3640Sstevel@tonic-gate 		nelem = data_end - data;
3650Sstevel@tonic-gate 	}
3660Sstevel@tonic-gate 
3670Sstevel@tonic-gate 	/*
3680Sstevel@tonic-gate 	 * if the type is of strings, make sure they are printable
3690Sstevel@tonic-gate 	 * otherwise print them out as byte arrays
3700Sstevel@tonic-gate 	 */
3710Sstevel@tonic-gate 	if (elem_size == 0) {
3720Sstevel@tonic-gate 		int32_t	count = 0;
3730Sstevel@tonic-gate 
3740Sstevel@tonic-gate 		i = 0;
3750Sstevel@tonic-gate 		while ((&data[i] < data_end) && (count < nelem)) {
3760Sstevel@tonic-gate 			if (data[i] == '\0')
3770Sstevel@tonic-gate 				count++;
3780Sstevel@tonic-gate 			else if (!isprint(data[i]))
3790Sstevel@tonic-gate 				break;
3800Sstevel@tonic-gate 			i++;
3810Sstevel@tonic-gate 		}
3820Sstevel@tonic-gate 		if (count != nelem) {
3830Sstevel@tonic-gate 			/* there is unprintable data, output as byte array */
3840Sstevel@tonic-gate 			elem_size = 1;
3850Sstevel@tonic-gate 			nelem =  data_end - data;
3860Sstevel@tonic-gate 		}
3870Sstevel@tonic-gate 	}
3880Sstevel@tonic-gate 
389*789Sahrens 	if (!quiet) {
390*789Sahrens 		mdb_inc_indent(NVPAIR_VALUE_INDENT);
391*789Sahrens 		mdb_printf("value=");
392*789Sahrens 	} else {
393*789Sahrens 		mdb_printf("=");
394*789Sahrens 	}
3950Sstevel@tonic-gate 	nvpair_print_value(data, elem_size, nelem, type);
396*789Sahrens 	if (!quiet)
397*789Sahrens 		mdb_dec_indent(NVPAIR_VALUE_INDENT);
3980Sstevel@tonic-gate 
3990Sstevel@tonic-gate 	return (DCMD_OK);
4000Sstevel@tonic-gate }
401