1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 1414 cindi * Common Development and Distribution License (the "License"). 6 1414 cindi * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 1414 cindi 22 0 stevel /* 23 9501 Robert * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 0 stevel * Use is subject to license terms. 25 0 stevel */ 26 0 stevel 27 0 stevel 28 0 stevel #include <sys/fm/protocol.h> 29 0 stevel #include <fm/libtopo.h> 30 3062 cindi #include <ctype.h> 31 4087 cindi #include <fnmatch.h> 32 1414 cindi #include <limits.h> 33 1414 cindi #include <strings.h> 34 1414 cindi #include <stdio.h> 35 1414 cindi #include <errno.h> 36 4087 cindi #include <umem.h> 37 3062 cindi #include <sys/param.h> 38 0 stevel 39 1414 cindi #define FMTOPO_EXIT_SUCCESS 0 40 1414 cindi #define FMTOPO_EXIT_ERROR 1 41 1414 cindi #define FMTOPO_EXIT_USAGE 2 42 0 stevel 43 3062 cindi #define STDERR "stderr" 44 3062 cindi #define DOTS "..." 45 3062 cindi #define ALL "all" 46 3062 cindi 47 1414 cindi static const char *g_pname; 48 4087 cindi static const char *g_fmri = NULL; 49 1414 cindi 50 1414 cindi static const char *opt_R = "/"; 51 1414 cindi static const char *opt_s = FM_FMRI_SCHEME_HC; 52 9501 Robert static const char optstr[] = "bCdem:P:pR:s:StVx"; 53 9501 Robert static const char *opt_m; 54 1414 cindi 55 6341 cy152378 static int opt_b = 0; 56 6341 cy152378 static int opt_d = 0; 57 3062 cindi static int opt_e = 0; 58 3062 cindi static int opt_p = 0; 59 4087 cindi static int opt_S = 0; 60 4087 cindi static int opt_t = 0; 61 6341 cy152378 static int opt_V = 0; 62 3062 cindi static int opt_x = 0; 63 4087 cindi static int opt_all = 0; 64 4087 cindi 65 4087 cindi struct prop_args { 66 4087 cindi const char *group; 67 4087 cindi const char *prop; 68 4087 cindi const char *type; 69 4087 cindi const char *value; 70 4087 cindi }; 71 4087 cindi 72 4087 cindi static struct prop_args **pargs = NULL; 73 4087 cindi static int pcnt = 0; 74 1414 cindi 75 1414 cindi static int 76 1414 cindi usage(FILE *fp) 77 0 stevel { 78 1414 cindi (void) fprintf(fp, 79 7585 Robert "Usage: %s [-bCedpSVx] [-P group.property[=type:value]] " 80 9501 Robert "[-R root] [-m method] [-s scheme] [fmri]\n", g_pname); 81 1414 cindi 82 1414 cindi (void) fprintf(fp, 83 6341 cy152378 "\t-b walk in sibling-first order (default is child-first)\n" 84 1414 cindi "\t-C dump core after completing execution\n" 85 3062 cindi "\t-d set debug mode for libtopo modules\n" 86 3062 cindi "\t-e display FMRIs as paths using esc/eft notation\n" 87 9501 Robert "\t-m execute given method\n" 88 4087 cindi "\t-P get/set specified properties\n" 89 3062 cindi "\t-p display of FMRI protocol properties\n" 90 1414 cindi "\t-R set root directory for libtopo plug-ins and other files\n" 91 1414 cindi "\t-s display topology for the specified FMRI scheme\n" 92 4087 cindi "\t-S display FMRI status (present/usable)\n" 93 3062 cindi "\t-V set verbose mode\n" 94 3062 cindi "\t-x display a xml formatted topology\n"); 95 1414 cindi 96 1414 cindi return (FMTOPO_EXIT_USAGE); 97 0 stevel } 98 0 stevel 99 4087 cindi static topo_type_t 100 4087 cindi str2type(const char *tstr) 101 0 stevel { 102 4087 cindi topo_type_t type; 103 0 stevel 104 4087 cindi if (tstr == NULL) 105 4087 cindi return (TOPO_TYPE_INVALID); 106 4087 cindi 107 4087 cindi if (strcmp(tstr, "int32") == 0) 108 4087 cindi type = TOPO_TYPE_INT32; 109 4087 cindi else if (strcmp(tstr, "uint32") == 0) 110 4087 cindi type = TOPO_TYPE_UINT32; 111 4087 cindi else if (strcmp(tstr, "int64") == 0) 112 4087 cindi type = TOPO_TYPE_INT64; 113 4087 cindi else if (strcmp(tstr, "uint64") == 0) 114 4087 cindi type = TOPO_TYPE_UINT64; 115 4087 cindi else if (strcmp(tstr, "string") == 0) 116 4087 cindi type = TOPO_TYPE_STRING; 117 4087 cindi else if (strcmp(tstr, "fmri") == 0) 118 4087 cindi type = TOPO_TYPE_FMRI; 119 4087 cindi else { 120 4087 cindi type = TOPO_TYPE_INVALID; 121 0 stevel } 122 0 stevel 123 4087 cindi return (type); 124 4087 cindi } 125 0 stevel 126 4087 cindi static void 127 4087 cindi print_node(topo_hdl_t *thp, tnode_t *node, nvlist_t *nvl, const char *fmri) 128 4087 cindi { 129 4087 cindi int err, ret; 130 0 stevel 131 4087 cindi (void) printf("%s\n", (char *)fmri); 132 4087 cindi 133 4087 cindi if (opt_p && !(pcnt > 0 || opt_V || opt_all)) { 134 1414 cindi char *aname = NULL, *fname = NULL, *lname = NULL; 135 1414 cindi nvlist_t *asru = NULL; 136 1414 cindi nvlist_t *fru = NULL; 137 0 stevel 138 1414 cindi if (topo_node_asru(node, &asru, NULL, &err) == 0) 139 4328 cindi (void) topo_fmri_nvl2str(thp, asru, &aname, &err); 140 1414 cindi if (topo_node_fru(node, &fru, NULL, &err) == 0) 141 4328 cindi (void) topo_fmri_nvl2str(thp, fru, &fname, &err); 142 1414 cindi (void) topo_node_label(node, &lname, &err); 143 1414 cindi if (aname != NULL) { 144 1414 cindi nvlist_free(asru); 145 1414 cindi (void) printf("\tASRU: %s\n", aname); 146 1414 cindi topo_hdl_strfree(thp, aname); 147 1414 cindi } else { 148 1414 cindi (void) printf("\tASRU: -\n"); 149 1414 cindi } 150 1414 cindi if (fname != NULL) { 151 1414 cindi nvlist_free(fru); 152 1414 cindi (void) printf("\tFRU: %s\n", fname); 153 1414 cindi topo_hdl_strfree(thp, fname); 154 1414 cindi } else { 155 1414 cindi (void) printf("\tFRU: -\n"); 156 1414 cindi } 157 1414 cindi if (lname != NULL) { 158 1414 cindi (void) printf("\tLabel: %s\n", lname); 159 1414 cindi topo_hdl_strfree(thp, lname); 160 1414 cindi } else { 161 1414 cindi (void) printf("\tLabel: -\n"); 162 0 stevel } 163 0 stevel } 164 0 stevel 165 4087 cindi if (opt_S) { 166 4087 cindi if ((ret = topo_fmri_present(thp, nvl, &err)) < 0) 167 4087 cindi (void) printf("\tPresent: -\n"); 168 4087 cindi else 169 4087 cindi (void) printf("\tPresent: %s\n", 170 4087 cindi ret ? "true" : "false"); 171 4087 cindi 172 4087 cindi if ((ret = topo_fmri_unusable(thp, nvl, &err)) < 0) 173 4087 cindi (void) printf("\tUnusable: -\n"); 174 4087 cindi else 175 4087 cindi (void) printf("\tUnusable: %s\n", 176 4087 cindi ret ? "true" : "false"); 177 4087 cindi } 178 1414 cindi } 179 1414 cindi 180 1414 cindi static void 181 1414 cindi print_everstyle(tnode_t *node) 182 1414 cindi { 183 1414 cindi char buf[PATH_MAX], numbuf[64]; 184 1414 cindi nvlist_t *fmri, **hcl; 185 1414 cindi int i, err; 186 1414 cindi uint_t n; 187 1414 cindi 188 1414 cindi if (topo_prop_get_fmri(node, TOPO_PGROUP_PROTOCOL, 189 1414 cindi TOPO_PROP_RESOURCE, &fmri, &err) < 0) { 190 1414 cindi (void) fprintf(stderr, "%s: failed to get fmri for %s=%d: %s\n", 191 1414 cindi g_pname, topo_node_name(node), 192 1414 cindi topo_node_instance(node), topo_strerror(err)); 193 1414 cindi return; 194 1414 cindi } 195 1414 cindi 196 1414 cindi if (nvlist_lookup_nvlist_array(fmri, FM_FMRI_HC_LIST, &hcl, &n) != 0) { 197 1414 cindi (void) fprintf(stderr, "%s: failed to find %s for %s=%d\n", 198 1414 cindi g_pname, FM_FMRI_HC_LIST, topo_node_name(node), 199 1414 cindi topo_node_instance(node)); 200 7243 robj nvlist_free(fmri); 201 1414 cindi return; 202 1414 cindi } 203 1414 cindi 204 1414 cindi buf[0] = '\0'; 205 1414 cindi 206 1414 cindi for (i = 0; i < n; i++) { 207 1414 cindi char *name, *inst, *estr; 208 1414 cindi ulong_t ul; 209 1414 cindi 210 1414 cindi if (nvlist_lookup_string(hcl[i], FM_FMRI_HC_NAME, &name) != 0 || 211 1414 cindi nvlist_lookup_string(hcl[i], FM_FMRI_HC_ID, &inst) != 0) { 212 1414 cindi (void) fprintf(stderr, "%s: failed to get " 213 1414 cindi "name-instance for %s=%d\n", g_pname, 214 1414 cindi topo_node_name(node), topo_node_instance(node)); 215 7243 robj nvlist_free(fmri); 216 1414 cindi return; 217 1414 cindi } 218 1414 cindi 219 1414 cindi errno = 0; 220 1414 cindi ul = strtoul(inst, &estr, 10); 221 1414 cindi 222 1414 cindi if (errno != 0 || estr == inst) { 223 1414 cindi (void) fprintf(stderr, "%s: instance %s does not " 224 1414 cindi "convert to an unsigned integer\n", g_pname, inst); 225 1414 cindi } 226 1414 cindi 227 1414 cindi (void) strlcat(buf, "/", sizeof (buf)); 228 1414 cindi (void) strlcat(buf, name, sizeof (buf)); 229 1414 cindi (void) snprintf(numbuf, sizeof (numbuf), "%u", ul); 230 1414 cindi (void) strlcat(buf, numbuf, sizeof (buf)); 231 1414 cindi } 232 7243 robj nvlist_free(fmri); 233 1414 cindi 234 1414 cindi (void) printf("%s\n", buf); 235 1414 cindi } 236 1414 cindi 237 3062 cindi static void 238 7243 robj print_prop_nameval(topo_hdl_t *thp, tnode_t *node, nvlist_t *nvl) 239 3062 cindi { 240 3062 cindi int err; 241 3062 cindi topo_type_t type; 242 7243 robj char *tstr, *propn, buf[48], *factype; 243 3062 cindi nvpair_t *pv_nvp; 244 3323 cindi int i; 245 3323 cindi uint_t nelem; 246 3062 cindi 247 3062 cindi if ((pv_nvp = nvlist_next_nvpair(nvl, NULL)) == NULL) 248 3062 cindi return; 249 3062 cindi 250 3062 cindi /* Print property name */ 251 3062 cindi if ((pv_nvp = nvlist_next_nvpair(nvl, NULL)) == NULL || 252 3062 cindi nvpair_name(pv_nvp) == NULL || 253 3062 cindi strcmp(TOPO_PROP_VAL_NAME, nvpair_name(pv_nvp)) != 0) { 254 3062 cindi (void) fprintf(stderr, "%s: malformed property name\n", 255 3062 cindi g_pname); 256 3062 cindi return; 257 3062 cindi } else { 258 4328 cindi (void) nvpair_value_string(pv_nvp, &propn); 259 3062 cindi } 260 3062 cindi 261 3062 cindi if ((pv_nvp = nvlist_next_nvpair(nvl, pv_nvp)) == NULL || 262 3062 cindi nvpair_name(pv_nvp) == NULL || 263 3062 cindi strcmp(nvpair_name(pv_nvp), TOPO_PROP_VAL_TYPE) != 0 || 264 4087 cindi nvpair_type(pv_nvp) != DATA_TYPE_UINT32) { 265 3062 cindi (void) fprintf(stderr, "%s: malformed property type for %s\n", 266 3062 cindi g_pname, propn); 267 3062 cindi return; 268 3062 cindi } else { 269 4087 cindi (void) nvpair_value_uint32(pv_nvp, (uint32_t *)&type); 270 3062 cindi } 271 3062 cindi 272 3062 cindi switch (type) { 273 3062 cindi case TOPO_TYPE_BOOLEAN: tstr = "boolean"; break; 274 3062 cindi case TOPO_TYPE_INT32: tstr = "int32"; break; 275 3062 cindi case TOPO_TYPE_UINT32: tstr = "uint32"; break; 276 3062 cindi case TOPO_TYPE_INT64: tstr = "int64"; break; 277 3062 cindi case TOPO_TYPE_UINT64: tstr = "uint64"; break; 278 7243 robj case TOPO_TYPE_DOUBLE: tstr = "double"; break; 279 3062 cindi case TOPO_TYPE_STRING: tstr = "string"; break; 280 3062 cindi case TOPO_TYPE_FMRI: tstr = "fmri"; break; 281 3062 cindi case TOPO_TYPE_INT32_ARRAY: tstr = "int32[]"; break; 282 3062 cindi case TOPO_TYPE_UINT32_ARRAY: tstr = "uint32[]"; break; 283 3062 cindi case TOPO_TYPE_INT64_ARRAY: tstr = "int64[]"; break; 284 3062 cindi case TOPO_TYPE_UINT64_ARRAY: tstr = "uint64[]"; break; 285 3062 cindi case TOPO_TYPE_STRING_ARRAY: tstr = "string[]"; break; 286 3062 cindi case TOPO_TYPE_FMRI_ARRAY: tstr = "fmri[]"; break; 287 3062 cindi default: tstr = "unknown type"; 288 3062 cindi } 289 3062 cindi 290 11050 Robert (void) printf(" %-17s %-8s ", propn, tstr); 291 3062 cindi 292 3062 cindi /* 293 3062 cindi * Get property value 294 3062 cindi */ 295 3062 cindi if (nvpair_name(pv_nvp) == NULL || 296 3062 cindi (pv_nvp = nvlist_next_nvpair(nvl, pv_nvp)) == NULL) { 297 3062 cindi (void) fprintf(stderr, "%s: malformed property value\n", 298 3062 cindi g_pname); 299 3062 cindi return; 300 3062 cindi } 301 3062 cindi 302 3062 cindi switch (nvpair_type(pv_nvp)) { 303 3062 cindi case DATA_TYPE_INT32: { 304 3062 cindi int32_t val; 305 3062 cindi (void) nvpair_value_int32(pv_nvp, &val); 306 3062 cindi (void) printf(" %d", val); 307 3062 cindi break; 308 3062 cindi } 309 3062 cindi case DATA_TYPE_UINT32: { 310 7243 robj uint32_t val, type; 311 7243 robj char val_str[49]; 312 7243 robj nvlist_t *fac, *rsrc = NULL; 313 7243 robj 314 3062 cindi (void) nvpair_value_uint32(pv_nvp, &val); 315 7243 robj if (node == NULL || topo_node_flags(node) != 316 7243 robj TOPO_NODE_FACILITY) 317 7243 robj goto uint32_def; 318 7243 robj 319 7243 robj if (topo_node_resource(node, &rsrc, &err) != 0) 320 7243 robj goto uint32_def; 321 7243 robj 322 7243 robj if (nvlist_lookup_nvlist(rsrc, "facility", &fac) != 0) 323 7243 robj goto uint32_def; 324 7243 robj 325 7243 robj if (nvlist_lookup_string(fac, FM_FMRI_FACILITY_TYPE, 326 7243 robj &factype) != 0) 327 7243 robj goto uint32_def; 328 7243 robj 329 7243 robj nvlist_free(rsrc); 330 7243 robj rsrc = NULL; 331 7243 robj 332 7243 robj /* 333 7243 robj * Special case code to do friendlier printing of 334 7243 robj * facility node properties 335 7243 robj */ 336 7243 robj if ((strcmp(propn, TOPO_FACILITY_TYPE) == 0) && 337 7243 robj (strcmp(factype, TOPO_FAC_TYPE_SENSOR) == 0)) { 338 7243 robj topo_sensor_type_name(val, val_str, 48); 339 7243 robj (void) printf(" 0x%x (%s)", val, val_str); 340 7243 robj break; 341 7243 robj } else if ((strcmp(propn, TOPO_FACILITY_TYPE) == 0) && 342 7243 robj (strcmp(factype, TOPO_FAC_TYPE_INDICATOR) == 0)) { 343 7243 robj topo_led_type_name(val, val_str, 48); 344 7243 robj (void) printf(" 0x%x (%s)", val, val_str); 345 7243 robj break; 346 7243 robj } else if (strcmp(propn, TOPO_SENSOR_UNITS) == 0) { 347 7243 robj topo_sensor_units_name(val, val_str, 48); 348 7243 robj (void) printf(" 0x%x (%s)", val, val_str); 349 7243 robj break; 350 7243 robj } else if (strcmp(propn, TOPO_LED_MODE) == 0) { 351 7243 robj topo_led_state_name(val, val_str, 48); 352 7243 robj (void) printf(" 0x%x (%s)", val, val_str); 353 7243 robj break; 354 7243 robj } else if ((strcmp(propn, TOPO_SENSOR_STATE) == 0) && 355 7243 robj (strcmp(factype, TOPO_FAC_TYPE_SENSOR) == 0)) { 356 7243 robj if (topo_prop_get_uint32(node, 357 7243 robj TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE, 358 7243 robj &type, &err) != 0) { 359 7243 robj goto uint32_def; 360 7243 robj } 361 7243 robj topo_sensor_state_name(type, val, val_str, 48); 362 7243 robj (void) printf(" 0x%x (%s)", val, val_str); 363 7243 robj break; 364 7243 robj } 365 7243 robj uint32_def: 366 3062 cindi (void) printf(" 0x%x", val); 367 7243 robj if (rsrc != NULL) 368 7243 robj nvlist_free(rsrc); 369 3062 cindi break; 370 3062 cindi } 371 3062 cindi case DATA_TYPE_INT64: { 372 3062 cindi int64_t val; 373 3062 cindi (void) nvpair_value_int64(pv_nvp, &val); 374 3062 cindi (void) printf(" %lld", (longlong_t)val); 375 3062 cindi break; 376 3062 cindi } 377 3062 cindi case DATA_TYPE_UINT64: { 378 3062 cindi uint64_t val; 379 3062 cindi (void) nvpair_value_uint64(pv_nvp, &val); 380 3062 cindi (void) printf(" 0x%llx", (u_longlong_t)val); 381 7243 robj break; 382 7243 robj } 383 7243 robj case DATA_TYPE_DOUBLE: { 384 7243 robj double val; 385 7243 robj (void) nvpair_value_double(pv_nvp, &val); 386 7243 robj (void) printf(" %lf", (double)val); 387 3062 cindi break; 388 3062 cindi } 389 3062 cindi case DATA_TYPE_STRING: { 390 3062 cindi char *val; 391 3062 cindi (void) nvpair_value_string(pv_nvp, &val); 392 3062 cindi if (!opt_V && strlen(val) > 48) { 393 3062 cindi (void) snprintf(buf, 48, "%s...", val); 394 3062 cindi (void) printf(" %s", buf); 395 3062 cindi } else { 396 3062 cindi (void) printf(" %s", val); 397 3062 cindi } 398 3062 cindi break; 399 3062 cindi } 400 3062 cindi case DATA_TYPE_NVLIST: { 401 3062 cindi nvlist_t *val; 402 3062 cindi char *fmri; 403 3062 cindi (void) nvpair_value_nvlist(pv_nvp, &val); 404 3062 cindi if (topo_fmri_nvl2str(thp, val, &fmri, &err) != 0) { 405 3062 cindi if (opt_V) 406 3062 cindi nvlist_print(stdout, nvl); 407 3062 cindi break; 408 3062 cindi } 409 3062 cindi 410 3062 cindi if (!opt_V && strlen(fmri) > 48) { 411 3062 cindi (void) snprintf(buf, 48, "%s", fmri); 412 3062 cindi (void) snprintf(&buf[45], 4, "%s", DOTS); 413 3062 cindi (void) printf(" %s", buf); 414 3062 cindi } else { 415 3062 cindi (void) printf(" %s", fmri); 416 3062 cindi } 417 3062 cindi 418 3062 cindi topo_hdl_strfree(thp, fmri); 419 3323 cindi break; 420 3323 cindi } 421 10234 Robert case DATA_TYPE_INT32_ARRAY: { 422 10234 Robert int32_t *val; 423 10234 Robert 424 10234 Robert (void) nvpair_value_int32_array(pv_nvp, &val, &nelem); 425 10234 Robert (void) printf(" [ "); 426 10234 Robert for (i = 0; i < nelem; i++) 427 10234 Robert (void) printf("%d ", val[i]); 428 10234 Robert (void) printf("]"); 429 10234 Robert break; 430 10234 Robert } 431 3323 cindi case DATA_TYPE_UINT32_ARRAY: { 432 3323 cindi uint32_t *val; 433 3323 cindi 434 3323 cindi (void) nvpair_value_uint32_array(pv_nvp, &val, &nelem); 435 3323 cindi (void) printf(" [ "); 436 3323 cindi for (i = 0; i < nelem; i++) 437 3323 cindi (void) printf("%u ", val[i]); 438 7243 robj (void) printf("]"); 439 7243 robj break; 440 7243 robj } 441 7243 robj case DATA_TYPE_INT64_ARRAY: { 442 7243 robj int64_t *val; 443 7243 robj 444 7243 robj (void) nvpair_value_int64_array(pv_nvp, &val, &nelem); 445 7243 robj (void) printf(" [ "); 446 7243 robj for (i = 0; i < nelem; i++) 447 7243 robj (void) printf("%lld ", val[i]); 448 6640 cth (void) printf("]"); 449 6640 cth break; 450 6640 cth } 451 10234 Robert case DATA_TYPE_UINT64_ARRAY: { 452 10234 Robert uint64_t *val; 453 10234 Robert 454 10234 Robert (void) nvpair_value_uint64_array(pv_nvp, &val, &nelem); 455 10234 Robert (void) printf(" [ "); 456 10234 Robert for (i = 0; i < nelem; i++) 457 10234 Robert (void) printf("%llu ", val[i]); 458 10234 Robert (void) printf("]"); 459 10234 Robert break; 460 10234 Robert } 461 6640 cth case DATA_TYPE_STRING_ARRAY: { 462 6640 cth char **val; 463 6640 cth 464 6640 cth (void) nvpair_value_string_array(pv_nvp, &val, &nelem); 465 6640 cth (void) printf(" [ "); 466 6640 cth for (i = 0; i < nelem; i++) 467 10234 Robert (void) printf("\"%s\" ", val[i]); 468 3323 cindi (void) printf("]"); 469 3062 cindi break; 470 3062 cindi } 471 3062 cindi default: 472 3062 cindi (void) fprintf(stderr, " unknown data type (%d)", 473 3062 cindi nvpair_type(pv_nvp)); 474 3062 cindi break; 475 3062 cindi } 476 3062 cindi (void) printf("\n"); 477 3062 cindi } 478 3062 cindi 479 3062 cindi static void 480 4087 cindi print_pgroup(topo_hdl_t *thp, tnode_t *node, const char *pgn, char *dstab, 481 4087 cindi char *nstab, int32_t version) 482 3062 cindi { 483 4087 cindi int err; 484 3062 cindi char buf[30]; 485 4087 cindi topo_pgroup_info_t *pgi = NULL; 486 3062 cindi 487 4087 cindi if (pgn == NULL) 488 3062 cindi return; 489 3062 cindi 490 4087 cindi if (node != NULL && (dstab == NULL || nstab == NULL || version == -1)) { 491 4087 cindi if ((pgi = topo_pgroup_info(node, pgn, &err)) != NULL) { 492 4087 cindi dstab = (char *)topo_stability2name(pgi->tpi_datastab); 493 4087 cindi nstab = (char *)topo_stability2name(pgi->tpi_namestab); 494 4087 cindi version = pgi->tpi_version; 495 4087 cindi } 496 4087 cindi } 497 4087 cindi 498 4087 cindi if (dstab == NULL || nstab == NULL || version == -1) { 499 11050 Robert (void) printf(" group: %-30s version: - stability: -/-\n", 500 11050 Robert pgn); 501 4087 cindi } else if (!opt_V && strlen(pgn) > 30) { 502 3062 cindi (void) snprintf(buf, 26, "%s", pgn); 503 3062 cindi (void) snprintf(&buf[27], 4, "%s", DOTS); 504 11050 Robert (void) printf(" group: %-30s version: %-3d stability: %s/%s\n", 505 3062 cindi buf, version, nstab, dstab); 506 3062 cindi } else { 507 11050 Robert (void) printf(" group: %-30s version: %-3d stability: %s/%s\n", 508 3062 cindi pgn, version, nstab, dstab); 509 3062 cindi } 510 3062 cindi 511 4087 cindi if (pgi != NULL) { 512 4087 cindi topo_hdl_strfree(thp, (char *)pgi->tpi_name); 513 4087 cindi topo_hdl_free(thp, pgi, sizeof (topo_pgroup_info_t)); 514 3062 cindi } 515 3062 cindi } 516 3062 cindi 517 3062 cindi static void 518 4087 cindi print_all_props(topo_hdl_t *thp, tnode_t *node, nvlist_t *p_nv, 519 4087 cindi const char *group) 520 3062 cindi { 521 3062 cindi char *pgn = NULL, *dstab = NULL, *nstab = NULL; 522 4087 cindi int32_t version; 523 3062 cindi nvlist_t *pg_nv, *pv_nv; 524 3062 cindi nvpair_t *nvp, *pg_nvp; 525 4087 cindi int pg_done, match, all = strcmp(group, ALL) == 0; 526 3062 cindi 527 3062 cindi for (nvp = nvlist_next_nvpair(p_nv, NULL); nvp != NULL; 528 3062 cindi nvp = nvlist_next_nvpair(p_nv, nvp)) { 529 3062 cindi if (strcmp(TOPO_PROP_GROUP, nvpair_name(nvp)) != 0 || 530 3062 cindi nvpair_type(nvp) != DATA_TYPE_NVLIST) 531 3062 cindi continue; 532 3062 cindi 533 4087 cindi nstab = NULL; 534 4087 cindi dstab = NULL; 535 4087 cindi version = -1; 536 4087 cindi pg_done = match = 0; 537 3062 cindi (void) nvpair_value_nvlist(nvp, &pg_nv); 538 3062 cindi for (pg_nvp = nvlist_next_nvpair(pg_nv, NULL); pg_nvp != NULL; 539 3062 cindi pg_nvp = nvlist_next_nvpair(pg_nv, pg_nvp)) { 540 3062 cindi /* 541 3062 cindi * Print property group name and stability levels 542 3062 cindi */ 543 3062 cindi if (strcmp(TOPO_PROP_GROUP_NAME, nvpair_name(pg_nvp)) 544 3062 cindi == 0 && nvpair_type(pg_nvp) == DATA_TYPE_STRING) { 545 3062 cindi (void) nvpair_value_string(pg_nvp, &pgn); 546 4087 cindi match = strcmp(group, pgn) == 0; 547 4087 cindi continue; 548 4087 cindi } 549 3062 cindi 550 4087 cindi if (strcmp(TOPO_PROP_GROUP_NSTAB, 551 3062 cindi nvpair_name(pg_nvp)) == 0 && 552 3062 cindi nvpair_type(pg_nvp) == DATA_TYPE_STRING) { 553 3062 cindi (void) nvpair_value_string(pg_nvp, &nstab); 554 4087 cindi continue; 555 4087 cindi } 556 4087 cindi 557 4087 cindi if (strcmp(TOPO_PROP_GROUP_DSTAB, 558 3062 cindi nvpair_name(pg_nvp)) == 0 && 559 3062 cindi nvpair_type(pg_nvp) == DATA_TYPE_STRING) { 560 3062 cindi (void) nvpair_value_string(pg_nvp, &dstab); 561 4087 cindi continue; 562 4087 cindi } 563 4087 cindi 564 4087 cindi if (strcmp(TOPO_PROP_GROUP_VERSION, 565 3062 cindi nvpair_name(pg_nvp)) == 0 && 566 3062 cindi nvpair_type(pg_nvp) == DATA_TYPE_INT32) { 567 3062 cindi (void) nvpair_value_int32(pg_nvp, &version); 568 4087 cindi continue; 569 3062 cindi } 570 3062 cindi 571 4087 cindi if ((match || all) && !pg_done) { 572 4087 cindi print_pgroup(thp, node, pgn, dstab, nstab, 573 4087 cindi version); 574 4087 cindi pg_done++; 575 4087 cindi } 576 4087 cindi 577 4087 cindi /* 578 4087 cindi * Print property group and property name-value pair 579 4087 cindi */ 580 4087 cindi if (strcmp(TOPO_PROP_VAL, nvpair_name(pg_nvp)) 581 4087 cindi == 0 && nvpair_type(pg_nvp) == DATA_TYPE_NVLIST) { 582 4087 cindi (void) nvpair_value_nvlist(pg_nvp, &pv_nv); 583 4087 cindi if ((match || all) && pg_done) { 584 7243 robj print_prop_nameval(thp, node, pv_nv); 585 4087 cindi } 586 4087 cindi 587 4087 cindi } 588 4087 cindi 589 4087 cindi } 590 4087 cindi if (match && !all) 591 4087 cindi return; 592 4087 cindi } 593 4087 cindi } 594 4087 cindi 595 4087 cindi static void 596 4087 cindi set_prop(topo_hdl_t *thp, tnode_t *node, nvlist_t *fmri, struct prop_args *pp) 597 4087 cindi { 598 4087 cindi int ret, err = 0; 599 4087 cindi topo_type_t type; 600 4087 cindi nvlist_t *nvl, *f = NULL; 601 4087 cindi char *end; 602 4087 cindi 603 4087 cindi if (pp->prop == NULL || pp->type == NULL || pp->value == NULL) 604 4087 cindi return; 605 4087 cindi 606 4087 cindi if ((type = str2type(pp->type)) == TOPO_TYPE_INVALID) { 607 4087 cindi (void) fprintf(stderr, "%s: invalid property type %s for %s\n", 608 4087 cindi g_pname, pp->type, pp->prop); 609 4087 cindi return; 610 4087 cindi } 611 4087 cindi 612 4087 cindi if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) { 613 4087 cindi (void) fprintf(stderr, "%s: nvlist allocation failed for " 614 4087 cindi "%s=%s:%s\n", g_pname, pp->prop, pp->type, pp->value); 615 4087 cindi return; 616 4087 cindi } 617 4087 cindi ret = nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, pp->prop); 618 4087 cindi ret |= nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, type); 619 4087 cindi if (ret != 0) { 620 4087 cindi (void) fprintf(stderr, "%s: invalid property type %s for %s\n", 621 4087 cindi g_pname, pp->type, pp->prop); 622 4087 cindi nvlist_free(nvl); 623 4087 cindi return; 624 4087 cindi } 625 4087 cindi 626 4087 cindi errno = 0; 627 4087 cindi switch (type) { 628 4087 cindi case TOPO_TYPE_INT32: 629 4087 cindi { 630 4087 cindi int32_t val; 631 4087 cindi 632 4087 cindi val = strtol(pp->value, &end, 0); 633 4087 cindi if (errno == ERANGE) { 634 4087 cindi ret = -1; 635 4087 cindi break; 636 4087 cindi } 637 4087 cindi ret = nvlist_add_int32(nvl, TOPO_PROP_VAL_VAL, val); 638 4087 cindi break; 639 4087 cindi } 640 4087 cindi case TOPO_TYPE_UINT32: 641 4087 cindi { 642 4087 cindi uint32_t val; 643 4087 cindi 644 4087 cindi val = strtoul(pp->value, &end, 0); 645 4087 cindi if (errno == ERANGE) { 646 4087 cindi ret = -1; 647 4087 cindi break; 648 4087 cindi } 649 4087 cindi ret = nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, val); 650 4087 cindi break; 651 4087 cindi } 652 4087 cindi case TOPO_TYPE_INT64: 653 4087 cindi { 654 4087 cindi int64_t val; 655 4087 cindi 656 4087 cindi val = strtoll(pp->value, &end, 0); 657 4087 cindi if (errno == ERANGE) { 658 4087 cindi ret = -1; 659 4087 cindi break; 660 4087 cindi } 661 4087 cindi ret = nvlist_add_int64(nvl, TOPO_PROP_VAL_VAL, val); 662 4087 cindi break; 663 4087 cindi } 664 4087 cindi case TOPO_TYPE_UINT64: 665 4087 cindi { 666 4087 cindi uint64_t val; 667 4087 cindi 668 4087 cindi val = strtoull(pp->value, &end, 0); 669 4087 cindi if (errno == ERANGE) { 670 4087 cindi ret = -1; 671 4087 cindi break; 672 4087 cindi } 673 4087 cindi ret = nvlist_add_uint64(nvl, TOPO_PROP_VAL_VAL, val); 674 4087 cindi break; 675 4087 cindi } 676 4087 cindi case TOPO_TYPE_STRING: 677 4087 cindi { 678 4087 cindi ret = nvlist_add_string(nvl, TOPO_PROP_VAL_VAL, 679 4087 cindi pp->value); 680 4087 cindi break; 681 4087 cindi } 682 4087 cindi case TOPO_TYPE_FMRI: 683 4087 cindi { 684 4087 cindi if ((ret = topo_fmri_str2nvl(thp, pp->value, &f, &err)) 685 4087 cindi < 0) 686 4087 cindi break; 687 4087 cindi 688 4087 cindi if ((ret = nvlist_add_nvlist(nvl, TOPO_PROP_VAL_VAL, 689 4087 cindi f)) != 0) 690 4087 cindi err = ETOPO_PROP_NVL; 691 4087 cindi break; 692 4087 cindi } 693 4087 cindi default: 694 4087 cindi ret = -1; 695 4087 cindi } 696 4087 cindi 697 4087 cindi if (ret != 0) { 698 4087 cindi (void) fprintf(stderr, "%s: unable to set property value for " 699 4087 cindi "%s: %s\n", g_pname, pp->prop, topo_strerror(err)); 700 4087 cindi nvlist_free(nvl); 701 4087 cindi return; 702 4087 cindi } 703 4087 cindi 704 4087 cindi if (node != NULL) { 705 4087 cindi if (topo_prop_setprop(node, pp->group, nvl, TOPO_PROP_MUTABLE, 706 4087 cindi f, &ret) < 0) { 707 4087 cindi (void) fprintf(stderr, "%s: unable to set property " 708 4087 cindi "value for " "%s=%s:%s: %s\n", g_pname, pp->prop, 709 4087 cindi pp->type, pp->value, topo_strerror(ret)); 710 4087 cindi nvlist_free(nvl); 711 4087 cindi nvlist_free(f); 712 4087 cindi return; 713 4087 cindi } 714 4087 cindi } else { 715 4087 cindi if (topo_fmri_setprop(thp, fmri, pp->group, nvl, 716 4087 cindi TOPO_PROP_MUTABLE, f, &ret) < 0) { 717 4087 cindi (void) fprintf(stderr, "%s: unable to set property " 718 4087 cindi "value for " "%s=%s:%s: %s\n", g_pname, pp->prop, 719 4087 cindi pp->type, pp->value, topo_strerror(ret)); 720 4087 cindi nvlist_free(nvl); 721 4087 cindi nvlist_free(f); 722 4087 cindi return; 723 4087 cindi } 724 4087 cindi } 725 4087 cindi 726 4087 cindi nvlist_free(nvl); 727 4087 cindi 728 4087 cindi /* 729 4087 cindi * Now, get the property back for printing 730 4087 cindi */ 731 4087 cindi if (node != NULL) { 732 4087 cindi if (topo_prop_getprop(node, pp->group, pp->prop, f, &nvl, 733 4087 cindi &err) < 0) { 734 4087 cindi (void) fprintf(stderr, "%s: failed to get %s.%s: %s\n", 735 4087 cindi g_pname, pp->group, pp->prop, topo_strerror(err)); 736 4087 cindi nvlist_free(f); 737 4087 cindi return; 738 4087 cindi } 739 4087 cindi } else { 740 4087 cindi if (topo_fmri_getprop(thp, fmri, pp->group, pp->prop, 741 4087 cindi f, &nvl, &err) < 0) { 742 4087 cindi (void) fprintf(stderr, "%s: failed to get %s.%s: %s\n", 743 4087 cindi g_pname, pp->group, pp->prop, topo_strerror(err)); 744 4087 cindi nvlist_free(f); 745 4087 cindi return; 746 4087 cindi } 747 4087 cindi } 748 4087 cindi 749 4087 cindi print_pgroup(thp, node, pp->group, NULL, NULL, 0); 750 7243 robj print_prop_nameval(thp, node, nvl); 751 4087 cindi nvlist_free(nvl); 752 4087 cindi 753 4087 cindi nvlist_free(f); 754 4087 cindi } 755 4087 cindi 756 4087 cindi static void 757 4087 cindi print_props(topo_hdl_t *thp, tnode_t *node) 758 4087 cindi { 759 4087 cindi int i, err; 760 4087 cindi nvlist_t *nvl; 761 4087 cindi struct prop_args *pp; 762 4087 cindi 763 4087 cindi if (pcnt == 0) 764 4087 cindi return; 765 4087 cindi 766 4087 cindi for (i = 0; i < pcnt; ++i) { 767 4087 cindi pp = pargs[i]; 768 4087 cindi 769 4087 cindi if (pp->group == NULL) 770 4087 cindi continue; 771 4087 cindi 772 4087 cindi /* 773 4087 cindi * If we have a valid value, this is a request to 774 4087 cindi * set a property. Otherwise, just print the property 775 4087 cindi * group and any specified properties. 776 4087 cindi */ 777 4087 cindi if (pp->value == NULL) { 778 4087 cindi if (pp->prop == NULL) { 779 4087 cindi 780 4087 cindi /* 781 4087 cindi * Print all properties in this group 782 4087 cindi */ 783 4087 cindi if ((nvl = topo_prop_getprops(node, &err)) 784 4087 cindi == NULL) { 785 4087 cindi (void) fprintf(stderr, "%s: failed to " 786 4087 cindi "get %s: %s\n", g_pname, 787 4087 cindi pp->group, 788 4087 cindi topo_strerror(err)); 789 4087 cindi continue; 790 3062 cindi } else { 791 4087 cindi print_all_props(thp, node, nvl, 792 4087 cindi pp->group); 793 4087 cindi nvlist_free(nvl); 794 3062 cindi continue; 795 3062 cindi } 796 3062 cindi } 797 4087 cindi if (topo_prop_getprop(node, pp->group, pp->prop, 798 4087 cindi NULL, &nvl, &err) < 0) { 799 4087 cindi (void) fprintf(stderr, "%s: failed to get " 800 4087 cindi "%s.%s: %s\n", g_pname, 801 4087 cindi pp->group, pp->prop, 802 4087 cindi topo_strerror(err)); 803 4087 cindi continue; 804 4087 cindi } else { 805 4087 cindi print_pgroup(thp, node, pp->group, NULL, 806 4087 cindi NULL, 0); 807 7243 robj print_prop_nameval(thp, node, nvl); 808 4087 cindi nvlist_free(nvl); 809 4087 cindi } 810 4087 cindi } else { 811 4087 cindi set_prop(thp, node, NULL, pp); 812 3062 cindi } 813 3062 cindi } 814 3062 cindi } 815 3062 cindi 816 1414 cindi /*ARGSUSED*/ 817 1414 cindi static int 818 4087 cindi walk_node(topo_hdl_t *thp, tnode_t *node, void *arg) 819 1414 cindi { 820 3062 cindi int err; 821 3062 cindi nvlist_t *nvl; 822 9501 Robert nvlist_t *rsrc, *out; 823 4087 cindi char *s; 824 3062 cindi 825 3062 cindi if (opt_e && strcmp(opt_s, FM_FMRI_SCHEME_HC) == 0) { 826 1414 cindi print_everstyle(node); 827 3062 cindi return (TOPO_WALK_NEXT); 828 3062 cindi } 829 1414 cindi 830 4087 cindi if (topo_node_resource(node, &rsrc, &err) < 0) { 831 4087 cindi (void) fprintf(stderr, "%s: failed to get resource: " 832 4087 cindi "%s", g_pname, topo_strerror(err)); 833 4087 cindi return (TOPO_WALK_NEXT); 834 4087 cindi } 835 4087 cindi if (topo_fmri_nvl2str(thp, rsrc, &s, &err) < 0) { 836 4087 cindi (void) fprintf(stderr, "%s: failed to convert " 837 4087 cindi "resource to FMRI string: %s", g_pname, 838 4087 cindi topo_strerror(err)); 839 4087 cindi nvlist_free(rsrc); 840 4087 cindi return (TOPO_WALK_NEXT); 841 4087 cindi } 842 1414 cindi 843 4087 cindi if (g_fmri != NULL && fnmatch(g_fmri, s, 0) != 0) { 844 9501 Robert nvlist_free(rsrc); 845 9501 Robert topo_hdl_strfree(thp, s); 846 9501 Robert return (TOPO_WALK_NEXT); 847 4087 cindi } 848 4087 cindi 849 4087 cindi print_node(thp, node, rsrc, s); 850 4087 cindi topo_hdl_strfree(thp, s); 851 4087 cindi nvlist_free(rsrc); 852 9501 Robert 853 9501 Robert if (opt_m != NULL) { 854 9501 Robert if (topo_method_invoke(node, opt_m, 0, NULL, &out, &err) == 0) { 855 9501 Robert nvlist_print(stdout, out); 856 9501 Robert nvlist_free(out); 857 9501 Robert } else if (err != ETOPO_METHOD_NOTSUP) 858 9501 Robert (void) fprintf(stderr, "%s: method failed unexpectedly " 859 9501 Robert "on %s=%d (%s)\n", g_pname, topo_node_name(node), 860 9501 Robert topo_node_instance(node), topo_strerror(err)); 861 9501 Robert } 862 7243 robj 863 4087 cindi if (opt_V || opt_all) { 864 3062 cindi if ((nvl = topo_prop_getprops(node, &err)) == NULL) { 865 3062 cindi (void) fprintf(stderr, "%s: failed to get " 866 3062 cindi "properties for %s=%d: %s\n", g_pname, 867 3062 cindi topo_node_name(node), topo_node_instance(node), 868 3062 cindi topo_strerror(err)); 869 1414 cindi } else { 870 4087 cindi print_all_props(thp, node, nvl, ALL); 871 1414 cindi nvlist_free(nvl); 872 1414 cindi } 873 7243 robj } else if (pcnt > 0) 874 4087 cindi print_props(thp, node); 875 3062 cindi 876 11050 Robert (void) printf("\n"); 877 1414 cindi 878 1414 cindi return (TOPO_WALK_NEXT); 879 1414 cindi } 880 1414 cindi 881 4087 cindi static void 882 4087 cindi get_pargs(int argc, char *argv[]) 883 1414 cindi { 884 4087 cindi struct prop_args *pp; 885 4087 cindi char c, *s, *p; 886 4087 cindi int i = 0; 887 1414 cindi 888 4087 cindi if ((pargs = malloc(sizeof (struct prop_args *) * pcnt)) == NULL) { 889 4087 cindi (void) fprintf(stderr, "%s: failed to allocate property " 890 4087 cindi "arguments\n", g_pname); 891 4087 cindi return; 892 4087 cindi } 893 1414 cindi 894 4087 cindi for (optind = 1; (c = getopt(argc, argv, optstr)) != EOF; ) { 895 4087 cindi if (c == 'P') { 896 4087 cindi 897 4087 cindi if (strcmp(optarg, ALL) == 0) { 898 4087 cindi opt_all++; 899 1414 cindi break; 900 4087 cindi } 901 4087 cindi 902 4087 cindi if ((pp = pargs[i] = malloc(sizeof (struct prop_args))) 903 4087 cindi == NULL) { 904 4087 cindi (void) fprintf(stderr, "%s: failed to " 905 4087 cindi "allocate propertyarguments\n", g_pname); 906 4087 cindi return; 907 4087 cindi } 908 4087 cindi ++i; 909 4087 cindi pp->group = NULL; 910 4087 cindi pp->prop = NULL; 911 4087 cindi pp->type = NULL; 912 4087 cindi pp->value = NULL; 913 4087 cindi 914 4087 cindi p = optarg; 915 4087 cindi if ((s = strchr(p, '.')) != NULL) { 916 4087 cindi *s++ = '\0'; /* strike out delimiter */ 917 4087 cindi pp->group = p; 918 4087 cindi p = s; 919 4087 cindi if ((s = strchr(p, '=')) != NULL) { 920 4087 cindi *s++ = '\0'; /* strike out delimiter */ 921 4087 cindi pp->prop = p; 922 4087 cindi p = s; 923 4087 cindi if ((s = strchr(p, ':')) != NULL) { 924 4087 cindi *s++ = '\0'; 925 4087 cindi pp->type = p; 926 4087 cindi pp->value = s; 927 4087 cindi } else { 928 4087 cindi (void) fprintf(stderr, "%s: " 929 4087 cindi "property type not " 930 4087 cindi "specified for assignment " 931 4087 cindi " of %s.%s\n", g_pname, 932 4087 cindi pp->group, pp->prop); 933 4087 cindi break; 934 4087 cindi } 935 4087 cindi } else { 936 4087 cindi pp->prop = p; 937 4087 cindi } 938 4087 cindi } else { 939 4087 cindi pp->group = p; 940 4087 cindi } 941 4087 cindi if (i >= pcnt) 942 1414 cindi break; 943 1414 cindi } 944 1414 cindi } 945 1414 cindi 946 4087 cindi if (opt_all > 0) { 947 4087 cindi int j; 948 4087 cindi 949 4087 cindi for (j = 0; j < i; ++j) 950 4087 cindi free(pargs[i]); 951 4087 cindi free(pargs); 952 4087 cindi pargs = NULL; 953 1414 cindi } 954 4087 cindi } 955 1414 cindi 956 4087 cindi static int 957 4087 cindi walk_topo(topo_hdl_t *thp, char *uuid) 958 4087 cindi { 959 4087 cindi int err; 960 4087 cindi topo_walk_t *twp; 961 6341 cy152378 int flag; 962 1414 cindi 963 4087 cindi if ((twp = topo_walk_init(thp, opt_s, walk_node, NULL, &err)) 964 1414 cindi == NULL) { 965 1414 cindi (void) fprintf(stderr, "%s: failed to walk %s topology:" 966 1414 cindi " %s\n", g_pname, opt_s, topo_strerror(err)); 967 1414 cindi 968 4087 cindi return (-1); 969 1414 cindi } 970 1414 cindi 971 3062 cindi /* 972 3062 cindi * Print standard header 973 3062 cindi */ 974 3062 cindi if (!opt_e) { 975 3062 cindi char buf[32]; 976 3062 cindi time_t tod = time(NULL); 977 3062 cindi 978 11050 Robert (void) printf("TIME UUID\n"); 979 3062 cindi (void) strftime(buf, sizeof (buf), "%b %d %T", localtime(&tod)); 980 3062 cindi (void) printf("%-15s %-32s\n", buf, uuid); 981 3062 cindi (void) printf("\n"); 982 3062 cindi } 983 1414 cindi 984 6341 cy152378 flag = opt_b != 0 ? TOPO_WALK_SIBLING : TOPO_WALK_CHILD; 985 6341 cy152378 986 6341 cy152378 if (topo_walk_step(twp, flag) == TOPO_WALK_ERR) { 987 1414 cindi (void) fprintf(stderr, "%s: failed to walk topology\n", 988 1414 cindi g_pname); 989 2027 sethg topo_walk_fini(twp); 990 4087 cindi return (-1); 991 1414 cindi } 992 1414 cindi 993 1414 cindi topo_walk_fini(twp); 994 4087 cindi 995 4087 cindi return (0); 996 4087 cindi } 997 4087 cindi 998 4087 cindi static void 999 4087 cindi print_fmri_pgroup(topo_hdl_t *thp, const char *pgn, nvlist_t *nvl) 1000 4087 cindi { 1001 4087 cindi char *dstab = NULL, *nstab = NULL; 1002 4087 cindi int32_t version = -1; 1003 4087 cindi nvlist_t *pnvl; 1004 4087 cindi nvpair_t *pnvp; 1005 4087 cindi 1006 4087 cindi (void) nvlist_lookup_string(nvl, TOPO_PROP_GROUP_NSTAB, &nstab); 1007 4087 cindi (void) nvlist_lookup_string(nvl, TOPO_PROP_GROUP_DSTAB, &dstab); 1008 4087 cindi (void) nvlist_lookup_int32(nvl, TOPO_PROP_GROUP_VERSION, &version); 1009 4087 cindi 1010 4087 cindi print_pgroup(thp, NULL, pgn, dstab, nstab, version); 1011 4087 cindi 1012 4087 cindi for (pnvp = nvlist_next_nvpair(nvl, NULL); pnvp != NULL; 1013 4087 cindi pnvp = nvlist_next_nvpair(nvl, pnvp)) { 1014 4087 cindi 1015 4087 cindi /* 1016 4087 cindi * Print property group and property name-value pair 1017 4087 cindi */ 1018 4087 cindi if (strcmp(TOPO_PROP_VAL, nvpair_name(pnvp)) 1019 4087 cindi == 0 && nvpair_type(pnvp) == DATA_TYPE_NVLIST) { 1020 4087 cindi (void) nvpair_value_nvlist(pnvp, &pnvl); 1021 7243 robj print_prop_nameval(thp, NULL, pnvl); 1022 4087 cindi 1023 4087 cindi } 1024 4087 cindi 1025 4087 cindi } 1026 4087 cindi } 1027 4087 cindi 1028 4087 cindi static void 1029 4087 cindi print_fmri_props(topo_hdl_t *thp, nvlist_t *nvl) 1030 4087 cindi { 1031 4087 cindi int i, err; 1032 4087 cindi struct prop_args *pp; 1033 4087 cindi nvlist_t *pnvl; 1034 4087 cindi 1035 4087 cindi for (i = 0; i < pcnt; ++i) { 1036 4087 cindi pp = pargs[i]; 1037 4087 cindi 1038 4087 cindi if (pp->group == NULL) 1039 4087 cindi continue; 1040 4087 cindi 1041 4087 cindi pnvl = NULL; 1042 4087 cindi 1043 4087 cindi /* 1044 4087 cindi * If we have a valid value, this is a request to 1045 4087 cindi * set a property. Otherwise, just print the property 1046 4087 cindi * group and any specified properties. 1047 4087 cindi */ 1048 4087 cindi if (pp->value == NULL) { 1049 4087 cindi if (pp->prop == NULL) { 1050 4087 cindi 1051 4087 cindi /* 1052 4087 cindi * Print all properties in this group 1053 4087 cindi */ 1054 4087 cindi if (topo_fmri_getpgrp(thp, nvl, pp->group, 1055 4087 cindi &pnvl, &err) < 0) { 1056 4087 cindi (void) fprintf(stderr, "%s: failed to " 1057 4087 cindi "get group %s: %s\n", g_pname, 1058 4087 cindi pp->group, topo_strerror(err)); 1059 4087 cindi continue; 1060 4087 cindi } else { 1061 7243 robj print_fmri_pgroup(thp, pp->group, 1062 7243 robj pnvl); 1063 4087 cindi nvlist_free(pnvl); 1064 4087 cindi continue; 1065 4087 cindi } 1066 4087 cindi } 1067 4087 cindi if (topo_fmri_getprop(thp, nvl, pp->group, pp->prop, 1068 4087 cindi NULL, &pnvl, &err) < 0) { 1069 4087 cindi (void) fprintf(stderr, "%s: failed to get " 1070 4087 cindi "%s.%s: %s\n", g_pname, 1071 4087 cindi pp->group, pp->prop, 1072 4087 cindi topo_strerror(err)); 1073 4087 cindi continue; 1074 4087 cindi } else { 1075 4087 cindi print_fmri_pgroup(thp, pp->group, pnvl); 1076 7243 robj print_prop_nameval(thp, NULL, pnvl); 1077 4087 cindi nvlist_free(nvl); 1078 4087 cindi } 1079 4087 cindi } else { 1080 4087 cindi set_prop(thp, NULL, nvl, pp); 1081 4087 cindi } 1082 4087 cindi } 1083 4087 cindi } 1084 4087 cindi 1085 4087 cindi void 1086 4087 cindi print_fmri(topo_hdl_t *thp, char *uuid) 1087 4087 cindi { 1088 4087 cindi int ret, err; 1089 4087 cindi nvlist_t *nvl; 1090 4087 cindi char buf[32]; 1091 4087 cindi time_t tod = time(NULL); 1092 4087 cindi 1093 4087 cindi if (topo_fmri_str2nvl(thp, g_fmri, &nvl, &err) < 0) { 1094 4087 cindi (void) fprintf(stderr, "%s: failed to convert %s to nvlist: " 1095 4087 cindi "%s\n", g_pname, g_fmri, topo_strerror(err)); 1096 4087 cindi return; 1097 4087 cindi } 1098 4087 cindi 1099 11050 Robert (void) printf("TIME UUID\n"); 1100 4087 cindi (void) strftime(buf, sizeof (buf), "%b %d %T", localtime(&tod)); 1101 4087 cindi (void) printf("%-15s %-32s\n", buf, uuid); 1102 4087 cindi (void) printf("\n"); 1103 4087 cindi 1104 4087 cindi (void) printf("%s\n", (char *)g_fmri); 1105 4087 cindi 1106 4087 cindi if (opt_p && !(pcnt > 0 || opt_V || opt_all)) { 1107 4087 cindi char *aname = NULL, *fname = NULL, *lname = NULL; 1108 4087 cindi nvlist_t *asru = NULL; 1109 4087 cindi nvlist_t *fru = NULL; 1110 4087 cindi 1111 4087 cindi if (topo_fmri_asru(thp, nvl, &asru, &err) == 0) 1112 4328 cindi (void) topo_fmri_nvl2str(thp, asru, &aname, &err); 1113 4087 cindi if (topo_fmri_fru(thp, nvl, &fru, &err) == 0) 1114 4328 cindi (void) topo_fmri_nvl2str(thp, fru, &fname, &err); 1115 4087 cindi (void) topo_fmri_label(thp, nvl, &lname, &err); 1116 4087 cindi 1117 4087 cindi nvlist_free(fru); 1118 4087 cindi nvlist_free(asru); 1119 4087 cindi 1120 4087 cindi if (aname != NULL) { 1121 4087 cindi (void) printf("\tASRU: %s\n", aname); 1122 4087 cindi topo_hdl_strfree(thp, aname); 1123 4087 cindi } else { 1124 4087 cindi (void) printf("\tASRU: -\n"); 1125 4087 cindi } 1126 4087 cindi if (fname != NULL) { 1127 4087 cindi (void) printf("\tFRU: %s\n", fname); 1128 4087 cindi topo_hdl_strfree(thp, fname); 1129 4087 cindi } else { 1130 4087 cindi (void) printf("\tFRU: -\n"); 1131 4087 cindi } 1132 4087 cindi if (lname != NULL) { 1133 4087 cindi (void) printf("\tLabel: %s\n", lname); 1134 4087 cindi topo_hdl_strfree(thp, lname); 1135 4087 cindi } else { 1136 4087 cindi (void) printf("\tLabel: -\n"); 1137 4087 cindi } 1138 4087 cindi } 1139 4087 cindi 1140 4087 cindi if (opt_S) { 1141 4087 cindi if (topo_fmri_str2nvl(thp, g_fmri, &nvl, &err) < 0) { 1142 4087 cindi (void) printf("\tPresent: -\n"); 1143 4087 cindi (void) printf("\tUnusable: -\n"); 1144 4087 cindi return; 1145 4087 cindi } 1146 4087 cindi 1147 4087 cindi if ((ret = topo_fmri_present(thp, nvl, &err)) < 0) 1148 4087 cindi (void) printf("\tPresent: -\n"); 1149 4087 cindi else 1150 4087 cindi (void) printf("\tPresent: %s\n", 1151 4087 cindi ret ? "true" : "false"); 1152 4087 cindi 1153 4087 cindi if ((ret = topo_fmri_unusable(thp, nvl, &err)) < 0) 1154 4087 cindi (void) printf("\tUnusable: -\n"); 1155 4087 cindi else 1156 4087 cindi (void) printf("\tUnusable: %s\n", 1157 4087 cindi ret ? "true" : "false"); 1158 4087 cindi 1159 4087 cindi nvlist_free(nvl); 1160 4087 cindi } 1161 4087 cindi 1162 5068 robj if (pargs && pcnt > 0) 1163 4087 cindi print_fmri_props(thp, nvl); 1164 4087 cindi } 1165 4087 cindi 1166 4087 cindi int 1167 4087 cindi fmtopo_exit(topo_hdl_t *thp, char *uuid, int err) 1168 4087 cindi { 1169 4087 cindi if (uuid != NULL) 1170 4087 cindi topo_hdl_strfree(thp, uuid); 1171 4087 cindi 1172 4087 cindi if (thp != NULL) { 1173 4087 cindi topo_snap_release(thp); 1174 4087 cindi topo_close(thp); 1175 4087 cindi } 1176 4087 cindi 1177 4087 cindi if (pargs) { 1178 4087 cindi int i; 1179 4087 cindi for (i = 0; i < pcnt; ++i) 1180 4087 cindi free(pargs[i]); 1181 4087 cindi free(pargs); 1182 4087 cindi } 1183 4087 cindi 1184 4087 cindi return (err); 1185 4087 cindi } 1186 4087 cindi 1187 4087 cindi int 1188 4087 cindi main(int argc, char *argv[]) 1189 4087 cindi { 1190 4087 cindi topo_hdl_t *thp = NULL; 1191 4087 cindi char *uuid = NULL; 1192 4087 cindi int c, err = 0; 1193 4087 cindi 1194 4087 cindi g_pname = argv[0]; 1195 4087 cindi 1196 4087 cindi while (optind < argc) { 1197 4087 cindi while ((c = getopt(argc, argv, optstr)) != -1) { 1198 4087 cindi switch (c) { 1199 6341 cy152378 case 'b': 1200 6341 cy152378 opt_b++; 1201 6341 cy152378 break; 1202 4087 cindi case 'C': 1203 11050 Robert (void) atexit(abort); 1204 4087 cindi break; 1205 4087 cindi case 'd': 1206 4087 cindi opt_d++; 1207 4087 cindi break; 1208 4087 cindi case 'e': 1209 4087 cindi opt_e++; 1210 4087 cindi break; 1211 9501 Robert case 'm': 1212 9501 Robert opt_m = optarg; 1213 9501 Robert break; 1214 4087 cindi case 'P': 1215 4087 cindi pcnt++; 1216 4087 cindi break; 1217 4087 cindi case 'p': 1218 4087 cindi opt_p++; 1219 4087 cindi break; 1220 4087 cindi case 'V': 1221 4087 cindi opt_V++; 1222 4087 cindi break; 1223 4087 cindi case 'R': 1224 4087 cindi opt_R = optarg; 1225 4087 cindi break; 1226 4087 cindi case 's': 1227 4087 cindi opt_s = optarg; 1228 4087 cindi break; 1229 4087 cindi case 'S': 1230 4087 cindi opt_S++; 1231 4087 cindi break; 1232 4087 cindi case 't': 1233 4087 cindi opt_t++; 1234 4087 cindi break; 1235 4087 cindi case 'x': 1236 4087 cindi opt_x++; 1237 4087 cindi break; 1238 4087 cindi default: 1239 4087 cindi return (usage(stderr)); 1240 4087 cindi } 1241 4087 cindi } 1242 4087 cindi 1243 4087 cindi if (optind < argc) { 1244 4087 cindi if (g_fmri != NULL) { 1245 4087 cindi (void) fprintf(stderr, "%s: illegal argument " 1246 4087 cindi "-- %s\n", g_pname, argv[optind]); 1247 4087 cindi return (FMTOPO_EXIT_USAGE); 1248 4087 cindi } else { 1249 4087 cindi g_fmri = argv[optind++]; 1250 4087 cindi } 1251 4087 cindi } 1252 4087 cindi } 1253 4087 cindi 1254 4087 cindi if (pcnt > 0) 1255 4087 cindi get_pargs(argc, argv); 1256 4087 cindi 1257 4087 cindi if ((thp = topo_open(TOPO_VERSION, opt_R, &err)) == NULL) { 1258 4087 cindi (void) fprintf(stderr, "%s: failed to open topology tree: %s\n", 1259 4087 cindi g_pname, topo_strerror(err)); 1260 4087 cindi return (fmtopo_exit(thp, uuid, FMTOPO_EXIT_ERROR)); 1261 4087 cindi } 1262 4087 cindi 1263 4087 cindi if (opt_d) 1264 4087 cindi topo_debug_set(thp, "module", "stderr"); 1265 4087 cindi 1266 4087 cindi if ((uuid = topo_snap_hold(thp, NULL, &err)) == NULL) { 1267 4087 cindi (void) fprintf(stderr, "%s: failed to snapshot topology: %s\n", 1268 4087 cindi g_pname, topo_strerror(err)); 1269 4087 cindi return (fmtopo_exit(thp, uuid, FMTOPO_EXIT_ERROR)); 1270 4087 cindi } else if (err != 0) { 1271 4087 cindi (void) fprintf(stderr, "%s: topology snapshot incomplete\n", 1272 4087 cindi g_pname); 1273 4087 cindi } 1274 4087 cindi 1275 6341 cy152378 if (opt_x) { 1276 6341 cy152378 if (opt_b) { 1277 6341 cy152378 (void) fprintf(stderr, 1278 6341 cy152378 "%s: -b and -x cannot be specified together\n", 1279 6341 cy152378 g_pname); 1280 6341 cy152378 return (fmtopo_exit(thp, uuid, FMTOPO_EXIT_USAGE)); 1281 6341 cy152378 } 1282 4087 cindi 1283 4087 cindi err = 0; 1284 4087 cindi if (topo_xml_print(thp, stdout, opt_s, &err) < 0) 1285 4087 cindi (void) fprintf(stderr, "%s: failed to print xml " 1286 4087 cindi "formatted topology:%s", g_pname, 1287 4087 cindi topo_strerror(err)); 1288 4087 cindi 1289 4087 cindi return (fmtopo_exit(thp, uuid, err ? FMTOPO_EXIT_ERROR : 1290 4087 cindi FMTOPO_EXIT_SUCCESS)); 1291 4087 cindi } 1292 4087 cindi 1293 4087 cindi if (opt_t || walk_topo(thp, uuid) < 0) { 1294 4087 cindi if (g_fmri != NULL) 1295 4087 cindi /* 1296 4087 cindi * Try getting some useful information 1297 4087 cindi */ 1298 4087 cindi print_fmri(thp, uuid); 1299 4087 cindi 1300 4087 cindi return (fmtopo_exit(thp, uuid, FMTOPO_EXIT_ERROR)); 1301 4087 cindi } 1302 4087 cindi 1303 4328 cindi return (fmtopo_exit(thp, uuid, FMTOPO_EXIT_SUCCESS)); 1304 0 stevel } 1305