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