diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/fm/fmtopo/common/fmtopo.c | 57 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/libtopo/Makefile.com | 1 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/topo_2xml.c | 282 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/libtopo/common/topo_xml.c | 46 |
4 files changed, 255 insertions, 131 deletions
diff --git a/usr/src/cmd/fm/fmtopo/common/fmtopo.c b/usr/src/cmd/fm/fmtopo/common/fmtopo.c index 5327cf5da9..07fe40fafd 100644 --- a/usr/src/cmd/fm/fmtopo/common/fmtopo.c +++ b/usr/src/cmd/fm/fmtopo/common/fmtopo.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright (c) 2019, Joyent, Inc. All rights reserved. */ @@ -42,7 +42,6 @@ #define FMTOPO_EXIT_USAGE 2 #define STDERR "stderr" -#define DOTS "..." #define ALL "all" static const char *g_pname; @@ -240,7 +239,7 @@ print_prop_nameval(topo_hdl_t *thp, tnode_t *node, nvlist_t *nvl) { int err; topo_type_t type; - char *tstr, *propn, buf[48], *factype; + char *tstr, *propn, *factype; nvpair_t *pv_nvp; int i; uint_t nelem; @@ -389,12 +388,7 @@ uint32_def: case DATA_TYPE_STRING: { char *val; (void) nvpair_value_string(pv_nvp, &val); - if (!opt_V && strlen(val) > 48) { - (void) snprintf(buf, 48, "%s...", val); - (void) printf(" %s", buf); - } else { - (void) printf(" %s", val); - } + (void) printf(" %s", val); break; } case DATA_TYPE_NVLIST: { @@ -402,19 +396,13 @@ uint32_def: char *fmri; (void) nvpair_value_nvlist(pv_nvp, &val); if (topo_fmri_nvl2str(thp, val, &fmri, &err) != 0) { - if (opt_V) - nvlist_print(stdout, nvl); + (void) fprintf(stderr, "failed to convert " + "FMRI to string: (%s)\n", + topo_strerror(err)); + nvlist_print(stdout, nvl); break; } - - if (!opt_V && strlen(fmri) > 48) { - (void) snprintf(buf, 48, "%s", fmri); - (void) snprintf(&buf[45], 4, "%s", DOTS); - (void) printf(" %s", buf); - } else { - (void) printf(" %s", fmri); - } - + (void) printf(" %s", fmri); topo_hdl_strfree(thp, fmri); break; } @@ -468,6 +456,29 @@ uint32_def: (void) printf("]"); break; } + case DATA_TYPE_NVLIST_ARRAY: { + nvlist_t **val; + char *fmri; + int ret; + + (void) nvpair_value_nvlist_array(pv_nvp, &val, &nelem); + (void) printf(" [ "); + for (i = 0; i < nelem; i++) { + ret = topo_fmri_nvl2str(thp, val[i], &fmri, + &err); + if (ret != 0) { + (void) fprintf(stderr, "failed to " + "convert FMRI to string (%s)\n", + topo_strerror(err)); + nvlist_print(stdout, val[i]); + break; + } + (void) printf("\"%s\" ", fmri); + topo_hdl_strfree(thp, fmri); + } + (void) printf("]"); + break; + } default: (void) fprintf(stderr, " unknown data type (%d)", nvpair_type(pv_nvp)); @@ -481,7 +492,6 @@ print_pgroup(topo_hdl_t *thp, tnode_t *node, const char *pgn, char *dstab, char *nstab, int32_t version) { int err; - char buf[30]; topo_pgroup_info_t *pgi = NULL; if (pgn == NULL) @@ -498,11 +508,6 @@ print_pgroup(topo_hdl_t *thp, tnode_t *node, const char *pgn, char *dstab, if (dstab == NULL || nstab == NULL || version == -1) { (void) printf(" group: %-30s version: - stability: -/-\n", pgn); - } else if (!opt_V && strlen(pgn) > 30) { - (void) snprintf(buf, 26, "%s", pgn); - (void) snprintf(&buf[27], 4, "%s", DOTS); - (void) printf(" group: %-30s version: %-3d stability: %s/%s\n", - buf, version, nstab, dstab); } else { (void) printf(" group: %-30s version: %-3d stability: %s/%s\n", pgn, version, nstab, dstab); diff --git a/usr/src/lib/fm/topo/libtopo/Makefile.com b/usr/src/lib/fm/topo/libtopo/Makefile.com index c0c164fa18..4f397a589e 100644 --- a/usr/src/lib/fm/topo/libtopo/Makefile.com +++ b/usr/src/lib/fm/topo/libtopo/Makefile.com @@ -76,6 +76,7 @@ SRCDIR = ../common CLEANFILES += $(SRCDIR)/topo_error.c $(SRCDIR)/topo_tables.c CPPFLAGS += -I../common -I$(ADJUNCT_PROTO)/usr/include/libxml2 -I. +CSTD = $(CSTD_GNU99) CFLAGS += $(CCVERBOSE) $(C_BIGPICFLAGS) CFLAGS += -D_POSIX_PTHREAD_SEMANTICS CFLAGS64 += $(CCVERBOSE) $(C_BIGPICFLAGS) diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_2xml.c b/usr/src/lib/fm/topo/libtopo/common/topo_2xml.c index d7edbc31e7..768d47d182 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_2xml.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_2xml.c @@ -45,8 +45,15 @@ * 10 bytes for base-10 value + 1 for sign + nul */ #define INT32BUFSZ 12 -/* 2 bytes for "0x" + 16 bytes for the hex value + 1 for sign + nul */ -#define INT64BUFSZ 20 +/* + * Buffer that is large enough to hold the string representation of any signed + * or unsigned 64-bit integer. + * + * 2 bytes for "0x" + 16 bytes for the base-16 value + nul + * or + * 19 bytes for base-10 value + 1 for sign + nul + */ +#define INT64BUFSZ 21 #define XML_VERSION "1.0" static int txml_print_range(topo_hdl_t *, FILE *, tnode_t *, int); @@ -115,129 +122,240 @@ txml_print_prop(topo_hdl_t *thp, FILE *fp, tnode_t *node, const char *pgname, topo_propval_t *pv) { int err; - char *fmri = NULL; - char vbuf[INT64BUFSZ], tbuf[32], *pval = NULL, *aval = NULL; + uint_t nelem; + char vbuf[INT64BUFSZ]; switch (pv->tp_type) { case TOPO_TYPE_INT32: { int32_t val; + if (topo_prop_get_int32(node, pgname, pv->tp_name, &val, - &err) == 0) { - (void) snprintf(vbuf, INT64BUFSZ, "%d", val); - (void) snprintf(tbuf, sizeof (tbuf), "%s", - Int32); - pval = vbuf; - } else + &err) != 0) return; + + (void) snprintf(vbuf, INT64BUFSZ, "%d", val); + begin_end_element(fp, Propval, Name, pv->tp_name, Type, + Int32, Value, vbuf, NULL); break; } case TOPO_TYPE_UINT32: { uint32_t val; + if (topo_prop_get_uint32(node, pgname, pv->tp_name, - &val, &err) == 0) { - (void) snprintf(vbuf, INT64BUFSZ, "0x%x", val); - (void) snprintf(tbuf, sizeof (tbuf), "%s", - UInt32); - pval = vbuf; - } else + &val, &err) != 0) return; + + (void) snprintf(vbuf, INT64BUFSZ, "0x%x", val); + begin_end_element(fp, Propval, Name, pv->tp_name, Type, + UInt32, Value, vbuf, NULL); break; } case TOPO_TYPE_INT64: { int64_t val; + if (topo_prop_get_int64(node, pgname, pv->tp_name, &val, - &err) == 0) { - (void) snprintf(vbuf, INT64BUFSZ, "0x%llx", - (longlong_t)val); - (void) snprintf(tbuf, sizeof (tbuf), "%s", - Int64); - pval = vbuf; - } else + &err) != 0) return; + + (void) snprintf(vbuf, INT64BUFSZ, "%" PRId64, val); + begin_end_element(fp, Propval, Name, pv->tp_name, Type, + Int64, Value, vbuf, NULL); break; } case TOPO_TYPE_UINT64: { uint64_t val; + if (topo_prop_get_uint64(node, pgname, pv->tp_name, - &val, &err) == 0) { - (void) snprintf(vbuf, INT64BUFSZ, "0x%llx", - (u_longlong_t)val); - (void) snprintf(tbuf, sizeof (tbuf), "%s", - UInt64); - pval = vbuf; - } else + &val, &err) != 0) return; + + (void) snprintf(vbuf, INT64BUFSZ, "0x%" PRIx64, val); + begin_end_element(fp, Propval, Name, pv->tp_name, Type, + UInt64, Value, vbuf, NULL); + break; + } + case TOPO_TYPE_DOUBLE: { + double val; + char *dblstr = NULL; + + if (topo_prop_get_double(node, pgname, pv->tp_name, + &val, &err) != 0) + return; + + /* + * The %a format specifier allows floating point values + * to be serialized without losing precision. + */ + if (asprintf(&dblstr, "%a", val) < 0) + return; + begin_end_element(fp, Propval, Name, pv->tp_name, Type, + Double, Value, dblstr, NULL); + free(dblstr); break; } case TOPO_TYPE_STRING: { + char *strbuf = NULL; + if (topo_prop_get_string(node, pgname, pv->tp_name, - &pval, &err) != 0) + &strbuf, &err) != 0) return; - (void) snprintf(tbuf, sizeof (tbuf), "%s", "string"); + + begin_end_element(fp, Propval, Name, pv->tp_name, Type, + String, Value, strbuf, NULL); + topo_hdl_strfree(thp, strbuf); break; } case TOPO_TYPE_FMRI: { - nvlist_t *val; + nvlist_t *val = NULL; + char *fmristr = NULL; if (topo_prop_get_fmri(node, pgname, pv->tp_name, &val, - &err) == 0) { - if (topo_fmri_nvl2str(thp, val, &fmri, &err) - == 0) { - nvlist_free(val); - pval = fmri; - } else { - nvlist_free(val); - return; - } - } else + &err) != 0 || + topo_fmri_nvl2str(thp, val, &fmristr, &err) != 0) { + nvlist_free(val); return; - (void) snprintf(tbuf, sizeof (tbuf), "%s", FMRI); + } + nvlist_free(val); + begin_end_element(fp, Propval, Name, pv->tp_name, Type, + FMRI, Value, fmristr, NULL); + topo_hdl_strfree(thp, fmristr); + break; + } + case TOPO_TYPE_INT32_ARRAY: { + int32_t *val; + + if (topo_prop_get_int32_array(node, pgname, + pv->tp_name, &val, &nelem, &err) != 0) + return; + + begin_element(fp, Propval, Name, pv->tp_name, Type, + Int32_Arr, NULL); + + for (uint_t i = 0; i < nelem; i++) { + (void) snprintf(vbuf, INT64BUFSZ, "%d", val[i]); + begin_end_element(fp, Propitem, Value, vbuf, + NULL); + } + + topo_hdl_free(thp, val, nelem * sizeof (int32_t)); + end_element(fp, Propval); break; } case TOPO_TYPE_UINT32_ARRAY: { uint32_t *val; - uint_t nelem, i; + if (topo_prop_get_uint32_array(node, pgname, pv->tp_name, &val, &nelem, &err) != 0) return; - if (nelem > 0) { - if ((aval = calloc((nelem * 9 - 1), - sizeof (uchar_t))) == NULL) { - - topo_hdl_free(thp, val, - nelem * sizeof (uint32_t)); - return; - } - - (void) sprintf(aval, "0x%x", val[0]); - for (i = 1; i < nelem; i++) { - (void) sprintf(vbuf, " 0x%x", val[i]); - (void) strcat(aval, vbuf); - } - topo_hdl_free(thp, val, - nelem * sizeof (uint32_t)); - (void) snprintf(tbuf, sizeof (tbuf), "%s", - UInt32_Arr); - pval = aval; + begin_element(fp, Propval, Name, pv->tp_name, Type, + UInt32_Arr, NULL); + + for (uint_t i = 0; i < nelem; i++) { + (void) snprintf(vbuf, INT64BUFSZ, "0x%x", + val[i]); + begin_end_element(fp, Propitem, Value, vbuf, + NULL); } + + topo_hdl_free(thp, val, nelem * sizeof (uint32_t)); + end_element(fp, Propval); break; } - default: - return; - } + case TOPO_TYPE_INT64_ARRAY: { + int64_t *val; - begin_end_element(fp, Propval, Name, pv->tp_name, Type, tbuf, - Value, pval, NULL); + if (topo_prop_get_int64_array(node, pgname, + pv->tp_name, &val, &nelem, &err) != 0) + return; + + begin_element(fp, Propval, Name, pv->tp_name, Type, + Int64_Arr, NULL); + + for (uint_t i = 0; i < nelem; i++) { + (void) snprintf(vbuf, INT64BUFSZ, "%" PRId64, + val[i]); + begin_end_element(fp, Propitem, Value, vbuf, + NULL); + } + + topo_hdl_free(thp, val, nelem * sizeof (int64_t)); + end_element(fp, Propval); + break; + } + case TOPO_TYPE_UINT64_ARRAY: { + uint64_t *val; + + if (topo_prop_get_uint64_array(node, pgname, + pv->tp_name, &val, &nelem, &err) != 0) + return; + + begin_element(fp, Propval, Name, pv->tp_name, Type, + UInt64_Arr, NULL); - if (pval != NULL && pv->tp_type == TOPO_TYPE_STRING) - topo_hdl_strfree(thp, pval); + for (uint_t i = 0; i < nelem; i++) { + (void) snprintf(vbuf, INT64BUFSZ, "0x%" PRIx64, + val[i]); + begin_end_element(fp, Propitem, Value, vbuf, + NULL); + } + + topo_hdl_free(thp, val, nelem * sizeof (uint64_t)); + end_element(fp, Propval); + break; + } + case TOPO_TYPE_STRING_ARRAY: { + char **val; + + if (topo_prop_get_string_array(node, pgname, + pv->tp_name, &val, &nelem, &err) != 0) + return; - if (fmri != NULL) - topo_hdl_strfree(thp, fmri); + begin_element(fp, Propval, Name, pv->tp_name, Type, + String_Arr, NULL); - if (aval != NULL) - free(aval); + for (uint_t i = 0; i < nelem; i++) { + begin_end_element(fp, Propitem, Value, val[i], + NULL); + } + for (uint_t i = 0; i < nelem; i++) { + topo_hdl_strfree(thp, val[i]); + } + topo_hdl_free(thp, val, nelem * sizeof (char *)); + + end_element(fp, Propval); + break; + } + case TOPO_TYPE_FMRI_ARRAY: { + nvlist_t **val; + char *fmristr = NULL; + int ret; + + if (topo_prop_get_fmri_array(node, pgname, + pv->tp_name, &val, &nelem, &err) != 0) + return; + + begin_element(fp, Propval, Name, pv->tp_name, Type, + FMRI_Arr, NULL); + + for (uint_t i = 0; i < nelem; i++) { + if ((ret = topo_fmri_nvl2str(thp, val[i], + &fmristr, &err)) != 0) + break; + begin_end_element(fp, Propitem, Value, fmristr, + NULL); + topo_hdl_strfree(thp, fmristr); + } + for (uint_t i = 0; i < nelem; i++) { + nvlist_free(val[i]); + } + topo_hdl_free(thp, val, nelem * sizeof (nvlist_t *)); + end_element(fp, Propval); + break; + } + default: + return; + } } static void @@ -277,7 +395,19 @@ txml_print_node(topo_hdl_t *thp, FILE *fp, tnode_t *node) topo_pgroup_t *pg; (void) snprintf(inst, INT32BUFSZ, "%d", node->tn_instance); - begin_element(fp, Node, Instance, inst, Static, True, NULL); + /* + * The "static" attribute for the "node" element controls whether the + * node gets enumerated, if it doesn't already exist. Setting it to + * true causes the node to not be created. The primary use-case for + * setting it to true is when want to use XML to override a property + * value on a topo node that was already created by an enumerator + * module. In this case we're trying to serialize the whole topology + * in a fashion such that we could reconstitute it from the generated + * XML. In which case, we relly need it to create all the nodes becuase + * no enumerator modules will be running. Hence, we set static to + * false. + */ + begin_element(fp, Node, Instance, inst, Static, False, NULL); for (pg = topo_list_next(&node->tn_pgroups); pg != NULL; pg = topo_list_next(pg)) { txml_print_pgroup(thp, fp, node, pg); diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_xml.c b/usr/src/lib/fm/topo/libtopo/common/topo_xml.c index d907c72c44..3e3241c8f3 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_xml.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_xml.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2018, Joyent, Inc. + * Copyright (c) 2019, Joyent, Inc. */ #include <libxml/parser.h> @@ -118,8 +118,10 @@ xmlattr_to_int(topo_mod_t *mp, propname); if ((str = xmlGetProp(n, (xmlChar *)propname)) == NULL) return (topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR)); - *value = strtoull((char *)str, (char **)&estr, 10); - if (estr == str) { + + errno = 0; + *value = strtoull((char *)str, (char **)&estr, 0); + if (errno != 0 || *estr != '\0') { /* no conversion was done */ xmlFree(str); return (topo_mod_seterrno(mp, ETOPO_PRSR_BADNUM)); @@ -139,8 +141,10 @@ xmlattr_to_double(topo_mod_t *mp, "xmlattr_to_double(propname=%s)\n", propname); if ((str = xmlGetProp(n, (xmlChar *)propname)) == NULL) return (topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR)); - *value = strtod((char *)str, (char **)&estr); - if (estr == str || *estr != '\0') { + + errno = 0; + *value = strtold((char *)str, (char **)&estr); + if (errno != 0 || *estr != '\0') { /* full or partial conversion failure */ xmlFree(str); return (topo_mod_seterrno(mp, ETOPO_PRSR_BADNUM)); @@ -301,13 +305,9 @@ xlate_common(topo_mod_t *mp, xmlNodePtr xn, topo_type_t ptype, nvlist_t *nvl, if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) || (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) { - if ((str = xmlGetProp(cn, (xmlChar *)Value)) - == NULL) + if (xmlattr_to_int(mp, cn, Value, &ui) < 0) return (-1); - - ((int32_t *)arrbuf)[i++] - = atoi((const char *)str); - xmlFree(str); + ((int32_t *)arrbuf)[i++] = (int32_t)ui; } } @@ -323,13 +323,9 @@ xlate_common(topo_mod_t *mp, xmlNodePtr xn, topo_type_t ptype, nvlist_t *nvl, if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) || (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) { - if ((str = xmlGetProp(cn, (xmlChar *)Value)) - == NULL) + if (xmlattr_to_int(mp, cn, Value, &ui) < 0) return (-1); - - ((uint32_t *)arrbuf)[i++] - = atoi((const char *)str); - xmlFree(str); + ((uint32_t *)arrbuf)[i++] = (uint32_t)ui; } } @@ -345,13 +341,9 @@ xlate_common(topo_mod_t *mp, xmlNodePtr xn, topo_type_t ptype, nvlist_t *nvl, if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) || (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) { - if ((str = xmlGetProp(cn, (xmlChar *)Value)) - == NULL) + if (xmlattr_to_int(mp, cn, Value, &ui) < 0) return (-1); - - ((int64_t *)arrbuf)[i++] - = atol((const char *)str); - xmlFree(str); + ((int64_t *)arrbuf)[i++] = (int64_t)ui; } } @@ -367,13 +359,9 @@ xlate_common(topo_mod_t *mp, xmlNodePtr xn, topo_type_t ptype, nvlist_t *nvl, if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) || (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) { - if ((str = xmlGetProp(cn, (xmlChar *)Value)) - == NULL) + if (xmlattr_to_int(mp, cn, Value, &ui) < 0) return (-1); - - ((uint64_t *)arrbuf)[i++] - = atol((const char *)str); - xmlFree(str); + ((uint64_t *)arrbuf)[i++] = ui; } } |