4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
28 #include <sys/fm/protocol.h>
29 #include <fm/libtopo.h>
38 #include <sys/param.h>
40 #define FMTOPO_EXIT_SUCCESS 0
41 #define FMTOPO_EXIT_ERROR 1
42 #define FMTOPO_EXIT_USAGE 2
44 #define STDERR "stderr"
48 static const char *g_pname
;
49 static const char *g_fmri
= NULL
;
51 static const char *opt_R
= "/";
52 static const char *opt_s
= FM_FMRI_SCHEME_HC
;
53 static const char optstr
[] = "bCdem:P:pR:s:StVx";
54 static const char *opt_m
;
64 static int opt_all
= 0;
73 static struct prop_args
**pargs
= NULL
;
80 "Usage: %s [-bCedpSVx] [-P group.property[=type:value]] "
81 "[-R root] [-m method] [-s scheme] [fmri]\n", g_pname
);
84 "\t-b walk in sibling-first order (default is child-first)\n"
85 "\t-C dump core after completing execution\n"
86 "\t-d set debug mode for libtopo modules\n"
87 "\t-e display FMRIs as paths using esc/eft notation\n"
88 "\t-m execute given method\n"
89 "\t-P get/set specified properties\n"
90 "\t-p display of FMRI protocol properties\n"
91 "\t-R set root directory for libtopo plug-ins and other files\n"
92 "\t-s display topology for the specified FMRI scheme\n"
93 "\t-S display FMRI status (present/usable)\n"
94 "\t-V set verbose mode\n"
95 "\t-x display a xml formatted topology\n");
97 return (FMTOPO_EXIT_USAGE
);
101 str2type(const char *tstr
)
106 return (TOPO_TYPE_INVALID
);
108 if (strcmp(tstr
, "int32") == 0)
109 type
= TOPO_TYPE_INT32
;
110 else if (strcmp(tstr
, "uint32") == 0)
111 type
= TOPO_TYPE_UINT32
;
112 else if (strcmp(tstr
, "int64") == 0)
113 type
= TOPO_TYPE_INT64
;
114 else if (strcmp(tstr
, "uint64") == 0)
115 type
= TOPO_TYPE_UINT64
;
116 else if (strcmp(tstr
, "string") == 0)
117 type
= TOPO_TYPE_STRING
;
118 else if (strcmp(tstr
, "fmri") == 0)
119 type
= TOPO_TYPE_FMRI
;
121 type
= TOPO_TYPE_INVALID
;
128 print_node(topo_hdl_t
*thp
, tnode_t
*node
, nvlist_t
*nvl
, const char *fmri
)
132 (void) printf("%s\n", (char *)fmri
);
134 if (opt_p
&& !(pcnt
> 0 || opt_V
|| opt_all
)) {
135 char *aname
= NULL
, *fname
= NULL
, *lname
= NULL
;
136 nvlist_t
*asru
= NULL
;
137 nvlist_t
*fru
= NULL
;
139 if (topo_node_asru(node
, &asru
, NULL
, &err
) == 0)
140 (void) topo_fmri_nvl2str(thp
, asru
, &aname
, &err
);
141 if (topo_node_fru(node
, &fru
, NULL
, &err
) == 0)
142 (void) topo_fmri_nvl2str(thp
, fru
, &fname
, &err
);
143 (void) topo_node_label(node
, &lname
, &err
);
146 (void) printf("\tASRU: %s\n", aname
);
147 topo_hdl_strfree(thp
, aname
);
149 (void) printf("\tASRU: -\n");
153 (void) printf("\tFRU: %s\n", fname
);
154 topo_hdl_strfree(thp
, fname
);
156 (void) printf("\tFRU: -\n");
159 (void) printf("\tLabel: %s\n", lname
);
160 topo_hdl_strfree(thp
, lname
);
162 (void) printf("\tLabel: -\n");
167 if ((ret
= topo_fmri_present(thp
, nvl
, &err
)) < 0)
168 (void) printf("\tPresent: -\n");
170 (void) printf("\tPresent: %s\n",
171 ret
? "true" : "false");
173 if ((ret
= topo_fmri_unusable(thp
, nvl
, &err
)) < 0)
174 (void) printf("\tUnusable: -\n");
176 (void) printf("\tUnusable: %s\n",
177 ret
? "true" : "false");
182 print_everstyle(tnode_t
*node
)
184 char buf
[PATH_MAX
], numbuf
[64];
185 nvlist_t
*fmri
, **hcl
;
189 if (topo_prop_get_fmri(node
, TOPO_PGROUP_PROTOCOL
,
190 TOPO_PROP_RESOURCE
, &fmri
, &err
) < 0) {
191 (void) fprintf(stderr
, "%s: failed to get fmri for %s=%d: %s\n",
192 g_pname
, topo_node_name(node
),
193 topo_node_instance(node
), topo_strerror(err
));
197 if (nvlist_lookup_nvlist_array(fmri
, FM_FMRI_HC_LIST
, &hcl
, &n
) != 0) {
198 (void) fprintf(stderr
, "%s: failed to find %s for %s=%d\n",
199 g_pname
, FM_FMRI_HC_LIST
, topo_node_name(node
),
200 topo_node_instance(node
));
207 for (i
= 0; i
< n
; i
++) {
208 char *name
, *inst
, *estr
;
211 if (nvlist_lookup_string(hcl
[i
], FM_FMRI_HC_NAME
, &name
) != 0 ||
212 nvlist_lookup_string(hcl
[i
], FM_FMRI_HC_ID
, &inst
) != 0) {
213 (void) fprintf(stderr
, "%s: failed to get "
214 "name-instance for %s=%d\n", g_pname
,
215 topo_node_name(node
), topo_node_instance(node
));
221 ul
= strtoul(inst
, &estr
, 10);
223 if (errno
!= 0 || estr
== inst
) {
224 (void) fprintf(stderr
, "%s: instance %s does not "
225 "convert to an unsigned integer\n", g_pname
, inst
);
228 (void) strlcat(buf
, "/", sizeof (buf
));
229 (void) strlcat(buf
, name
, sizeof (buf
));
230 (void) snprintf(numbuf
, sizeof (numbuf
), "%u", ul
);
231 (void) strlcat(buf
, numbuf
, sizeof (buf
));
235 (void) printf("%s\n", buf
);
239 print_prop_nameval(topo_hdl_t
*thp
, tnode_t
*node
, nvlist_t
*nvl
)
243 char *tstr
, *propn
, buf
[48], *factype
;
248 if ((pv_nvp
= nvlist_next_nvpair(nvl
, NULL
)) == NULL
)
251 /* Print property name */
252 if ((pv_nvp
= nvlist_next_nvpair(nvl
, NULL
)) == NULL
||
253 nvpair_name(pv_nvp
) == NULL
||
254 strcmp(TOPO_PROP_VAL_NAME
, nvpair_name(pv_nvp
)) != 0) {
255 (void) fprintf(stderr
, "%s: malformed property name\n",
259 (void) nvpair_value_string(pv_nvp
, &propn
);
262 if ((pv_nvp
= nvlist_next_nvpair(nvl
, pv_nvp
)) == NULL
||
263 nvpair_name(pv_nvp
) == NULL
||
264 strcmp(nvpair_name(pv_nvp
), TOPO_PROP_VAL_TYPE
) != 0 ||
265 nvpair_type(pv_nvp
) != DATA_TYPE_UINT32
) {
266 (void) fprintf(stderr
, "%s: malformed property type for %s\n",
270 (void) nvpair_value_uint32(pv_nvp
, (uint32_t *)&type
);
274 case TOPO_TYPE_BOOLEAN
: tstr
= "boolean"; break;
275 case TOPO_TYPE_INT32
: tstr
= "int32"; break;
276 case TOPO_TYPE_UINT32
: tstr
= "uint32"; break;
277 case TOPO_TYPE_INT64
: tstr
= "int64"; break;
278 case TOPO_TYPE_UINT64
: tstr
= "uint64"; break;
279 case TOPO_TYPE_DOUBLE
: tstr
= "double"; break;
280 case TOPO_TYPE_STRING
: tstr
= "string"; break;
281 case TOPO_TYPE_FMRI
: tstr
= "fmri"; break;
282 case TOPO_TYPE_INT32_ARRAY
: tstr
= "int32[]"; break;
283 case TOPO_TYPE_UINT32_ARRAY
: tstr
= "uint32[]"; break;
284 case TOPO_TYPE_INT64_ARRAY
: tstr
= "int64[]"; break;
285 case TOPO_TYPE_UINT64_ARRAY
: tstr
= "uint64[]"; break;
286 case TOPO_TYPE_STRING_ARRAY
: tstr
= "string[]"; break;
287 case TOPO_TYPE_FMRI_ARRAY
: tstr
= "fmri[]"; break;
288 default: tstr
= "unknown type";
291 (void) printf(" %-17s %-8s ", propn
, tstr
);
296 if (nvpair_name(pv_nvp
) == NULL
||
297 (pv_nvp
= nvlist_next_nvpair(nvl
, pv_nvp
)) == NULL
) {
298 (void) fprintf(stderr
, "%s: malformed property value\n",
303 switch (nvpair_type(pv_nvp
)) {
304 case DATA_TYPE_INT32
: {
306 (void) nvpair_value_int32(pv_nvp
, &val
);
307 (void) printf(" %d", val
);
310 case DATA_TYPE_UINT32
: {
313 nvlist_t
*fac
, *rsrc
= NULL
;
315 (void) nvpair_value_uint32(pv_nvp
, &val
);
316 if (node
== NULL
|| topo_node_flags(node
) !=
320 if (topo_node_resource(node
, &rsrc
, &err
) != 0)
323 if (nvlist_lookup_nvlist(rsrc
, "facility", &fac
) != 0)
326 if (nvlist_lookup_string(fac
, FM_FMRI_FACILITY_TYPE
,
334 * Special case code to do friendlier printing of
335 * facility node properties
337 if ((strcmp(propn
, TOPO_FACILITY_TYPE
) == 0) &&
338 (strcmp(factype
, TOPO_FAC_TYPE_SENSOR
) == 0)) {
339 topo_sensor_type_name(val
, val_str
, 48);
340 (void) printf(" 0x%x (%s)", val
, val_str
);
342 } else if ((strcmp(propn
, TOPO_FACILITY_TYPE
) == 0) &&
343 (strcmp(factype
, TOPO_FAC_TYPE_INDICATOR
) == 0)) {
344 topo_led_type_name(val
, val_str
, 48);
345 (void) printf(" 0x%x (%s)", val
, val_str
);
347 } else if (strcmp(propn
, TOPO_SENSOR_UNITS
) == 0) {
348 topo_sensor_units_name(val
, val_str
, 48);
349 (void) printf(" 0x%x (%s)", val
, val_str
);
351 } else if (strcmp(propn
, TOPO_LED_MODE
) == 0) {
352 topo_led_state_name(val
, val_str
, 48);
353 (void) printf(" 0x%x (%s)", val
, val_str
);
355 } else if ((strcmp(propn
, TOPO_SENSOR_STATE
) == 0) &&
356 (strcmp(factype
, TOPO_FAC_TYPE_SENSOR
) == 0)) {
357 if (topo_prop_get_uint32(node
,
358 TOPO_PGROUP_FACILITY
, TOPO_FACILITY_TYPE
,
362 topo_sensor_state_name(type
, val
, val_str
, 48);
363 (void) printf(" 0x%x (%s)", val
, val_str
);
367 (void) printf(" 0x%x", val
);
371 case DATA_TYPE_INT64
: {
373 (void) nvpair_value_int64(pv_nvp
, &val
);
374 (void) printf(" %lld", (longlong_t
)val
);
377 case DATA_TYPE_UINT64
: {
379 (void) nvpair_value_uint64(pv_nvp
, &val
);
380 (void) printf(" 0x%llx", (u_longlong_t
)val
);
383 case DATA_TYPE_DOUBLE
: {
385 (void) nvpair_value_double(pv_nvp
, &val
);
386 (void) printf(" %lf", (double)val
);
389 case DATA_TYPE_STRING
: {
391 (void) nvpair_value_string(pv_nvp
, &val
);
392 if (!opt_V
&& strlen(val
) > 48) {
393 (void) snprintf(buf
, 48, "%s...", val
);
394 (void) printf(" %s", buf
);
396 (void) printf(" %s", val
);
400 case DATA_TYPE_NVLIST
: {
403 (void) nvpair_value_nvlist(pv_nvp
, &val
);
404 if (topo_fmri_nvl2str(thp
, val
, &fmri
, &err
) != 0) {
406 nvlist_print(stdout
, nvl
);
410 if (!opt_V
&& strlen(fmri
) > 48) {
411 (void) snprintf(buf
, 48, "%s", fmri
);
412 (void) snprintf(&buf
[45], 4, "%s", DOTS
);
413 (void) printf(" %s", buf
);
415 (void) printf(" %s", fmri
);
418 topo_hdl_strfree(thp
, fmri
);
421 case DATA_TYPE_INT32_ARRAY
: {
424 (void) nvpair_value_int32_array(pv_nvp
, &val
, &nelem
);
425 (void) printf(" [ ");
426 for (i
= 0; i
< nelem
; i
++)
427 (void) printf("%d ", val
[i
]);
431 case DATA_TYPE_UINT32_ARRAY
: {
434 (void) nvpair_value_uint32_array(pv_nvp
, &val
, &nelem
);
435 (void) printf(" [ ");
436 for (i
= 0; i
< nelem
; i
++)
437 (void) printf("%u ", val
[i
]);
441 case DATA_TYPE_INT64_ARRAY
: {
444 (void) nvpair_value_int64_array(pv_nvp
, &val
, &nelem
);
445 (void) printf(" [ ");
446 for (i
= 0; i
< nelem
; i
++)
447 (void) printf("%lld ", val
[i
]);
451 case DATA_TYPE_UINT64_ARRAY
: {
454 (void) nvpair_value_uint64_array(pv_nvp
, &val
, &nelem
);
455 (void) printf(" [ ");
456 for (i
= 0; i
< nelem
; i
++)
457 (void) printf("%llu ", val
[i
]);
461 case DATA_TYPE_STRING_ARRAY
: {
464 (void) nvpair_value_string_array(pv_nvp
, &val
, &nelem
);
465 (void) printf(" [ ");
466 for (i
= 0; i
< nelem
; i
++)
467 (void) printf("\"%s\" ", val
[i
]);
472 (void) fprintf(stderr
, " unknown data type (%d)",
473 nvpair_type(pv_nvp
));
480 print_pgroup(topo_hdl_t
*thp
, tnode_t
*node
, const char *pgn
, char *dstab
,
481 char *nstab
, int32_t version
)
485 topo_pgroup_info_t
*pgi
= NULL
;
490 if (node
!= NULL
&& (dstab
== NULL
|| nstab
== NULL
|| version
== -1)) {
491 if ((pgi
= topo_pgroup_info(node
, pgn
, &err
)) != NULL
) {
492 dstab
= (char *)topo_stability2name(pgi
->tpi_datastab
);
493 nstab
= (char *)topo_stability2name(pgi
->tpi_namestab
);
494 version
= pgi
->tpi_version
;
498 if (dstab
== NULL
|| nstab
== NULL
|| version
== -1) {
499 (void) printf(" group: %-30s version: - stability: -/-\n",
501 } else if (!opt_V
&& strlen(pgn
) > 30) {
502 (void) snprintf(buf
, 26, "%s", pgn
);
503 (void) snprintf(&buf
[27], 4, "%s", DOTS
);
504 (void) printf(" group: %-30s version: %-3d stability: %s/%s\n",
505 buf
, version
, nstab
, dstab
);
507 (void) printf(" group: %-30s version: %-3d stability: %s/%s\n",
508 pgn
, version
, nstab
, dstab
);
512 topo_hdl_strfree(thp
, (char *)pgi
->tpi_name
);
513 topo_hdl_free(thp
, pgi
, sizeof (topo_pgroup_info_t
));
518 print_all_props(topo_hdl_t
*thp
, tnode_t
*node
, nvlist_t
*p_nv
,
521 char *pgn
= NULL
, *dstab
= NULL
, *nstab
= NULL
;
523 nvlist_t
*pg_nv
, *pv_nv
;
524 nvpair_t
*nvp
, *pg_nvp
;
525 int pg_done
, match
, all
= strcmp(group
, ALL
) == 0;
527 for (nvp
= nvlist_next_nvpair(p_nv
, NULL
); nvp
!= NULL
;
528 nvp
= nvlist_next_nvpair(p_nv
, nvp
)) {
529 if (strcmp(TOPO_PROP_GROUP
, nvpair_name(nvp
)) != 0 ||
530 nvpair_type(nvp
) != DATA_TYPE_NVLIST
)
537 (void) nvpair_value_nvlist(nvp
, &pg_nv
);
538 for (pg_nvp
= nvlist_next_nvpair(pg_nv
, NULL
); pg_nvp
!= NULL
;
539 pg_nvp
= nvlist_next_nvpair(pg_nv
, pg_nvp
)) {
541 * Print property group name and stability levels
543 if (strcmp(TOPO_PROP_GROUP_NAME
, nvpair_name(pg_nvp
))
544 == 0 && nvpair_type(pg_nvp
) == DATA_TYPE_STRING
) {
545 (void) nvpair_value_string(pg_nvp
, &pgn
);
546 match
= strcmp(group
, pgn
) == 0;
550 if (strcmp(TOPO_PROP_GROUP_NSTAB
,
551 nvpair_name(pg_nvp
)) == 0 &&
552 nvpair_type(pg_nvp
) == DATA_TYPE_STRING
) {
553 (void) nvpair_value_string(pg_nvp
, &nstab
);
557 if (strcmp(TOPO_PROP_GROUP_DSTAB
,
558 nvpair_name(pg_nvp
)) == 0 &&
559 nvpair_type(pg_nvp
) == DATA_TYPE_STRING
) {
560 (void) nvpair_value_string(pg_nvp
, &dstab
);
564 if (strcmp(TOPO_PROP_GROUP_VERSION
,
565 nvpair_name(pg_nvp
)) == 0 &&
566 nvpair_type(pg_nvp
) == DATA_TYPE_INT32
) {
567 (void) nvpair_value_int32(pg_nvp
, &version
);
571 if ((match
|| all
) && !pg_done
) {
572 print_pgroup(thp
, node
, pgn
, dstab
, nstab
,
578 * Print property group and property name-value pair
580 if (strcmp(TOPO_PROP_VAL
, nvpair_name(pg_nvp
))
581 == 0 && nvpair_type(pg_nvp
) == DATA_TYPE_NVLIST
) {
582 (void) nvpair_value_nvlist(pg_nvp
, &pv_nv
);
583 if ((match
|| all
) && pg_done
) {
584 print_prop_nameval(thp
, node
, pv_nv
);
596 set_prop(topo_hdl_t
*thp
, tnode_t
*node
, nvlist_t
*fmri
, struct prop_args
*pp
)
600 nvlist_t
*nvl
= NULL
;
603 if (pp
->prop
== NULL
|| pp
->type
== NULL
|| pp
->value
== NULL
)
606 if ((type
= str2type(pp
->type
)) == TOPO_TYPE_INVALID
) {
607 (void) fprintf(stderr
, "%s: invalid property type %s for %s\n",
608 g_pname
, pp
->type
, pp
->prop
);
612 if (nvlist_alloc(&nvl
, NV_UNIQUE_NAME
, 0) != 0) {
613 (void) fprintf(stderr
, "%s: nvlist allocation failed for "
614 "%s=%s:%s\n", g_pname
, pp
->prop
, pp
->type
, pp
->value
);
617 ret
= nvlist_add_string(nvl
, TOPO_PROP_VAL_NAME
, pp
->prop
);
618 ret
|= nvlist_add_uint32(nvl
, TOPO_PROP_VAL_TYPE
, type
);
620 (void) fprintf(stderr
, "%s: invalid property type %s for %s\n",
621 g_pname
, pp
->type
, pp
->prop
);
627 case TOPO_TYPE_INT32
:
631 val
= strtol(pp
->value
, &end
, 0);
632 if (errno
== ERANGE
) {
636 ret
= nvlist_add_int32(nvl
, TOPO_PROP_VAL_VAL
, val
);
639 case TOPO_TYPE_UINT32
:
643 val
= strtoul(pp
->value
, &end
, 0);
644 if (errno
== ERANGE
) {
648 ret
= nvlist_add_uint32(nvl
, TOPO_PROP_VAL_VAL
, val
);
651 case TOPO_TYPE_INT64
:
655 val
= strtoll(pp
->value
, &end
, 0);
656 if (errno
== ERANGE
) {
660 ret
= nvlist_add_int64(nvl
, TOPO_PROP_VAL_VAL
, val
);
663 case TOPO_TYPE_UINT64
:
667 val
= strtoull(pp
->value
, &end
, 0);
668 if (errno
== ERANGE
) {
672 ret
= nvlist_add_uint64(nvl
, TOPO_PROP_VAL_VAL
, val
);
675 case TOPO_TYPE_STRING
:
677 ret
= nvlist_add_string(nvl
, TOPO_PROP_VAL_VAL
,
683 nvlist_t
*val
= NULL
;
685 if ((ret
= topo_fmri_str2nvl(thp
, pp
->value
, &val
,
689 if ((ret
= nvlist_add_nvlist(nvl
, TOPO_PROP_VAL_VAL
,
691 err
= ETOPO_PROP_NVL
;
701 (void) fprintf(stderr
, "%s: unable to set property value for "
702 "%s: %s\n", g_pname
, pp
->prop
, topo_strerror(err
));
707 if ((ret
= topo_prop_setprop(node
, pp
->group
, nvl
,
708 TOPO_PROP_MUTABLE
, nvl
, &err
)) < 0) {
709 (void) fprintf(stderr
, "%s: unable to set property "
710 "value for " "%s=%s:%s: %s\n", g_pname
, pp
->prop
,
711 pp
->type
, pp
->value
, topo_strerror(err
));
715 if ((ret
= topo_fmri_setprop(thp
, fmri
, pp
->group
, nvl
,
716 TOPO_PROP_MUTABLE
, nvl
, &err
)) < 0) {
717 (void) fprintf(stderr
, "%s: unable to set property "
718 "value for " "%s=%s:%s: %s\n", g_pname
, pp
->prop
,
719 pp
->type
, pp
->value
, topo_strerror(err
));
728 * Now, get the property back for printing
731 if ((ret
= topo_prop_getprop(node
, pp
->group
, pp
->prop
, NULL
,
733 (void) fprintf(stderr
, "%s: failed to get %s.%s: %s\n",
734 g_pname
, pp
->group
, pp
->prop
, topo_strerror(err
));
738 if ((ret
= topo_fmri_getprop(thp
, fmri
, pp
->group
, pp
->prop
,
739 NULL
, &nvl
, &err
)) < 0) {
740 (void) fprintf(stderr
, "%s: failed to get %s.%s: %s\n",
741 g_pname
, pp
->group
, pp
->prop
, topo_strerror(err
));
746 print_pgroup(thp
, node
, pp
->group
, NULL
, NULL
, 0);
747 print_prop_nameval(thp
, node
, nvl
);
754 print_props(topo_hdl_t
*thp
, tnode_t
*node
)
758 struct prop_args
*pp
;
763 for (i
= 0; i
< pcnt
; ++i
) {
766 if (pp
->group
== NULL
)
770 * If we have a valid value, this is a request to
771 * set a property. Otherwise, just print the property
772 * group and any specified properties.
774 if (pp
->value
== NULL
) {
775 if (pp
->prop
== NULL
) {
778 * Print all properties in this group
780 if ((nvl
= topo_prop_getprops(node
, &err
))
782 (void) fprintf(stderr
, "%s: failed to "
783 "get %s: %s\n", g_pname
,
788 print_all_props(thp
, node
, nvl
,
794 if (topo_prop_getprop(node
, pp
->group
, pp
->prop
,
795 NULL
, &nvl
, &err
) < 0) {
796 (void) fprintf(stderr
, "%s: failed to get "
797 "%s.%s: %s\n", g_pname
,
802 print_pgroup(thp
, node
, pp
->group
, NULL
,
804 print_prop_nameval(thp
, node
, nvl
);
808 set_prop(thp
, node
, NULL
, pp
);
815 walk_node(topo_hdl_t
*thp
, tnode_t
*node
, void *arg
)
819 nvlist_t
*rsrc
, *out
;
822 if (opt_e
&& strcmp(opt_s
, FM_FMRI_SCHEME_HC
) == 0) {
823 print_everstyle(node
);
824 return (TOPO_WALK_NEXT
);
827 if (topo_node_resource(node
, &rsrc
, &err
) < 0) {
828 (void) fprintf(stderr
, "%s: failed to get resource: "
829 "%s", g_pname
, topo_strerror(err
));
830 return (TOPO_WALK_NEXT
);
832 if (topo_fmri_nvl2str(thp
, rsrc
, &s
, &err
) < 0) {
833 (void) fprintf(stderr
, "%s: failed to convert "
834 "resource to FMRI string: %s", g_pname
,
837 return (TOPO_WALK_NEXT
);
840 if (g_fmri
!= NULL
&& fnmatch(g_fmri
, s
, 0) != 0) {
842 topo_hdl_strfree(thp
, s
);
843 return (TOPO_WALK_NEXT
);
846 print_node(thp
, node
, rsrc
, s
);
847 topo_hdl_strfree(thp
, s
);
851 if (topo_method_invoke(node
, opt_m
, 0, NULL
, &out
, &err
) == 0) {
852 nvlist_print(stdout
, out
);
854 } else if (err
!= ETOPO_METHOD_NOTSUP
)
855 (void) fprintf(stderr
, "%s: method failed unexpectedly "
856 "on %s=%d (%s)\n", g_pname
, topo_node_name(node
),
857 topo_node_instance(node
), topo_strerror(err
));
860 if (opt_V
|| opt_all
) {
861 if ((nvl
= topo_prop_getprops(node
, &err
)) == NULL
) {
862 (void) fprintf(stderr
, "%s: failed to get "
863 "properties for %s=%d: %s\n", g_pname
,
864 topo_node_name(node
), topo_node_instance(node
),
867 print_all_props(thp
, node
, nvl
, ALL
);
871 print_props(thp
, node
);
875 return (TOPO_WALK_NEXT
);
879 get_pargs(int argc
, char *argv
[])
881 struct prop_args
*pp
;
885 if ((pargs
= malloc(sizeof (struct prop_args
*) * pcnt
)) == NULL
) {
886 (void) fprintf(stderr
, "%s: failed to allocate property "
887 "arguments\n", g_pname
);
891 for (optind
= 1; (c
= getopt(argc
, argv
, optstr
)) != EOF
; ) {
894 if (strcmp(optarg
, ALL
) == 0) {
899 if ((pp
= pargs
[i
] = malloc(sizeof (struct prop_args
)))
901 (void) fprintf(stderr
, "%s: failed to "
902 "allocate propertyarguments\n", g_pname
);
912 if ((s
= strchr(p
, '.')) != NULL
) {
913 *s
++ = '\0'; /* strike out delimiter */
916 if ((s
= strchr(p
, '=')) != NULL
) {
917 *s
++ = '\0'; /* strike out delimiter */
920 if ((s
= strchr(p
, ':')) != NULL
) {
925 (void) fprintf(stderr
, "%s: "
927 "specified for assignment "
928 " of %s.%s\n", g_pname
,
929 pp
->group
, pp
->prop
);
946 for (j
= 0; j
< i
; ++j
)
954 walk_topo(topo_hdl_t
*thp
, char *uuid
)
960 if (getzoneid() != GLOBAL_ZONEID
&&
961 strcmp(opt_s
, FM_FMRI_SCHEME_HC
) == 0) {
965 if ((twp
= topo_walk_init(thp
, opt_s
, walk_node
, NULL
, &err
))
967 (void) fprintf(stderr
, "%s: failed to walk %s topology:"
968 " %s\n", g_pname
, opt_s
, topo_strerror(err
));
974 * Print standard header
978 time_t tod
= time(NULL
);
980 (void) printf("TIME UUID\n");
981 (void) strftime(buf
, sizeof (buf
), "%b %d %T", localtime(&tod
));
982 (void) printf("%-15s %-32s\n", buf
, uuid
);
986 flag
= opt_b
!= 0 ? TOPO_WALK_SIBLING
: TOPO_WALK_CHILD
;
988 if (topo_walk_step(twp
, flag
) == TOPO_WALK_ERR
) {
989 (void) fprintf(stderr
, "%s: failed to walk topology\n",
1001 print_fmri_pgroup(topo_hdl_t
*thp
, const char *pgn
, nvlist_t
*nvl
)
1003 char *dstab
= NULL
, *nstab
= NULL
;
1004 int32_t version
= -1;
1008 (void) nvlist_lookup_string(nvl
, TOPO_PROP_GROUP_NSTAB
, &nstab
);
1009 (void) nvlist_lookup_string(nvl
, TOPO_PROP_GROUP_DSTAB
, &dstab
);
1010 (void) nvlist_lookup_int32(nvl
, TOPO_PROP_GROUP_VERSION
, &version
);
1012 print_pgroup(thp
, NULL
, pgn
, dstab
, nstab
, version
);
1014 for (pnvp
= nvlist_next_nvpair(nvl
, NULL
); pnvp
!= NULL
;
1015 pnvp
= nvlist_next_nvpair(nvl
, pnvp
)) {
1018 * Print property group and property name-value pair
1020 if (strcmp(TOPO_PROP_VAL
, nvpair_name(pnvp
))
1021 == 0 && nvpair_type(pnvp
) == DATA_TYPE_NVLIST
) {
1022 (void) nvpair_value_nvlist(pnvp
, &pnvl
);
1023 print_prop_nameval(thp
, NULL
, pnvl
);
1031 print_fmri_props(topo_hdl_t
*thp
, nvlist_t
*nvl
)
1034 struct prop_args
*pp
;
1037 for (i
= 0; i
< pcnt
; ++i
) {
1040 if (pp
->group
== NULL
)
1046 * If we have a valid value, this is a request to
1047 * set a property. Otherwise, just print the property
1048 * group and any specified properties.
1050 if (pp
->value
== NULL
) {
1051 if (pp
->prop
== NULL
) {
1054 * Print all properties in this group
1056 if (topo_fmri_getpgrp(thp
, nvl
, pp
->group
,
1058 (void) fprintf(stderr
, "%s: failed to "
1059 "get group %s: %s\n", g_pname
,
1060 pp
->group
, topo_strerror(err
));
1063 print_fmri_pgroup(thp
, pp
->group
,
1069 if (topo_fmri_getprop(thp
, nvl
, pp
->group
, pp
->prop
,
1070 NULL
, &pnvl
, &err
) < 0) {
1071 (void) fprintf(stderr
, "%s: failed to get "
1072 "%s.%s: %s\n", g_pname
,
1073 pp
->group
, pp
->prop
,
1074 topo_strerror(err
));
1077 print_fmri_pgroup(thp
, pp
->group
, pnvl
);
1078 print_prop_nameval(thp
, NULL
, pnvl
);
1082 set_prop(thp
, NULL
, nvl
, pp
);
1088 print_fmri(topo_hdl_t
*thp
, char *uuid
)
1093 time_t tod
= time(NULL
);
1095 if (topo_fmri_str2nvl(thp
, g_fmri
, &nvl
, &err
) < 0) {
1096 (void) fprintf(stderr
, "%s: failed to convert %s to nvlist: "
1097 "%s\n", g_pname
, g_fmri
, topo_strerror(err
));
1101 (void) printf("TIME UUID\n");
1102 (void) strftime(buf
, sizeof (buf
), "%b %d %T", localtime(&tod
));
1103 (void) printf("%-15s %-32s\n", buf
, uuid
);
1104 (void) printf("\n");
1106 (void) printf("%s\n", (char *)g_fmri
);
1108 if (opt_p
&& !(pcnt
> 0 || opt_V
|| opt_all
)) {
1109 char *aname
= NULL
, *fname
= NULL
, *lname
= NULL
;
1110 nvlist_t
*asru
= NULL
;
1111 nvlist_t
*fru
= NULL
;
1113 if (topo_fmri_asru(thp
, nvl
, &asru
, &err
) == 0)
1114 (void) topo_fmri_nvl2str(thp
, asru
, &aname
, &err
);
1115 if (topo_fmri_fru(thp
, nvl
, &fru
, &err
) == 0)
1116 (void) topo_fmri_nvl2str(thp
, fru
, &fname
, &err
);
1117 (void) topo_fmri_label(thp
, nvl
, &lname
, &err
);
1122 if (aname
!= NULL
) {
1123 (void) printf("\tASRU: %s\n", aname
);
1124 topo_hdl_strfree(thp
, aname
);
1126 (void) printf("\tASRU: -\n");
1128 if (fname
!= NULL
) {
1129 (void) printf("\tFRU: %s\n", fname
);
1130 topo_hdl_strfree(thp
, fname
);
1132 (void) printf("\tFRU: -\n");
1134 if (lname
!= NULL
) {
1135 (void) printf("\tLabel: %s\n", lname
);
1136 topo_hdl_strfree(thp
, lname
);
1138 (void) printf("\tLabel: -\n");
1143 if (topo_fmri_str2nvl(thp
, g_fmri
, &nvl
, &err
) < 0) {
1144 (void) printf("\tPresent: -\n");
1145 (void) printf("\tUnusable: -\n");
1149 if ((ret
= topo_fmri_present(thp
, nvl
, &err
)) < 0)
1150 (void) printf("\tPresent: -\n");
1152 (void) printf("\tPresent: %s\n",
1153 ret
? "true" : "false");
1155 if ((ret
= topo_fmri_unusable(thp
, nvl
, &err
)) < 0)
1156 (void) printf("\tUnusable: -\n");
1158 (void) printf("\tUnusable: %s\n",
1159 ret
? "true" : "false");
1164 if (pargs
&& pcnt
> 0)
1165 print_fmri_props(thp
, nvl
);
1169 fmtopo_exit(topo_hdl_t
*thp
, char *uuid
, int err
)
1172 topo_hdl_strfree(thp
, uuid
);
1175 topo_snap_release(thp
);
1181 for (i
= 0; i
< pcnt
; ++i
)
1190 main(int argc
, char *argv
[])
1192 topo_hdl_t
*thp
= NULL
;
1198 while (optind
< argc
) {
1199 while ((c
= getopt(argc
, argv
, optstr
)) != -1) {
1205 (void) atexit(abort
);
1241 return (usage(stderr
));
1245 if (optind
< argc
) {
1246 if (g_fmri
!= NULL
) {
1247 (void) fprintf(stderr
, "%s: illegal argument "
1248 "-- %s\n", g_pname
, argv
[optind
]);
1249 return (FMTOPO_EXIT_USAGE
);
1251 g_fmri
= argv
[optind
++];
1257 get_pargs(argc
, argv
);
1259 if ((thp
= topo_open(TOPO_VERSION
, opt_R
, &err
)) == NULL
) {
1260 (void) fprintf(stderr
, "%s: failed to open topology tree: %s\n",
1261 g_pname
, topo_strerror(err
));
1262 return (fmtopo_exit(thp
, uuid
, FMTOPO_EXIT_ERROR
));
1266 topo_debug_set(thp
, "module", "stderr");
1268 if ((uuid
= topo_snap_hold(thp
, NULL
, &err
)) == NULL
) {
1269 (void) fprintf(stderr
, "%s: failed to snapshot topology: %s\n",
1270 g_pname
, topo_strerror(err
));
1271 return (fmtopo_exit(thp
, uuid
, FMTOPO_EXIT_ERROR
));
1272 } else if (err
!= 0) {
1273 (void) fprintf(stderr
, "%s: topology snapshot incomplete%s\n",
1274 g_pname
, getzoneid() != GLOBAL_ZONEID
&&
1275 strcmp(opt_s
, FM_FMRI_SCHEME_HC
) == 0 ?
1276 " (" FM_FMRI_SCHEME_HC
" scheme does not enumerate "
1277 "in a non-global zone)": "");
1282 (void) fprintf(stderr
,
1283 "%s: -b and -x cannot be specified together\n",
1285 return (fmtopo_exit(thp
, uuid
, FMTOPO_EXIT_USAGE
));
1289 if (topo_xml_print(thp
, stdout
, opt_s
, &err
) < 0)
1290 (void) fprintf(stderr
, "%s: failed to print xml "
1291 "formatted topology:%s", g_pname
,
1292 topo_strerror(err
));
1294 return (fmtopo_exit(thp
, uuid
, err
? FMTOPO_EXIT_ERROR
:
1295 FMTOPO_EXIT_SUCCESS
));
1298 if (opt_t
|| walk_topo(thp
, uuid
) < 0) {
1301 * Try getting some useful information
1303 print_fmri(thp
, uuid
);
1305 return (fmtopo_exit(thp
, uuid
, FMTOPO_EXIT_ERROR
));
1308 return (fmtopo_exit(thp
, uuid
, FMTOPO_EXIT_SUCCESS
));