📄 snmp_rsa_event.c
字号:
/* -*- linux-c -*- * * (C) Copyright IBM Corp. 2004 * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This * file and program are licensed under a BSD style license. See * the Copying file included with the OpenHPI distribution for * full licensing terms. * * Author(s): * Steve Sherman <stevees@us.ibm.com> * W. David Ashley <dashley@us.ibm.com> */#include <glib.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <SaHpi.h>#include <openhpi.h>#include <oh_plugin.h>#include <oh_utils.h>#include <rsa_resources.h>#include <rsa_str2event.h>#include <rsa_errorlog.h>#include <snmp_util.h>#include <snmp_rsa.h>#include <snmp_rsa_sel.h>#include <snmp_rsa_utils.h>#include <snmp_rsa_event.h>unsigned int rsa_str2event_use_count = 0; /* It is here for initialization */ typedef enum { EVENT_NOT_MAPPED, EVENT_NOT_ALERTABLE,} OEMReasonCodeT;static void free_hash_data(gpointer key, gpointer value, gpointer user_data);static int parse_threshold_str(gchar *str, gchar *root_str, gchar *read_value_str, gchar *trigger_value_str);static int set_previous_event_state(void *hnd, SaHpiEventT *event, int recovery_event, int *event_enabled);static int map2oem(SaHpiEventT *event, rsa_sel_entry *sel_entry, OEMReasonCodeT reason);static Str2EventInfoT *findevent4dupstr(gchar *search_str, Str2EventInfoT *dupstrhash_data, LogSource2ResourceT *resinfo);int event2hpi_hash_init(struct oh_handler_state *handle){ struct snmp_rsa_hnd *custom_handle = (struct snmp_rsa_hnd *)handle->data; GHashTable *event2hpi_hash = g_hash_table_new(g_str_hash, g_str_equal); custom_handle->event2hpi_hash_ptr = event2hpi_hash; if (event2hpi_hash == NULL) { dbg("Cannot allocate event2hpi_hash table"); return -1; } return 0;}int event2hpi_hash_free(struct oh_handler_state *handle){ struct snmp_rsa_hnd *custom_handle = (struct snmp_rsa_hnd *)handle->data; GHashTable *event2hpi_hash = custom_handle->event2hpi_hash_ptr; g_hash_table_foreach(event2hpi_hash, free_hash_data, NULL); g_hash_table_destroy(event2hpi_hash); return 0;}static void free_hash_data(gpointer key, gpointer value, gpointer user_data){ g_free(key); /* Memory was created for these during normalization process */ g_free(value);}int find_res_events(struct oh_handler_state *handle, SaHpiEntityPathT *ep, const struct RSA_ResourceInfo *rsa_res_info){ int i; int max = MAX_RESOURCE_EVENT_ARRAY_SIZE; char *normalized_str; char *hash_existing_key, *hash_value; SaHpiEventT *hpievent; SaHpiResourceIdT rid; struct snmp_rsa_hnd *custom_handle = (struct snmp_rsa_hnd *)handle->data; GHashTable *event2hpi_hash = custom_handle->event2hpi_hash_ptr; rid = oh_uid_lookup(ep); if (rid == 0) { dbg("RID = 0"); return -1; } for (i=0; rsa_res_info->event_array[i].event != NULL && i < max; i++) { /* Normalized and convert event string */ normalized_str = snmp_derive_objid(*ep, rsa_res_info->event_array[i].event); if (normalized_str == NULL) { dbg("NULL string returned for event=%s\n", rsa_res_info->event_array[i].event); return -1; } /* Add to hash; Set HPI values */ if (!g_hash_table_lookup_extended(event2hpi_hash, normalized_str, (gpointer)&hash_existing_key, (gpointer)&hash_value)) { hpievent = g_malloc0(sizeof(SaHpiEventT)); if (!hpievent) { dbg("Cannot allocate memory for HPI event"); g_free(normalized_str); return -1; } hpievent->Source = rid; hpievent->EventType = SAHPI_ET_HOTSWAP; hpievent->EventDataUnion.HotSwapEvent.HotSwapState = rsa_res_info->event_array[i].event_state; /* Overload field with recovery state - this will be overwritten when event is processed with current resource's state */ hpievent->EventDataUnion.HotSwapEvent.PreviousHotSwapState = rsa_res_info->event_array[i].recovery_state; g_hash_table_insert(event2hpi_hash, normalized_str, hpievent); /* normalized_str space is recovered when hash is freed */ } else { /* Event already exists */ g_free(normalized_str); } } return 0;}int find_sensor_events(struct oh_handler_state *handle, SaHpiEntityPathT *ep, SaHpiSensorNumT sid, const struct snmp_rsa_sensor *rpt_sensor){ int i; int max = MAX_SENSOR_EVENT_ARRAY_SIZE; char *normalized_str; char *hash_existing_key, *hash_value; SaHpiEventT *hpievent; SaHpiResourceIdT rid; struct snmp_rsa_hnd *custom_handle = (struct snmp_rsa_hnd *)handle->data; GHashTable *event2hpi_hash = custom_handle->event2hpi_hash_ptr; rid = oh_uid_lookup(ep); if (rid == 0) { dbg("RID = 0"); return -1; } for (i=0; rpt_sensor->rsa_sensor_info.event_array[i].event != NULL && i < max; i++) { /* Normalized and convert event string */ normalized_str = snmp_derive_objid(*ep, rpt_sensor->rsa_sensor_info.event_array[i].event); if (normalized_str == NULL) { dbg("NULL string returned for event=%s\n", rpt_sensor->rsa_sensor_info.event_array[i].event); return -1; } /* Add to hash; Set HPI values */ if (!g_hash_table_lookup_extended(event2hpi_hash, normalized_str, (gpointer)&hash_existing_key, (gpointer)&hash_value)) { hpievent = g_malloc0(sizeof(SaHpiEventT)); if (!hpievent) { dbg("Cannot allocate memory for HPI event"); g_free(normalized_str); return -1; } /* Set values */ hpievent->Source = rid; hpievent->EventType = SAHPI_ET_SENSOR; hpievent->EventDataUnion.SensorEvent.SensorNum = sid; hpievent->EventDataUnion.SensorEvent.SensorType = rpt_sensor->sensor.Type; hpievent->EventDataUnion.SensorEvent.EventCategory = rpt_sensor->sensor.Category; hpievent->EventDataUnion.SensorEvent.Assertion = SAHPI_TRUE; hpievent->EventDataUnion.SensorEvent.EventState = rpt_sensor->rsa_sensor_info.event_array[i].event_state; /* Overload field with recovery state - this will be overwritten when event is processed with current resource's state */ hpievent->EventDataUnion.SensorEvent.PreviousState = rpt_sensor->rsa_sensor_info.event_array[i].recovery_state; /* Setup trigger values for threshold sensors */ if (rpt_sensor->sensor.ThresholdDefn.IsThreshold == SAHPI_TRUE) { if (rpt_sensor->sensor.DataFormat.Range.Max.ValuesPresent & SAHPI_SRF_INTERPRETED) { hpievent->EventDataUnion.SensorEvent.TriggerReading.ValuesPresent = hpievent->EventDataUnion.SensorEvent.TriggerReading.ValuesPresent | SAHPI_SRF_INTERPRETED; hpievent->EventDataUnion.SensorEvent.TriggerReading.Interpreted.Type = rpt_sensor->sensor.DataFormat.Range.Max.Interpreted.Type; hpievent->EventDataUnion.SensorEvent.TriggerThreshold.ValuesPresent = hpievent->EventDataUnion.SensorEvent.TriggerThreshold.ValuesPresent | SAHPI_SRF_INTERPRETED; hpievent->EventDataUnion.SensorEvent.TriggerThreshold.Interpreted.Type = rpt_sensor->sensor.DataFormat.Range.Max.Interpreted.Type; } else { dbg("Max.Interpreted must be defined for threshold sensor=%s\n", rpt_sensor->comment); g_free(normalized_str); g_free(hpievent); return -1; } } g_hash_table_insert(event2hpi_hash, normalized_str, hpievent); /* normalized_str space is recovered when hash is freed */ } else { /* Event already exists */ g_free(normalized_str); } } return 0;}/**************************************************************************** * log2event maps RSA error log entries to HPI events. * isdst ("is DayLight Savings Time") parameter is a performance hack. * Design assumes the event's timestamp is the time local to the RSA box itself. * So instead of forcing RSA SNMP accesses for each log entry to determine if * DST is in effect on the RSA box, the isdst parameter allows the caller to * query the RSA for DST info once then make multiple translation calls. *****************************************************************************/int rsa_log2event(void *hnd, gchar *logstr, SaHpiEventT *event, int isdst, int *event_enabled){ rsa_sel_entry log_entry; gchar *recovery_str, *login_str; gchar search_str[RSA_SEL_ENTRY_STRING]; gchar thresh_read_value[MAX_THRESHOLD_VALUE_STRINGSIZE]; gchar thresh_trigger_value[MAX_THRESHOLD_VALUE_STRINGSIZE]; int is_recovery_event, is_threshold_event; LogSource2ResourceT resinfo; SaHpiEventT working, *event_ptr; SaHpiResourceIdT event_rid; SaHpiSeverityT event_severity; SaHpiTimeT event_time; Str2EventInfoT *strhash_data; struct oh_handler_state *handle = (struct oh_handler_state *)hnd; struct snmp_rsa_hnd *custom_handle = (struct snmp_rsa_hnd *)handle->data; GHashTable *event2hpi_hash = custom_handle->event2hpi_hash_ptr; memset(&working, 0, sizeof(SaHpiEventT)); is_recovery_event = is_threshold_event = 0; /* Parse RSA error log entry into its various components */ if (snmp_rsa_parse_sel_entry(handle, logstr, &log_entry)) { dbg("Couldn't parse RSA error log entry=%s", logstr); return -1; } /* Find default RID and RSA resource info for error log's source */ if (rsasrc2rid(hnd, log_entry.source, &resinfo)) { dbg("Cannot translate RSA Source string=%s to RID\n", log_entry.source); return -1; } /* Set dynamic event fields with default values from the error log string These can be overwritten in the code below */ event_rid = resinfo.rid; event_time = (SaHpiTimeT)mktime(&log_entry.time) * 1000000000; event_severity = log_entry.sev; /* Assume event is enabled; unless we find out differently below */ *event_enabled = 1; /****************************************************************** * Find event search string * * For some types of events (e.g. thresholds), RSA appends dynamic * data which cannot be in the static str2event hash table. Need to * find the non-dynamic root of these strings. ******************************************************************/ /* Set default search string */ strncpy(search_str, log_entry.text, RSA_SEL_ENTRY_STRING); /* Discover Recovery event strings */ recovery_str = strstr(search_str, EVT_RECOVERY); if (recovery_str && (recovery_str == search_str)) { is_recovery_event = 1; memset(search_str, 0, RSA_SEL_ENTRY_STRING); strcpy(search_str, (log_entry.text + strlen(EVT_RECOVERY))); } /* Adjust login event strings - strip username */ login_str = strstr(log_entry.text, LOG_LOGIN_STRING); if (login_str) { gchar *id_str = strstr(log_entry.text, LOG_LOGIN_CHAR); if (id_str != NULL) { memset(search_str, 0, RSA_SEL_ENTRY_STRING); strncpy(search_str, log_entry.text, (id_str - log_entry.text)); search_str[(id_str - log_entry.text)] = '\0'; } } /* Adjust threshold event strings */ if (strstr(log_entry.text, LOG_THRESHOLD_VALUE_STRING)) { is_threshold_event = 1; if (parse_threshold_str(log_entry.text, search_str, thresh_read_value, thresh_trigger_value)) { dbg("Cannot parse threshold event string=%s\n", log_entry.text); strncpy(search_str, log_entry.text, RSA_SEL_ENTRY_STRING); } } /* See if adjusted search string is a recognized RSA "alertable" event */ strhash_data = (Str2EventInfoT *)g_hash_table_lookup(rsa_str2event_hash, search_str); if (strhash_data) { /* Handle strings that have multiple event numbers */ int dupovrovr = 0; if (strhash_data->event_dup) { strhash_data = findevent4dupstr(search_str, strhash_data, &resinfo); if (strhash_data == NULL) { dbg("Could not find valid event for duplicate string=%s and RID=%d", search_str, resinfo.rid); if (map2oem(&working, &log_entry, EVENT_NOT_MAPPED)) { dbg("Cannot map to OEM Event %s", log_entry.text); return -1; } goto DONE; } if (strhash_data->event_ovr & OVR_RID) { dbg("Cannot have RID override on duplicate string=%s", search_str); dupovrovr = 1; } } /* If OVR_SEV, use RSA-level severity calculated in off-line scripts */ if (strhash_data->event_ovr & OVR_SEV) { event_severity = strhash_data->event_sev; } /* Look to see if event is mapped to an HPI entity */ event_ptr = (SaHpiEventT *)g_hash_table_lookup(event2hpi_hash, strhash_data->event); if (event_ptr) { /* Set static event data defined during resource discovery */ working = *event_ptr; /* If OVR_RID, use rid from rsa_resources.c (unless dup strings have OVR_RID set incorrectly) */ if ((strhash_data->event_ovr & OVR_RID) && !dupovrovr) { event_rid = event_ptr->Source; } else { working.Source = event_rid; /* Restore error log's RID */ } /* Handle sensor events */ if (working.EventType == SAHPI_ET_SENSOR) { /* ??? Should we read sensors on recovery events * ??? to determine the real state of the sensor. * ??? Currently recovery state is hardcoded in bc_resources.c */ if (is_recovery_event) { working.EventDataUnion.SensorEvent.Assertion = SAHPI_FALSE; } /* Set sensor's current/last state; see if sensor's events are disabled */ if (set_previous_event_state(hnd, &working, is_recovery_event, event_enabled)) { dbg("Cannot set previous state for sensor event = %s\n", log_entry.text); return -1; } if (!(*event_enabled)) { return 0; } /* Convert threshold strings into event values */ if (is_threshold_event) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -