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,29 **** --- 20,36 ---- */ /* * 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,279 **** } char * nd_get_event_fmri(nd_hdl_t *nhdl, fmev_t ev) { ! nvlist_t *ev_nvl, *attr_nvl; char *svcname; if ((ev_nvl = fmev_attr_list(ev)) == NULL) { ! nd_error(nhdl, "Failed to lookup event attr 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); return (NULL); } ! return (strdup((const char *)svcname)); } int nd_get_notify_prefs(nd_hdl_t *nhdl, const char *mech, fmev_t ev, nvlist_t ***pref_nvl, uint_t *nprefs) --- 263,321 ---- } char * nd_get_event_fmri(nd_hdl_t *nhdl, fmev_t ev) { ! 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 nvlist"); return (NULL); } ! ! /* 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); } ! 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,521 **** */ 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; nd_ev_info_t *evi; ! char *code, *uuid, *fmri, *from_state, *to_state, *reason; if ((evi = calloc(1, sizeof (nd_ev_info_t))) == NULL) { nd_error(nhdl, "Failed to allocate memory"); return (-1); } --- 551,563 ---- */ int nd_get_event_info(nd_hdl_t *nhdl, const char *class, fmev_t ev, nd_ev_info_t **ev_info) { ! nvlist_t *attr_nvl; nd_ev_info_t *evi; ! 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,591 **** /* * 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); /* ! * Lookup the MSGID, event description and severity 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) { 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) evi->ei_severity = strdup(ND_UNKNOWN); ! if (!evi->ei_descr) evi->ei_descr = strdup(ND_UNKNOWN); ! if (!evi->ei_url) 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 (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)) { 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; --- 565,637 ---- /* * Hold event; class and payload will be valid for as long as * we hold the event. */ fmev_hold(ev); + evi->ei_ev = 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, 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(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_type == NULL) ! evi->ei_type = strdup(ND_UNKNOWN); ! if (evi->ei_severity == NULL) evi->ei_severity = strdup(ND_UNKNOWN); ! if (evi->ei_descr == NULL) evi->ei_descr = strdup(ND_UNKNOWN); ! if (evi->ei_url == NULL) evi->ei_url = strdup(ND_UNKNOWN); ! 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 (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); return (-1); } evi->ei_to_state = strdup(to_state); evi->ei_from_state = strdup(from_state); evi->ei_reason = strdup(reason); } *ev_info = evi;