diff options
| author | Rob Johnston <rob.johnston@joyent.com> | 2018-02-14 00:41:37 +0000 |
|---|---|---|
| committer | Rob Johnston <rob.johnston@joyent.com> | 2018-03-30 18:25:22 +0000 |
| commit | 0d2eb7a53abcabd58cac94fda80cb021bae84390 (patch) | |
| tree | efb7949bf1640ee8be2d8934f49d272b7060a65a | |
| parent | b409c9a314a881a4aa643e85cd5494af77fa4488 (diff) | |
| download | illumos-joyent-0d2eb7a53abcabd58cac94fda80cb021bae84390.tar.gz | |
OS-6607 Expose drive speed and temperature on disk topo node
Reviewed by: Robert Mustacchi <rm@joyent.com>
Approved by: Dan McDonald <danmcd@joyent.com>
| -rw-r--r-- | usr/src/lib/fm/topo/modules/common/disk/Makefile | 4 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/modules/common/disk/disk.h | 3 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/modules/common/disk/disk_common.c | 194 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/modules/common/ses/Makefile | 3 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/modules/common/ses/ses.c | 8 | ||||
| -rw-r--r-- | usr/src/lib/fm/topo/modules/common/ses/ses_facility.c | 6 |
6 files changed, 189 insertions, 29 deletions
diff --git a/usr/src/lib/fm/topo/modules/common/disk/Makefile b/usr/src/lib/fm/topo/modules/common/disk/Makefile index 4b4c965050..8e8935be65 100644 --- a/usr/src/lib/fm/topo/modules/common/disk/Makefile +++ b/usr/src/lib/fm/topo/modules/common/disk/Makefile @@ -22,6 +22,8 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright (c) 2018, Joyent, Inc. +# MODULE = disk CLASS = common @@ -32,5 +34,5 @@ include ../../Makefile.plugin CPPFLAGS += -I$(SRC)/uts/common -LDLIBS += -ldevinfo -ldevid -lcfgadm -ldiskstatus +LDLIBS += -ldevinfo -ldevid -lcfgadm -ldiskstatus -ldiskmgt diff --git a/usr/src/lib/fm/topo/modules/common/disk/disk.h b/usr/src/lib/fm/topo/modules/common/disk/disk.h index d597df27b1..02aa7efc87 100644 --- a/usr/src/lib/fm/topo/modules/common/disk/disk.h +++ b/usr/src/lib/fm/topo/modules/common/disk/disk.h @@ -23,7 +23,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright (c) 2017, Joyent, Inc. + * Copyright (c) 2018, Joyent, Inc. */ #ifndef _DISK_H @@ -50,6 +50,7 @@ extern "C" { #define TOPO_STORAGE_SERIAL_NUM "serial-number" #define TOPO_STORAGE_FIRMWARE_REV "firmware-revision" #define TOPO_STORAGE_CAPACITY "capacity-in-bytes" +#define TOPO_STORAGE_RPM "speed-in-rpm" /* * Properties for binding group: The binding group required in platform diff --git a/usr/src/lib/fm/topo/modules/common/disk/disk_common.c b/usr/src/lib/fm/topo/modules/common/disk/disk_common.c index 123e86f44f..5a7a5b5467 100644 --- a/usr/src/lib/fm/topo/modules/common/disk/disk_common.c +++ b/usr/src/lib/fm/topo/modules/common/disk/disk_common.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2017, Joyent, Inc. + * Copyright (c) 2018, Joyent, Inc. */ /* @@ -38,6 +38,7 @@ #include <ctype.h> #include <strings.h> #include <libdevinfo.h> +#include <libdiskmgt.h> #include <devid.h> #include <sys/libdevid.h> #include <pthread.h> @@ -86,6 +87,20 @@ static const topo_method_t disk_methods[] = { { NULL } }; +static int disk_temp_reading(topo_mod_t *, tnode_t *, topo_version_t, + nvlist_t *, nvlist_t **); + +#define TOPO_METH_DISK_TEMP "disk_temp_reading" +#define TOPO_METH_DISK_TEMP_DESC "Disk Temperature Reading" +#define TOPO_METH_DISK_TEMP_VERSION 0 + +static const topo_method_t disk_fac_methods[] = { + { TOPO_METH_DISK_TEMP, TOPO_METH_DISK_TEMP_DESC, + TOPO_METH_DISK_TEMP_VERSION, TOPO_STABILITY_INTERNAL, + disk_temp_reading }, + { NULL } +}; + static const topo_pgroup_info_t io_pgroup = { TOPO_PGROUP_IO, TOPO_STABILITY_PRIVATE, @@ -125,9 +140,11 @@ static int disk_set_props(topo_mod_t *mod, tnode_t *parent, tnode_t *dtn, dev_di_node_t *dnode) { - nvlist_t *asru = NULL; + nvlist_t *asru = NULL, *drive_attrs; char *label = NULL; nvlist_t *fmri = NULL; + dm_descriptor_t drive_descr = NULL; + uint32_t rpm; int err; /* pull the label property down from our parent 'bay' node */ @@ -265,9 +282,29 @@ disk_set_props(topo_mod_t *mod, tnode_t *parent, "set cap error %s\n", topo_strerror(err)); goto error; } + + if (dnode->ddn_devid == NULL || + (drive_descr = dm_get_descriptor_by_name(DM_DRIVE, + dnode->ddn_devid, &err)) == NULL || + (drive_attrs = dm_get_attributes(drive_descr, &err)) == NULL) + goto out; + + if (nvlist_lookup_boolean(drive_attrs, DM_SOLIDSTATE) == 0 || + nvlist_lookup_uint32(drive_attrs, DM_RPM, &rpm) != 0) + goto out; + + if (topo_prop_set_uint32(dtn, TOPO_PGROUP_STORAGE, TOPO_STORAGE_RPM, + TOPO_PROP_IMMUTABLE, rpm, &err) != 0) { + topo_mod_dprintf(mod, "disk_set_props: " + "set rpm error %s\n", topo_strerror(err)); + dm_free_descriptor(drive_descr); + goto error; + } err = 0; out: + if (drive_descr != NULL) + dm_free_descriptor(drive_descr); nvlist_free(fmri); if (label) topo_mod_strfree(mod, label); @@ -307,26 +344,134 @@ disk_trim_whitespace(topo_mod_t *mod, const char *begin) return (buf); } -/* - * Manufacturing strings can contain characters that are invalid for use in hc - * authority names. This trims leading and trailing whitespace, and - * substitutes any characters known to be bad. - */ -char * -disk_auth_clean(topo_mod_t *mod, const char *str) +/*ARGSUSED*/ +static int +disk_temp_reading(topo_mod_t *mod, tnode_t *node, topo_version_t vers, + nvlist_t *in, nvlist_t **out) { - char *buf, *p; + char *devid; + uint32_t temp; + dm_descriptor_t drive_descr = NULL; + nvlist_t *drive_stats, *pargs, *nvl; + int err; + + if (vers > TOPO_METH_DISK_TEMP_VERSION) + return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW)); + + if (nvlist_lookup_nvlist(in, TOPO_PROP_ARGS, &pargs) != 0 || + nvlist_lookup_string(pargs, TOPO_IO_DEVID, &devid) != 0) { + topo_mod_dprintf(mod, "Failed to lookup %s arg", + TOPO_IO_DEVID); + return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); + } - if (str == NULL) - return (NULL); + if ((drive_descr = dm_get_descriptor_by_name(DM_DRIVE, devid, + &err)) == NULL) { + topo_mod_dprintf(mod, "failed to get drive decriptor for %s", + devid); + return (topo_mod_seterrno(mod, EMOD_UNKNOWN)); + } - if ((buf = topo_mod_strdup(mod, str)) == NULL) - return (NULL); + if ((drive_stats = dm_get_stats(drive_descr, DM_DRV_STAT_TEMPERATURE, + &err)) == NULL || + nvlist_lookup_uint32(drive_stats, DM_TEMPERATURE, &temp) != 0) { + topo_mod_dprintf(mod, "failed to read disk temp for %s", + devid); + dm_free_descriptor(drive_descr); + return (topo_mod_seterrno(mod, EMOD_UNKNOWN)); + } + dm_free_descriptor(drive_descr); + + if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 || + nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, + TOPO_SENSOR_READING) != 0 || + nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_DOUBLE) != + 0 || nvlist_add_double(nvl, TOPO_PROP_VAL_VAL, (double)temp) != 0) { + topo_mod_dprintf(mod, "Failed to allocate 'out' nvlist\n"); + nvlist_free(nvl); + return (topo_mod_seterrno(mod, EMOD_NOMEM)); + } + *out = nvl; - while ((p = strpbrk(buf, " :=")) != NULL) - *p = '-'; + return (0); +} - return (buf); +static int +disk_add_temp_sensor(topo_mod_t *mod, tnode_t *pnode, const char *devid) +{ + tnode_t *fnode; + topo_pgroup_info_t pgi; + nvlist_t *arg_nvl = NULL; + int err; + + if ((fnode = topo_node_facbind(mod, pnode, "temp", + TOPO_FAC_TYPE_SENSOR)) == NULL) { + topo_mod_dprintf(mod, "failed to bind facility node"); + /* errno set */ + return (-1); + } + + /* + * Set props: + * - facility/sensor-class + * - facility/sensor-type + * - facility/units + */ + pgi.tpi_name = TOPO_PGROUP_FACILITY; + pgi.tpi_namestab = TOPO_STABILITY_PRIVATE; + pgi.tpi_datastab = TOPO_STABILITY_PRIVATE; + pgi.tpi_version = 1; + if (topo_pgroup_create(fnode, &pgi, &err) != 0) { + if (err != ETOPO_PROP_DEFD) { + topo_mod_dprintf(mod, "pgroups create failure (%s)\n", + topo_strerror(err)); + /* errno set */ + goto err; + } + } + if (topo_prop_set_string(fnode, TOPO_PGROUP_FACILITY, + TOPO_SENSOR_CLASS, TOPO_PROP_IMMUTABLE, + TOPO_SENSOR_CLASS_THRESHOLD, &err) != 0 || + topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY, + TOPO_FACILITY_TYPE, TOPO_PROP_IMMUTABLE, TOPO_SENSOR_TYPE_TEMP, + &err) != 0 || + topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY, + TOPO_SENSOR_UNITS, TOPO_PROP_IMMUTABLE, + TOPO_SENSOR_UNITS_DEGREES_C, &err) != 0) { + topo_mod_dprintf(mod, "Failed to set props on facnode (%s)", + topo_strerror(err)); + /* errno set */ + goto err; + } + + /* + * Register a property method for facility/reading + */ + if (topo_method_register(mod, fnode, disk_fac_methods) < 0) { + topo_mod_dprintf(mod, "failed to register facility methods"); + goto err; + } + if (topo_mod_nvalloc(mod, &arg_nvl, NV_UNIQUE_NAME) < 0 || + nvlist_add_string(arg_nvl, TOPO_IO_DEVID, devid) != 0) { + topo_mod_dprintf(mod, "Failed build arg nvlist\n"); + (void) topo_mod_seterrno(mod, EMOD_NOMEM); + goto err; + } + if (topo_prop_method_register(fnode, TOPO_PGROUP_FACILITY, + TOPO_SENSOR_READING, TOPO_TYPE_DOUBLE, "disk_temp_reading", + arg_nvl, &err) != 0) { + topo_mod_dprintf(mod, "Failed to register %s propmeth " + "on fac node %s (%s)\n", TOPO_SENSOR_READING, + topo_node_name(fnode), topo_strerror(err)); + /* errno set */ + goto err; + } + nvlist_free(arg_nvl); + return (0); +err: + topo_node_unbind(fnode); + nvlist_free(arg_nvl); + return (-1); } /* create the disk topo node */ @@ -343,10 +488,10 @@ disk_tnode_create(topo_mod_t *mod, tnode_t *parent, *rval = NULL; if (dnode != NULL) { - mfg = disk_auth_clean(mod, dnode->ddn_mfg); - model = disk_auth_clean(mod, dnode->ddn_model); - firm = disk_auth_clean(mod, dnode->ddn_firm); - serial = disk_auth_clean(mod, dnode->ddn_serial); + mfg = topo_mod_clean_str(mod, dnode->ddn_mfg); + model = topo_mod_clean_str(mod, dnode->ddn_model); + firm = topo_mod_clean_str(mod, dnode->ddn_firm); + serial = topo_mod_clean_str(mod, dnode->ddn_serial); } else { mfg = model = firm = serial = NULL; } @@ -404,6 +549,13 @@ disk_tnode_create(topo_mod_t *mod, tnode_t *parent, topo_node_unbind(dtn); return (-1); } + + if (dnode->ddn_devid != NULL && + disk_add_temp_sensor(mod, dtn, dnode->ddn_devid) != 0) { + topo_mod_dprintf(mod, "disk_tnode_create: failed to create " + "temperature sensor node on bay=%d/disk=0", + topo_node_instance(parent)); + } *rval = dtn; return (0); } diff --git a/usr/src/lib/fm/topo/modules/common/ses/Makefile b/usr/src/lib/fm/topo/modules/common/ses/Makefile index 578b5bf493..acd772c92f 100644 --- a/usr/src/lib/fm/topo/modules/common/ses/Makefile +++ b/usr/src/lib/fm/topo/modules/common/ses/Makefile @@ -20,6 +20,7 @@ # # # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, Joyent, Inc. # MODULE = ses @@ -34,6 +35,6 @@ include ../../Makefile.plugin CPPFLAGS += -I../disk LDLIBS += -L$(ROOTLIBDIR)/scsi -R/usr/lib/scsi -lses -LDLIBS += -ldevinfo -ldevid -ldiskstatus -lcontract -lsysevent +LDLIBS += -ldevinfo -ldevid -ldiskstatus -lcontract -lsysevent -ldiskmgt CLOBBERFILES += disk_common.ln diff --git a/usr/src/lib/fm/topo/modules/common/ses/ses.c b/usr/src/lib/fm/topo/modules/common/ses/ses.c index 681c47f005..2f85476cb8 100644 --- a/usr/src/lib/fm/topo/modules/common/ses/ses.c +++ b/usr/src/lib/fm/topo/modules/common/ses/ses.c @@ -23,7 +23,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2012 Milan Jurik. All rights reserved. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 2017, Joyent, Inc. + * Copyright (c) 2018, Joyent, Inc. */ #include <alloca.h> @@ -2854,9 +2854,9 @@ ses_create_chassis(ses_enum_data_t *sdp, tnode_t *pnode, ses_enum_chassis_t *cp) * 'product-id', we use a concatenation of 'manufacturer-model'. We * also take the numerical serial number and convert it to a string. */ - if ((manufacturer = disk_auth_clean(mod, raw_manufacturer)) == NULL || - (model = disk_auth_clean(mod, raw_model)) == NULL || - (revision = disk_auth_clean(mod, raw_revision)) == NULL) { + if ((manufacturer = topo_mod_clean_str(mod, raw_manufacturer)) == + NULL || (model = topo_mod_clean_str(mod, raw_model)) == NULL || + (revision = topo_mod_clean_str(mod, raw_revision)) == NULL) { goto error; } diff --git a/usr/src/lib/fm/topo/modules/common/ses/ses_facility.c b/usr/src/lib/fm/topo/modules/common/ses/ses_facility.c index 08a4a569ee..125c41a83f 100644 --- a/usr/src/lib/fm/topo/modules/common/ses/ses_facility.c +++ b/usr/src/lib/fm/topo/modules/common/ses/ses_facility.c @@ -29,6 +29,10 @@ */ /* + * Copyright (c) 2018, Joyent, Inc. + */ + +/* * Facility node support for SES enclosures. We support the following facility * nodes, based on the node type: * @@ -930,7 +934,7 @@ ses_add_enclosure_sensors(topo_mod_t *mod, tnode_t *tn, ses_node_t *agg, "%.*s %llu", len, desc, index); } - if ((name = disk_auth_clean(mod, rawname)) == NULL) + if ((name = topo_mod_clean_str(mod, rawname)) == NULL) return (-1); if (ses_add_sensor(mod, tn, nodeid, name, &sd) != 0) { |
