Print this page
NEX-17829 libfmd_snmp and snmp-notify should provide FMRIs for all fault types
Reviewed by: Cynthia Eastham <cynthia.eastham@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-16536 SUN-IREPORT-MIB is broken
NEX-16537 enhance FM traps
NEX-16545 SMF dict should have obsolete entries removed
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Cynthia Eastham <cynthia.eastham@nexenta.com>
Reviewed by: Alexander Eremin <alexander.eremin@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
@@ -20,10 +20,17 @@
*/
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*/
+
+/*
+ * Copyright 2018 Nexenta Systems, Inc.
+ */
+
+#include <fm/libtopo.h>
+
#include <alloca.h>
#include "libfmnotify.h"
/*ARGSUSED*/
@@ -256,24 +263,59 @@
}
char *
nd_get_event_fmri(nd_hdl_t *nhdl, fmev_t ev)
{
- nvlist_t *ev_nvl, *attr_nvl;
+ nvlist_t *ev_nvl, *snvl;
+ nvlist_t **fnvl;
+ uint_t nnvl;
char *svcname;
if ((ev_nvl = fmev_attr_list(ev)) == NULL) {
- nd_error(nhdl, "Failed to lookup event attr nvlist");
+ nd_error(nhdl, "failed to lookup event nvlist");
return (NULL);
}
- if (nvlist_lookup_nvlist(ev_nvl, "attr", &attr_nvl) ||
- nvlist_lookup_string(attr_nvl, "svc-string", &svcname)) {
- nd_error(nhdl, "Malformed event 0x%p", (void *)ev_nvl);
+
+ /* If this is an ireport, simply lookup svc-string */
+ if (nvlist_lookup_nvlist(ev_nvl, "attr", &snvl) == 0 &&
+ nvlist_lookup_string(snvl, "svc-string", &svcname) == 0)
+ return (strdup((const char *)svcname));
+
+ /* Otherwise extract the fault-list and use the first element */
+ if (nvlist_lookup_nvlist_array(ev_nvl, FM_SUSPECT_FAULT_LIST,
+ &fnvl, &nnvl) != 0 || nnvl != 1)
return (NULL);
+
+ /*
+ * NOTE: this should match the logic in libfmd_snmp.
+ *
+ * Use the following order of nested nvlists to make up FMRI:
+ * - FRU
+ * - ASRU
+ * - resource
+ */
+ if (nvlist_lookup_nvlist(fnvl[0], FM_FAULT_FRU, &snvl) == 0 ||
+ nvlist_lookup_nvlist(fnvl[0], FM_FAULT_ASRU, &snvl) == 0 ||
+ nvlist_lookup_nvlist(fnvl[0], FM_FAULT_RESOURCE, &snvl) == 0) {
+ topo_hdl_t *thp;
+ int topoerr;
+ char *fmri, *ret = NULL;
+
+ thp = topo_open(TOPO_VERSION, NULL, &topoerr);
+ if (thp == NULL)
+ return (NULL);
+
+ if (topo_fmri_nvl2str(thp, snvl, &fmri, &topoerr) == 0) {
+ ret = strdup(fmri);
+ topo_hdl_strfree(thp, fmri);
}
- return (strdup((const char *)svcname));
+ topo_close(thp);
+ return (ret);
+ }
+
+ return (NULL);
}
int
nd_get_notify_prefs(nd_hdl_t *nhdl, const char *mech, fmev_t ev,
nvlist_t ***pref_nvl, uint_t *nprefs)
@@ -509,13 +551,13 @@
*/
int
nd_get_event_info(nd_hdl_t *nhdl, const char *class, fmev_t ev,
nd_ev_info_t **ev_info)
{
- nvlist_t *ev_nvl, *attr_nvl;
+ nvlist_t *attr_nvl;
nd_ev_info_t *evi;
- char *code, *uuid, *fmri, *from_state, *to_state, *reason;
+ char *code, *uuid, *from_state, *to_state, *reason;
if ((evi = calloc(1, sizeof (nd_ev_info_t))) == NULL) {
nd_error(nhdl, "Failed to allocate memory");
return (-1);
}
@@ -523,69 +565,73 @@
/*
* Hold event; class and payload will be valid for as long as
* we hold the event.
*/
fmev_hold(ev);
+
evi->ei_ev = ev;
- ev_nvl = fmev_attr_list(ev);
+ evi->ei_class = fmev_class(ev);
+ evi->ei_payload = fmev_attr_list(ev);
+ if (nvlist_lookup_string(evi->ei_payload, FM_SUSPECT_UUID,
+ &uuid) == 0) {
+ evi->ei_uuid = strdup(uuid);
+ } else {
+ nd_error(nhdl, "Malformed event");
+ nd_dump_nvlist(nhdl, evi->ei_payload);
+ nd_free_event_info(evi);
+ return (-1);
+ }
+
/*
- * Lookup the MSGID, event description and severity and KA URL
+ * Lookup the MSGID, type, severity, description, and KA URL.
*
* For FMA list.* events we just pull it out of the the event nvlist.
* For all other events we call a utility function that computes the
* diagcode using the dict name and class.
*/
evi->ei_diagcode = calloc(32, sizeof (char));
- if ((nvlist_lookup_string(ev_nvl, FM_SUSPECT_DIAG_CODE, &code) == 0 &&
- strcpy(evi->ei_diagcode, code)) ||
- nd_get_diagcode(nhdl, "SMF", class, evi->ei_diagcode, 32)
- == 0) {
+ if ((nvlist_lookup_string(evi->ei_payload, FM_SUSPECT_DIAG_CODE,
+ &code) == 0 && strcpy(evi->ei_diagcode, code) != NULL) ||
+ nd_get_diagcode(nhdl, "SMF", class, evi->ei_diagcode, 32) == 0) {
+ evi->ei_type = fmd_msg_getitem_id(nhdl->nh_msghdl,
+ NULL, evi->ei_diagcode, FMD_MSG_ITEM_TYPE);
evi->ei_severity = fmd_msg_getitem_id(nhdl->nh_msghdl,
NULL, evi->ei_diagcode, FMD_MSG_ITEM_SEVERITY);
evi->ei_descr = fmd_msg_getitem_id(nhdl->nh_msghdl,
NULL, evi->ei_diagcode, FMD_MSG_ITEM_DESC);
evi->ei_url = fmd_msg_getitem_id(nhdl->nh_msghdl,
NULL, evi->ei_diagcode, FMD_MSG_ITEM_URL);
} else
(void) strcpy(evi->ei_diagcode, ND_UNKNOWN);
- if (!evi->ei_severity)
+ if (evi->ei_type == NULL)
+ evi->ei_type = strdup(ND_UNKNOWN);
+ if (evi->ei_severity == NULL)
evi->ei_severity = strdup(ND_UNKNOWN);
- if (!evi->ei_descr)
+ if (evi->ei_descr == NULL)
evi->ei_descr = strdup(ND_UNKNOWN);
- if (!evi->ei_url)
+ if (evi->ei_url == NULL)
evi->ei_url = strdup(ND_UNKNOWN);
- evi->ei_payload = ev_nvl;
- evi->ei_class = fmev_class(ev);
- if (nvlist_lookup_string(ev_nvl, FM_SUSPECT_UUID, &uuid) == 0)
- evi->ei_uuid = strdup(uuid);
- else {
- nd_error(nhdl, "Malformed event");
- nd_dump_nvlist(nhdl, evi->ei_payload);
- nd_free_event_info(evi);
- return (-1);
- }
+ if ((evi->ei_fmri = nd_get_event_fmri(nhdl, ev)) == NULL)
+ evi->ei_fmri = strdup(ND_UNKNOWN);
if (strncmp(class, "ireport.os.smf", 14) == 0) {
- if ((fmri = nd_get_event_fmri(nhdl, ev)) == NULL) {
- nd_error(nhdl, "Failed to get fmri from event payload");
- nd_free_event_info(evi);
- return (-1);
- }
- if (nvlist_lookup_nvlist(evi->ei_payload, "attr", &attr_nvl) ||
- nvlist_lookup_string(attr_nvl, "from-state", &from_state) ||
- nvlist_lookup_string(attr_nvl, "to-state", &to_state) ||
- nvlist_lookup_string(attr_nvl, "reason-long", &reason)) {
+ if (nvlist_lookup_nvlist(evi->ei_payload, "attr",
+ &attr_nvl) != 0 ||
+ nvlist_lookup_string(attr_nvl, "from-state",
+ &from_state) != 0 ||
+ nvlist_lookup_string(attr_nvl, "to-state",
+ &to_state) != 0 ||
+ nvlist_lookup_string(attr_nvl, "reason-long",
+ &reason) != 0) {
nd_error(nhdl, "Malformed event");
nd_dump_nvlist(nhdl, evi->ei_payload);
nd_free_event_info(evi);
- free(fmri);
return (-1);
}
- evi->ei_fmri = fmri;
evi->ei_to_state = strdup(to_state);
evi->ei_from_state = strdup(from_state);
evi->ei_reason = strdup(reason);
}
*ev_info = evi;