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,28 +21,36 @@
/*
* 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 <strings.h>
#include <stdlib.h>
+#include <strings.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
*
@@ -49,21 +57,33 @@
* # 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;
- long long tstamp;
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,10 +183,12 @@
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,12 +201,13 @@
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];
+ oid var_name[MAX_OID_LEN] = { 0 };
netsnmp_variable_list *notification_vars = NULL;
size_t dt_len;
uchar_t dt[11], *tdt;
@@ -202,57 +225,52 @@
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) memcpy(var_name, sunIreportHostname_oid, oid_len);
(void) snmp_varlist_add_variable(¬ification_vars, var_name,
- sunIreport_base_len + 1, ASN_OCTET_STR, (uchar_t *)t->host,
- strlen(t->host));
+ var_len, ASN_OCTET_STR, (uchar_t *)t->host, strlen(t->host));
- (void) memcpy(var_name, sunIreportMsgid_oid,
- sunIreport_base_len * sizeof (oid));
+ (void) memcpy(var_name, sunIreportMsgid_oid, oid_len);
(void) snmp_varlist_add_variable(¬ification_vars, var_name,
- sunIreport_base_len + 1, ASN_OCTET_STR, (uchar_t *)t->msgid,
- strlen(t->msgid));
+ var_len, ASN_OCTET_STR, (uchar_t *)t->msgid, strlen(t->msgid));
- (void) memcpy(var_name, sunIreportDescription_oid,
- sunIreport_base_len * sizeof (oid));
+ (void) memcpy(var_name, sunIreportSeverity_oid, oid_len);
(void) snmp_varlist_add_variable(¬ification_vars, var_name,
- sunIreport_base_len + 1, ASN_OCTET_STR, (uchar_t *)t->desc,
- strlen(t->desc));
+ var_len, ASN_OCTET_STR, (uchar_t *)t->severity,
+ strlen(t->severity));
- (void) memcpy(var_name, sunIreportTime_oid, sunIreport_base_len *
- sizeof (oid));
+ (void) memcpy(var_name, sunIreportDescription_oid, oid_len);
(void) snmp_varlist_add_variable(¬ification_vars, var_name,
- sunIreport_base_len + 1, ASN_OCTET_STR, dt, dt_len);
+ 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(¬ification_vars, var_name,
+ var_len, ASN_OCTET_STR, dt, dt_len);
+
if (t->is_stn_event) {
- (void) memcpy(var_name, sunIreportSmfFmri_oid,
- sunIreport_base_len * sizeof (oid));
+ (void) memcpy(var_name, sunIreportSmfFmri_oid, oid_len);
(void) snmp_varlist_add_variable(¬ification_vars, var_name,
- sunIreport_base_len + 1, ASN_OCTET_STR, (uchar_t *)t->fmri,
+ var_len, ASN_OCTET_STR, (uchar_t *)t->fmri,
strlen(t->fmri));
- (void) memcpy(var_name, sunIreportSmfFromState_oid,
- sunIreport_base_len * sizeof (oid));
+ (void) memcpy(var_name, sunIreportSmfFromState_oid, oid_len);
(void) snmp_varlist_add_variable(¬ification_vars, var_name,
- sunIreport_base_len + 1, ASN_INTEGER,
- (uchar_t *)&t->from_state, sizeof (uint32_t));
+ var_len, ASN_INTEGER, (uchar_t *)&t->from_state,
+ sizeof (uint32_t));
- (void) memcpy(var_name, sunIreportSmfToState_oid,
- sunIreport_base_len * sizeof (oid));
+ (void) memcpy(var_name, sunIreportSmfToState_oid, oid_len);
(void) snmp_varlist_add_variable(¬ification_vars, var_name,
- sunIreport_base_len + 1, ASN_INTEGER,
- (uchar_t *)&t->to_state, sizeof (uint32_t));
+ var_len, ASN_INTEGER, (uchar_t *)&t->to_state,
+ sizeof (uint32_t));
(void) memcpy(var_name, sunIreportSmfTransitionReason_oid,
- sunIreport_base_len * sizeof (oid));
+ oid_len);
(void) snmp_varlist_add_variable(¬ification_vars, var_name,
- sunIreport_base_len + 1, ASN_OCTET_STR,
- (uchar_t *)t->reason, strlen(t->reason));
+ 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,30 +281,39 @@
(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)
+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 uuid_len = strlen(uuid);
+ 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,43 +335,65 @@
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];
+ 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,
- sunFmProblem_base_len * sizeof (oid));
+ (void) memcpy(var_name, sunFmProblemUUID_oid, oid_len);
(void) snmp_varlist_add_variable(¬ification_vars, var_name, var_len,
- ASN_OCTET_STR, (uchar_t *)uuid, strlen(uuid));
- (void) memcpy(var_name, sunFmProblemCode_oid,
- sunFmProblem_base_len * sizeof (oid));
+ ASN_OCTET_STR, (uchar_t *)t->uuid, strlen(t->uuid));
+
+ (void) memcpy(var_name, sunFmProblemHostname_oid, oid_len);
(void) snmp_varlist_add_variable(¬ification_vars, var_name, var_len,
- ASN_OCTET_STR, (uchar_t *)code, strlen(code));
- (void) memcpy(var_name, sunFmProblemURL_oid,
- sunFmProblem_base_len * sizeof (oid));
+ ASN_OCTET_STR, (uchar_t *)t->host, strlen(t->host));
+
+ (void) memcpy(var_name, sunFmProblemCode_oid, oid_len);
(void) snmp_varlist_add_variable(¬ification_vars, var_name, var_len,
- ASN_OCTET_STR, (uchar_t *)url, strlen(url));
+ ASN_OCTET_STR, (uchar_t *)t->code, strlen(t->code));
+ (void) memcpy(var_name, sunFmProblemType_oid, oid_len);
+ (void) snmp_varlist_add_variable(¬ification_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(¬ification_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(¬ification_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(¬ification_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(¬ification_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", code);
+ nd_debug(nhdl, "Sent SNMP trap for %s", t->code);
snmp_free_varbind(notification_vars);
}
/*
@@ -353,11 +402,11 @@
*
* 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.
+ * to its corresponding enum val.
*/
static int
state_to_val(char *statestr, uint32_t *stateval)
{
if (strcmp(statestr, "offline") == 0)
@@ -408,10 +457,11 @@
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,14 +484,14 @@
/*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;
+ fmproblem_trap_t fmtrap;
uint_t npref;
int ret;
boolean_t domsg;
nd_debug(nhdl, "Received event of class %s", class);
@@ -473,23 +523,26 @@
&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) {
+ 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);
+ 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;
- 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);
+ send_fm_trap(&fmtrap);
listcb_done:
nd_free_nvlarray(pref_nvl, npref);
if (ev_info)
nd_free_event_info(ev_info);
}