Mercurial > illumos > illumos-gate
changeset 10527:239e78cbcf46
6881719 debug message typo in disk_list_gather()
6881732 add facility method for platform event message service LED
6881744 ses enumerator snapshot caching is broken
author | Eric Schrock <Eric.Schrock@Sun.COM> |
---|---|
date | Mon, 14 Sep 2009 16:49:06 -0700 |
parents | a1c57e83a4db |
children | 9c88f2e713fc |
files | usr/src/lib/fm/topo/modules/common/disk/disk_common.c usr/src/lib/fm/topo/modules/common/fac_prov_ipmi/fac_prov_ipmi.c usr/src/lib/fm/topo/modules/common/ipmi/ipmi_enum.c usr/src/lib/fm/topo/modules/common/ses/ses.c usr/src/lib/fm/topo/modules/common/ses/ses.h usr/src/lib/fm/topo/modules/common/ses/ses_facility.c |
diffstat | 6 files changed, 164 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/fm/topo/modules/common/disk/disk_common.c Mon Sep 14 15:13:58 2009 -0600 +++ b/usr/src/lib/fm/topo/modules/common/disk/disk_common.c Mon Sep 14 16:49:06 2009 -0700 @@ -787,13 +787,13 @@ if ((devtree = topo_mod_devinfo(mod)) == DI_NODE_NIL) { topo_mod_dprintf(mod, "disk_list_gather: " - "di_init failed"); + "topo_mod_devinfo() failed"); return (-1); } if ((devhdl = di_devlink_init(NULL, 0)) == DI_NODE_NIL) { topo_mod_dprintf(mod, "disk_list_gather: " - "di_devlink_init failed"); + "di_devlink_init() failed"); return (-1); }
--- a/usr/src/lib/fm/topo/modules/common/fac_prov_ipmi/fac_prov_ipmi.c Mon Sep 14 15:13:58 2009 -0600 +++ b/usr/src/lib/fm/topo/modules/common/fac_prov_ipmi/fac_prov_ipmi.c Mon Sep 14 16:49:06 2009 -0700 @@ -48,6 +48,7 @@ */ #define MAX_ID_LEN 33 +#define TOPO_METH_IPMI_PLATFORM_MESSAGE_VERSION 0 #define TOPO_METH_IPMI_READING_VERSION 0 #define TOPO_METH_IPMI_STATE_VERSION 0 #define TOPO_METH_IPMI_MODE_VERSION 0 @@ -72,6 +73,8 @@ nvlist_t **); static int cs_ipmi_entity(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); +static int ipmi_platform_message(topo_mod_t *, tnode_t *, topo_version_t, + nvlist_t *, nvlist_t **); static int ipmi_sensor_reading(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); static int ipmi_sensor_state(topo_mod_t *, tnode_t *, topo_version_t, @@ -109,6 +112,9 @@ }; static const topo_method_t ipmi_fac_methods[] = { + { "ipmi_platform_message", TOPO_PROP_METH_DESC, + TOPO_METH_IPMI_PLATFORM_MESSAGE_VERSION, + TOPO_STABILITY_INTERNAL, ipmi_platform_message }, { "ipmi_sensor_reading", TOPO_PROP_METH_DESC, TOPO_METH_IPMI_READING_VERSION, TOPO_STABILITY_INTERNAL, ipmi_sensor_reading }, @@ -181,6 +187,147 @@ topo_mod_free(mod, arr, (nelems * sizeof (char *))); } +/* + * Some platforms (most notably G1/2N) use the 'platform event message' command + * to manipulate disk fault LEDs over IPMI, but uses the standard sensor + * reading to read the value. This method implements this alternative + * interface for these platforms. + */ +/*ARGSUSED*/ +static int +ipmi_platform_message(topo_mod_t *mod, tnode_t *node, topo_version_t vers, + nvlist_t *in, nvlist_t **out) +{ + char *entity_ref; + ipmi_sdr_compact_sensor_t *csp; + ipmi_handle_t *hdl; + int err, ret; + uint32_t mode; + nvlist_t *pargs, *nvl; + ipmi_platform_event_message_t pem; + ipmi_sensor_reading_t *reading; + + if (vers > TOPO_METH_IPMI_PLATFORM_MESSAGE_VERSION) + return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW)); + + /* + * Get an IPMI handle and then lookup the generic device locator sensor + * data record referenced by the entity_ref prop val + */ + if ((hdl = topo_mod_ipmi_hold(mod)) == NULL) { + topo_mod_dprintf(mod, "Failed to get IPMI handle\n"); + return (-1); + } + + if (topo_prop_get_string(node, TOPO_PGROUP_FACILITY, "entity_ref", + &entity_ref, &err) != 0) { + topo_mod_dprintf(mod, "Failed to lookup entity_ref property " + "(%s)", topo_strerror(err)); + topo_mod_ipmi_rele(mod); + return (-1); + } + + if ((csp = ipmi_sdr_lookup_compact_sensor(hdl, entity_ref)) == NULL) { + topo_mod_dprintf(mod, "Failed to lookup SDR for %s (%s)\n", + entity_ref, ipmi_errmsg(hdl)); + topo_mod_strfree(mod, entity_ref); + topo_mod_ipmi_rele(mod); + return (-1); + } + + /* + * Now look for a private argument list to figure out whether we're + * doing a get or a set operation, and then do it. + */ + if ((nvlist_lookup_nvlist(in, TOPO_PROP_PARGS, &pargs) == 0) && + nvlist_exists(pargs, TOPO_PROP_VAL_VAL)) { + /* + * Set the LED mode + */ + if ((ret = nvlist_lookup_uint32(pargs, TOPO_PROP_VAL_VAL, + &mode)) != 0) { + topo_mod_dprintf(mod, "Failed to lookup %s nvpair " + "(%s)\n", TOPO_PROP_VAL_VAL, strerror(ret)); + topo_mod_strfree(mod, entity_ref); + (void) topo_mod_seterrno(mod, EMOD_NVL_INVAL); + topo_mod_ipmi_rele(mod); + return (-1); + } + + if (mode != TOPO_LED_STATE_OFF && + mode != TOPO_LED_STATE_ON) { + topo_mod_dprintf(mod, "Invalid property value: %d\n", + mode); + topo_mod_strfree(mod, entity_ref); + (void) topo_mod_seterrno(mod, EMOD_NVL_INVAL); + topo_mod_ipmi_rele(mod); + return (-1); + } + + pem.ipem_sensor_type = csp->is_cs_type; + pem.ipem_sensor_num = csp->is_cs_number; + pem.ipem_event_type = csp->is_cs_reading_type; + + /* + * The spec states that any values between 0x20 and 0x29 are + * legitimate for "system software". However, some versions of + * Sun's ILOM rejects messages over /dev/bmc with a generator + * of 0x20, so we use 0x21 instead. + */ + pem.ipem_generator = 0x21; + pem.ipem_event_dir = 0; + pem.ipem_rev = 0x04; + if (mode == TOPO_LED_STATE_ON) + pem.ipem_event_data[0] = 1; + else + pem.ipem_event_data[0] = 0; + pem.ipem_event_data[1] = 0xff; + pem.ipem_event_data[2] = 0xff; + + if (ipmi_event_platform_message(hdl, &pem) < 0) { + topo_mod_dprintf(mod, "Failed to set LED mode for %s " + "(%s)\n", entity_ref, ipmi_errmsg(hdl)); + topo_mod_strfree(mod, entity_ref); + topo_mod_ipmi_rele(mod); + return (-1); + } + } else { + /* + * Get the LED mode + */ + if ((reading = ipmi_get_sensor_reading(hdl, csp->is_cs_number)) + == NULL) { + topo_mod_dprintf(mod, "Failed to get sensor reading " + "for sensor %s: %s\n", entity_ref, + ipmi_errmsg(hdl)); + topo_mod_strfree(mod, entity_ref); + topo_mod_ipmi_rele(mod); + return (-1); + } + + if (reading->isr_state & + TOPO_SENSOR_STATE_GENERIC_STATE_ASSERTED) + mode = TOPO_LED_STATE_ON; + else + mode = TOPO_LED_STATE_OFF; + } + topo_mod_strfree(mod, entity_ref); + + topo_mod_ipmi_rele(mod); + + if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 || + nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, TOPO_LED_MODE) != 0 || + nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_UINT32) != 0 || + nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, mode) != 0) { + topo_mod_dprintf(mod, "Failed to allocate 'out' nvlist\n"); + nvlist_free(nvl); + return (topo_mod_seterrno(mod, EMOD_NOMEM)); + } + *out = nvl; + + return (0); +} + /*ARGSUSED*/ static int ipmi_sensor_state(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
--- a/usr/src/lib/fm/topo/modules/common/ipmi/ipmi_enum.c Mon Sep 14 15:13:58 2009 -0600 +++ b/usr/src/lib/fm/topo/modules/common/ipmi/ipmi_enum.c Mon Sep 14 16:49:06 2009 -0700 @@ -114,6 +114,9 @@ return (-1); } + topo_mod_dprintf(mod, + "ipmi_entity_present_sdr(%s) = %d\n", name, + present); topo_mod_strfree(mod, name); } else { if (topo_prop_get_string(tn, TOPO_PGROUP_IPMI, @@ -151,6 +154,9 @@ topo_mod_ipmi_rele(mod); return (-1); } + + topo_mod_dprintf(mod, + "ipmi_entity_present() = %d\n", present); } topo_mod_ipmi_rele(mod);
--- a/usr/src/lib/fm/topo/modules/common/ses/ses.c Mon Sep 14 15:13:58 2009 -0600 +++ b/usr/src/lib/fm/topo/modules/common/ses/ses.c Mon Sep 14 16:49:06 2009 -0700 @@ -41,7 +41,7 @@ #define SES_VERSION 1 -#define SES_SNAP_FREQ 1000 /* in milliseconds */ +static int ses_snap_freq = 250; /* in milliseconds */ #define SES_STATUS_UNAVAIL(s) \ ((s) == SES_ESC_UNSUPPORTED || (s) >= SES_ESC_NOT_INSTALLED) @@ -298,9 +298,8 @@ ses_node_t * ses_node_lock(topo_mod_t *mod, tnode_t *tn) { - struct timeval tv; ses_enum_target_t *tp = topo_node_getspecific(tn); - uint64_t prev, now; + hrtime_t now; ses_snap_t *snap; int err; uint64_t nodeid; @@ -316,16 +315,9 @@ /* * Determine if we need to take a new snapshot. */ - if (gettimeofday(&tv, NULL) != 0) { - tv.tv_sec = time(NULL); - tv.tv_usec = 0; - } + now = gethrtime(); - now = tv.tv_sec * 1000 + tv.tv_usec / 1000; - prev = tp->set_snaptime.tv_sec * 1000 + - tp->set_snaptime.tv_usec / 1000; - - if (now - prev > SES_SNAP_FREQ && + if (now - tp->set_snaptime > (ses_snap_freq * 1000 * 1000) && (snap = ses_snap_new(tp->set_target)) != NULL) { if (ses_snap_generation(snap) != ses_snap_generation(tp->set_snap)) { @@ -347,7 +339,7 @@ ses_snap_rele(tp->set_snap); tp->set_snap = snap; } - tp->set_snaptime = tv; + tp->set_snaptime = gethrtime(); } snap = tp->set_snap; @@ -1629,8 +1621,7 @@ stp->set_refcount = 1; sdp->sed_target = stp; stp->set_snap = ses_snap_hold(stp->set_target); - if (gettimeofday(&stp->set_snaptime, NULL) != 0) - stp->set_snaptime.tv_sec = time(NULL); + stp->set_snaptime = gethrtime(); /* * Enumerate over all SES elements and merge them into the
--- a/usr/src/lib/fm/topo/modules/common/ses/ses.h Mon Sep 14 15:13:58 2009 -0600 +++ b/usr/src/lib/fm/topo/modules/common/ses/ses.h Mon Sep 14 16:49:06 2009 -0700 @@ -51,7 +51,7 @@ topo_list_t set_link; ses_target_t *set_target; ses_snap_t *set_snap; - struct timeval set_snaptime; + hrtime_t set_snaptime; char *set_devpath; int set_refcount; pthread_mutex_t set_lock;
--- a/usr/src/lib/fm/topo/modules/common/ses/ses_facility.c Mon Sep 14 15:13:58 2009 -0600 +++ b/usr/src/lib/fm/topo/modules/common/ses/ses_facility.c Mon Sep 14 16:49:06 2009 -0700 @@ -137,6 +137,7 @@ uint32_t mode; boolean_t current, altcurrent; nvlist_t *nvl; + ses_enum_target_t *tp = topo_node_getspecific(tn); if (vers > TOPO_METH_SES_MODE_VERSION) return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW)); @@ -193,6 +194,7 @@ goto error; } + tp->set_snaptime = 0; nvlist_free(nvl); } else { /* get operation */