Print this page
NEX-18417 bring back UUID-based OIDs for FM traps
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-17772 libfmd_snmp should learn about new FmProblem fields
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@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>
NEX-14494 FMA related SNMP traps should add description
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>

*** 21,48 **** /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. */ #include <sys/fm/protocol.h> #include <fm/fmd_snmp.h> #include <fm/fmd_msg.h> #include <fm/libfmevent.h> #include <net-snmp/net-snmp-config.h> #include <net-snmp/net-snmp-includes.h> #include <net-snmp/agent/net-snmp-agent-includes.h> #include <errno.h> #include <locale.h> #include <netdb.h> #include <signal.h> - #include <strings.h> #include <stdlib.h> #include <unistd.h> - #include <limits.h> - #include <alloca.h> - #include <priv_utils.h> #include <zone.h> #include "libfmnotify.h" /* * Debug messages can be enabled by setting the debug property to true * --- 21,56 ---- /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. */ + /* + * Copyright 2018 Nexenta Systems, Inc. + */ + #include <sys/fm/protocol.h> + #include <fm/fmd_snmp.h> #include <fm/fmd_msg.h> #include <fm/libfmevent.h> + #include <net-snmp/net-snmp-config.h> #include <net-snmp/net-snmp-includes.h> #include <net-snmp/agent/net-snmp-agent-includes.h> + + #include <alloca.h> #include <errno.h> + #include <limits.h> #include <locale.h> #include <netdb.h> + #include <priv_utils.h> #include <signal.h> #include <stdlib.h> + #include <strings.h> #include <unistd.h> #include <zone.h> + #include "libfmnotify.h" /* * Debug messages can be enabled by setting the debug property to true *
*** 49,69 **** * # svccfg -s svc:/system/fm/snmp-notify setprop config/debug=true */ #define SVCNAME "system/fm/snmp-notify" typedef struct ireport_trap { char *host; char *msgid; char *desc; - long long tstamp; char *fmri; uint32_t from_state; uint32_t to_state; char *reason; boolean_t is_stn_event; } ireport_trap_t; static nd_hdl_t *nhdl; static const char optstr[] = "dfR:"; static const char SNMP_SUPPCONF[] = "fmd-trapgen"; static char hostname[MAXHOSTNAMELEN + 1]; --- 57,89 ---- * # svccfg -s svc:/system/fm/snmp-notify setprop config/debug=true */ #define SVCNAME "system/fm/snmp-notify" typedef struct ireport_trap { + long long tstamp; char *host; char *msgid; + char *severity; char *desc; char *fmri; uint32_t from_state; uint32_t to_state; char *reason; boolean_t is_stn_event; } ireport_trap_t; + typedef struct fmproblem_trap { + char *uuid; + char *host; + char *code; + char *type; + char *severity; + char *url; + char *descr; + char *fmri; + } fmproblem_trap_t; + static nd_hdl_t *nhdl; static const char optstr[] = "dfR:"; static const char SNMP_SUPPCONF[] = "fmd-trapgen"; static char hostname[MAXHOSTNAMELEN + 1];
*** 163,172 **** --- 183,194 ---- static const oid sunIreportHostname_oid[] = { SUNIREPORTHOSTNAME_OID }; static const oid sunIreportMsgid_oid[] = { SUNIREPORTMSGID_OID }; + static const oid sunIreportSeverity_oid[] = + { SUNIREPORTSEVERITY_OID }; static const oid sunIreportDescription_oid[] = { SUNIREPORTDESCRIPTION_OID }; static const oid sunIreportTime_oid[] = { SUNIREPORTTIME_OID };
*** 179,190 **** static const oid sunIreportSmfTransitionReason_oid[] = { SUNIREPORTTRANSITIONREASON_OID }; const size_t sunIreport_base_len = OID_LENGTH(sunIreportHostname_oid); size_t var_len = sunIreport_base_len + 1; ! oid var_name[MAX_OID_LEN]; netsnmp_variable_list *notification_vars = NULL; size_t dt_len; uchar_t dt[11], *tdt; --- 201,213 ---- static const oid sunIreportSmfTransitionReason_oid[] = { SUNIREPORTTRANSITIONREASON_OID }; const size_t sunIreport_base_len = OID_LENGTH(sunIreportHostname_oid); + size_t oid_len = sunIreport_base_len * sizeof (oid); size_t var_len = sunIreport_base_len + 1; ! oid var_name[MAX_OID_LEN] = { 0 }; netsnmp_variable_list *notification_vars = NULL; size_t dt_len; uchar_t dt[11], *tdt;
*** 202,258 **** nd_error(nhdl, "var_len %d > MAX_OID_LEN %d\n", var_len, MAX_OID_LEN); return; } ! (void) memcpy(var_name, sunIreportHostname_oid, sunIreport_base_len * ! sizeof (oid)); (void) snmp_varlist_add_variable(&notification_vars, var_name, ! sunIreport_base_len + 1, ASN_OCTET_STR, (uchar_t *)t->host, ! strlen(t->host)); ! (void) memcpy(var_name, sunIreportMsgid_oid, ! sunIreport_base_len * sizeof (oid)); (void) snmp_varlist_add_variable(&notification_vars, var_name, ! sunIreport_base_len + 1, ASN_OCTET_STR, (uchar_t *)t->msgid, ! strlen(t->msgid)); ! (void) memcpy(var_name, sunIreportDescription_oid, ! sunIreport_base_len * sizeof (oid)); (void) snmp_varlist_add_variable(&notification_vars, var_name, ! sunIreport_base_len + 1, ASN_OCTET_STR, (uchar_t *)t->desc, ! strlen(t->desc)); ! (void) memcpy(var_name, sunIreportTime_oid, sunIreport_base_len * ! sizeof (oid)); (void) snmp_varlist_add_variable(&notification_vars, var_name, ! sunIreport_base_len + 1, ASN_OCTET_STR, dt, dt_len); if (t->is_stn_event) { ! (void) memcpy(var_name, sunIreportSmfFmri_oid, ! sunIreport_base_len * sizeof (oid)); (void) snmp_varlist_add_variable(&notification_vars, var_name, ! sunIreport_base_len + 1, ASN_OCTET_STR, (uchar_t *)t->fmri, strlen(t->fmri)); ! (void) memcpy(var_name, sunIreportSmfFromState_oid, ! sunIreport_base_len * sizeof (oid)); (void) snmp_varlist_add_variable(&notification_vars, var_name, ! sunIreport_base_len + 1, ASN_INTEGER, ! (uchar_t *)&t->from_state, sizeof (uint32_t)); ! (void) memcpy(var_name, sunIreportSmfToState_oid, ! sunIreport_base_len * sizeof (oid)); (void) snmp_varlist_add_variable(&notification_vars, var_name, ! sunIreport_base_len + 1, ASN_INTEGER, ! (uchar_t *)&t->to_state, sizeof (uint32_t)); (void) memcpy(var_name, sunIreportSmfTransitionReason_oid, ! sunIreport_base_len * sizeof (oid)); (void) snmp_varlist_add_variable(&notification_vars, var_name, ! sunIreport_base_len + 1, ASN_OCTET_STR, ! (uchar_t *)t->reason, strlen(t->reason)); } /* * This function is capable of sending both v1 and v2/v3 traps. * Which is sent to a specific destination is determined by the --- 225,276 ---- nd_error(nhdl, "var_len %d > MAX_OID_LEN %d\n", var_len, MAX_OID_LEN); return; } ! (void) memcpy(var_name, sunIreportHostname_oid, oid_len); (void) snmp_varlist_add_variable(&notification_vars, var_name, ! var_len, ASN_OCTET_STR, (uchar_t *)t->host, strlen(t->host)); ! (void) memcpy(var_name, sunIreportMsgid_oid, oid_len); (void) snmp_varlist_add_variable(&notification_vars, var_name, ! var_len, ASN_OCTET_STR, (uchar_t *)t->msgid, strlen(t->msgid)); ! (void) memcpy(var_name, sunIreportSeverity_oid, oid_len); (void) snmp_varlist_add_variable(&notification_vars, var_name, ! var_len, ASN_OCTET_STR, (uchar_t *)t->severity, ! strlen(t->severity)); ! (void) memcpy(var_name, sunIreportDescription_oid, oid_len); (void) snmp_varlist_add_variable(&notification_vars, var_name, ! var_len, ASN_OCTET_STR, (uchar_t *)t->desc, strlen(t->desc)); + (void) memcpy(var_name, sunIreportTime_oid, oid_len); + (void) snmp_varlist_add_variable(&notification_vars, var_name, + var_len, ASN_OCTET_STR, dt, dt_len); + if (t->is_stn_event) { ! (void) memcpy(var_name, sunIreportSmfFmri_oid, oid_len); (void) snmp_varlist_add_variable(&notification_vars, var_name, ! var_len, ASN_OCTET_STR, (uchar_t *)t->fmri, strlen(t->fmri)); ! (void) memcpy(var_name, sunIreportSmfFromState_oid, oid_len); (void) snmp_varlist_add_variable(&notification_vars, var_name, ! var_len, ASN_INTEGER, (uchar_t *)&t->from_state, ! sizeof (uint32_t)); ! (void) memcpy(var_name, sunIreportSmfToState_oid, oid_len); (void) snmp_varlist_add_variable(&notification_vars, var_name, ! var_len, ASN_INTEGER, (uchar_t *)&t->to_state, ! sizeof (uint32_t)); (void) memcpy(var_name, sunIreportSmfTransitionReason_oid, ! oid_len); (void) snmp_varlist_add_variable(&notification_vars, var_name, ! var_len, ASN_OCTET_STR, (uchar_t *)t->reason, ! strlen(t->reason)); } /* * This function is capable of sending both v1 and v2/v3 traps. * Which is sent to a specific destination is determined by the
*** 263,292 **** (oid *)sunIreportTrap_oid, sunIreportTrap_len - 2, notification_vars); nd_debug(nhdl, "Sent SNMP trap for %s", t->msgid); snmp_free_varbind(notification_vars); - } - /*ARGSUSED*/ static void ! send_fm_trap(const char *uuid, const char *code, const char *url) { static const oid sunFmProblemTrap_oid[] = { SUNFMPROBLEMTRAP_OID }; const size_t sunFmProblemTrap_len = OID_LENGTH(sunFmProblemTrap_oid); static const oid sunFmProblemUUID_oid[] = { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_UUID }; static const oid sunFmProblemCode_oid[] = { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_CODE }; static const oid sunFmProblemURL_oid[] = { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_URL }; const size_t sunFmProblem_base_len = OID_LENGTH(sunFmProblemUUID_oid); ! size_t uuid_len = strlen(uuid); size_t var_len = sunFmProblem_base_len + 1 + uuid_len; oid var_name[MAX_OID_LEN]; netsnmp_variable_list *notification_vars = NULL; --- 281,319 ---- (oid *)sunIreportTrap_oid, sunIreportTrap_len - 2, notification_vars); nd_debug(nhdl, "Sent SNMP trap for %s", t->msgid); snmp_free_varbind(notification_vars); } static void ! send_fm_trap(fmproblem_trap_t *t) { static const oid sunFmProblemTrap_oid[] = { SUNFMPROBLEMTRAP_OID }; const size_t sunFmProblemTrap_len = OID_LENGTH(sunFmProblemTrap_oid); static const oid sunFmProblemUUID_oid[] = { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_UUID }; + static const oid sunFmProblemHostname_oid[] = + { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_HOSTNAME }; static const oid sunFmProblemCode_oid[] = { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_CODE }; + static const oid sunFmProblemType_oid[] = + { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_TYPE }; + static const oid sunFmProblemSeverity_oid[] = + { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_SEVERITY }; static const oid sunFmProblemURL_oid[] = { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_URL }; + static const oid sunFmProblemDescr_oid[] = + { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_DESC }; + static const oid sunFmProblemFMRI_oid[] = + { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_FMRI }; const size_t sunFmProblem_base_len = OID_LENGTH(sunFmProblemUUID_oid); ! size_t oid_len = sunFmProblem_base_len * sizeof (oid); ! size_t uuid_len = strlen(t->uuid); size_t var_len = sunFmProblem_base_len + 1 + uuid_len; oid var_name[MAX_OID_LEN]; netsnmp_variable_list *notification_vars = NULL;
*** 308,350 **** if (var_len > MAX_OID_LEN) return; var_name[sunFmProblem_base_len] = (oid)uuid_len; for (int i = 0; i < uuid_len; i++) ! var_name[i + sunFmProblem_base_len + 1] = (oid)uuid[i]; /* * Ordinarily, we would need to add the OID of the trap itself * to the head of the variable list; this is required by SNMP v2. * However, send_enterprise_trap_vars does this for us as a part * of converting between v1 and v2 traps, so we skip directly to * the objects we're sending. */ ! (void) memcpy(var_name, sunFmProblemUUID_oid, ! sunFmProblem_base_len * sizeof (oid)); (void) snmp_varlist_add_variable(&notification_vars, var_name, var_len, ! ASN_OCTET_STR, (uchar_t *)uuid, strlen(uuid)); ! (void) memcpy(var_name, sunFmProblemCode_oid, ! sunFmProblem_base_len * sizeof (oid)); (void) snmp_varlist_add_variable(&notification_vars, var_name, var_len, ! ASN_OCTET_STR, (uchar_t *)code, strlen(code)); ! (void) memcpy(var_name, sunFmProblemURL_oid, ! sunFmProblem_base_len * sizeof (oid)); (void) snmp_varlist_add_variable(&notification_vars, var_name, var_len, ! ASN_OCTET_STR, (uchar_t *)url, strlen(url)); /* * This function is capable of sending both v1 and v2/v3 traps. * Which is sent to a specific destination is determined by the * configuration file(s). */ send_enterprise_trap_vars(SNMP_TRAP_ENTERPRISESPECIFIC, sunFmProblemTrap_oid[sunFmProblemTrap_len - 1], (oid *)sunFmProblemTrap_oid, sunFmProblemTrap_len - 2, notification_vars); ! nd_debug(nhdl, "Sent SNMP trap for %s", code); snmp_free_varbind(notification_vars); } /* --- 335,399 ---- if (var_len > MAX_OID_LEN) return; var_name[sunFmProblem_base_len] = (oid)uuid_len; for (int i = 0; i < uuid_len; i++) ! var_name[i + sunFmProblem_base_len + 1] = (oid)t->uuid[i]; /* * Ordinarily, we would need to add the OID of the trap itself * to the head of the variable list; this is required by SNMP v2. * However, send_enterprise_trap_vars does this for us as a part * of converting between v1 and v2 traps, so we skip directly to * the objects we're sending. */ ! (void) memcpy(var_name, sunFmProblemUUID_oid, oid_len); (void) snmp_varlist_add_variable(&notification_vars, var_name, var_len, ! ASN_OCTET_STR, (uchar_t *)t->uuid, strlen(t->uuid)); ! ! (void) memcpy(var_name, sunFmProblemHostname_oid, oid_len); (void) snmp_varlist_add_variable(&notification_vars, var_name, var_len, ! ASN_OCTET_STR, (uchar_t *)t->host, strlen(t->host)); ! ! (void) memcpy(var_name, sunFmProblemCode_oid, oid_len); (void) snmp_varlist_add_variable(&notification_vars, var_name, var_len, ! ASN_OCTET_STR, (uchar_t *)t->code, strlen(t->code)); + (void) memcpy(var_name, sunFmProblemType_oid, oid_len); + (void) snmp_varlist_add_variable(&notification_vars, var_name, var_len, + ASN_OCTET_STR, (uchar_t *)t->type, strlen(t->type)); + + (void) memcpy(var_name, sunFmProblemSeverity_oid, oid_len); + (void) snmp_varlist_add_variable(&notification_vars, var_name, var_len, + ASN_OCTET_STR, (uchar_t *)t->severity, strlen(t->severity)); + + (void) memcpy(var_name, sunFmProblemURL_oid, oid_len); + (void) snmp_varlist_add_variable(&notification_vars, var_name, var_len, + ASN_OCTET_STR, (uchar_t *)t->url, strlen(t->url)); + + (void) memcpy(var_name, sunFmProblemDescr_oid, oid_len); + (void) snmp_varlist_add_variable(&notification_vars, var_name, var_len, + ASN_OCTET_STR, (uchar_t *)t->descr, strlen(t->descr)); + + if (strcmp(t->fmri, ND_UNKNOWN) != 0) { + (void) memcpy(var_name, sunFmProblemFMRI_oid, oid_len); + (void) snmp_varlist_add_variable(&notification_vars, var_name, + var_len, ASN_OCTET_STR, (uchar_t *)t->fmri, + strlen(t->fmri)); + } + /* * This function is capable of sending both v1 and v2/v3 traps. * Which is sent to a specific destination is determined by the * configuration file(s). */ send_enterprise_trap_vars(SNMP_TRAP_ENTERPRISESPECIFIC, sunFmProblemTrap_oid[sunFmProblemTrap_len - 1], (oid *)sunFmProblemTrap_oid, sunFmProblemTrap_len - 2, notification_vars); ! nd_debug(nhdl, "Sent SNMP trap for %s", t->code); snmp_free_varbind(notification_vars); } /*
*** 353,363 **** * * offline(0), online(1), degraded(2), disabled(3), maintenance(4), * uninitialized(5) * * This function converts a string representation of an SMF service state ! * to it's corresponding enum val. */ static int state_to_val(char *statestr, uint32_t *stateval) { if (strcmp(statestr, "offline") == 0) --- 402,412 ---- * * offline(0), online(1), degraded(2), disabled(3), maintenance(4), * uninitialized(5) * * This function converts a string representation of an SMF service state ! * to its corresponding enum val. */ static int state_to_val(char *statestr, uint32_t *stateval) { if (strcmp(statestr, "offline") == 0)
*** 408,417 **** --- 457,467 ---- if (nd_get_event_info(nhdl, class, ev, &ev_info) != 0) goto irpt_done; swtrap.host = hostname; swtrap.msgid = ev_info->ei_diagcode; + swtrap.severity = ev_info->ei_severity; swtrap.desc = ev_info->ei_descr; swtrap.tstamp = (time_t)fmev_time_sec(ev); if (strncmp(class, "ireport.os.smf", 14) == 0) { swtrap.fmri = ev_info->ei_fmri;
*** 434,447 **** /*ARGSUSED*/ static void list_cb(fmev_t ev, const char *class, nvlist_t *nvl, void *arg) { - char *uuid; uint8_t version; nd_ev_info_t *ev_info = NULL; nvlist_t **pref_nvl = NULL; uint_t npref; int ret; boolean_t domsg; nd_debug(nhdl, "Received event of class %s", class); --- 484,497 ---- /*ARGSUSED*/ static void list_cb(fmev_t ev, const char *class, nvlist_t *nvl, void *arg) { uint8_t version; nd_ev_info_t *ev_info = NULL; nvlist_t **pref_nvl = NULL; + fmproblem_trap_t fmtrap; uint_t npref; int ret; boolean_t domsg; nd_debug(nhdl, "Received event of class %s", class);
*** 473,495 **** &domsg) == 0 && !domsg) { nd_debug(nhdl, "Messaging suppressed for this event"); goto listcb_done; } ! if (nvlist_lookup_uint8(ev_info->ei_payload, FM_VERSION, &version) ! != 0 || version > FM_SUSPECT_VERSION) { nd_error(nhdl, "invalid event version: %u", version); goto listcb_done; } ! (void) nvlist_lookup_string(ev_info->ei_payload, FM_SUSPECT_UUID, ! &uuid); ! if (strcmp(ev_info->ei_url, ND_UNKNOWN) != 0) ! send_fm_trap(uuid, ev_info->ei_diagcode, ev_info->ei_url); ! else ! nd_error(nhdl, "failed to format url for %s", uuid); listcb_done: nd_free_nvlarray(pref_nvl, npref); if (ev_info) nd_free_event_info(ev_info); } --- 523,548 ---- &domsg) == 0 && !domsg) { nd_debug(nhdl, "Messaging suppressed for this event"); goto listcb_done; } ! if (nvlist_lookup_uint8(ev_info->ei_payload, FM_VERSION, ! &version) != 0 || version > FM_SUSPECT_VERSION) { nd_error(nhdl, "invalid event version: %u", version); goto listcb_done; } ! fmtrap.uuid = ev_info->ei_uuid; ! fmtrap.host = hostname; ! fmtrap.code = ev_info->ei_diagcode; ! fmtrap.type = ev_info->ei_type; ! fmtrap.severity = ev_info->ei_severity; ! fmtrap.url = ev_info->ei_url; ! fmtrap.descr = ev_info->ei_descr; ! fmtrap.fmri = ev_info->ei_fmri; ! send_fm_trap(&fmtrap); listcb_done: nd_free_nvlarray(pref_nvl, npref); if (ev_info) nd_free_event_info(ev_info); }