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