summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/fm/fmtopo/common/fmtopo.c57
-rw-r--r--usr/src/lib/fm/topo/libtopo/Makefile.com1
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/topo_2xml.c282
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/topo_xml.c46
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;
}
}