static int _ipmi_monitoring_sel_parse_timestamped_oem_record (ipmi_monitoring_ctx_t c, struct ipmi_monitoring_sel_record *s) { uint32_t timestamp; uint32_t manufacturer_id; int ret; assert (c); assert (c->magic == IPMI_MONITORING_MAGIC); assert (s); if (ipmi_sel_parse_read_timestamp (c->sel_parse_ctx, NULL, 0, ×tamp) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_timestamp: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); return (-1); } s->timestamp = timestamp; if (ipmi_sel_parse_read_manufacturer_id (c->sel_parse_ctx, NULL, 0, &manufacturer_id) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_manufacturer_id: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); return (-1); } s->manufacturer_id = manufacturer_id; if ((ret = ipmi_sel_parse_read_oem (c->sel_parse_ctx, NULL, 0, s->oem_data, IPMI_MONITORING_OEM_DATA_MAX)) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_oem: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); return (-1); } s->oem_data_len = ret; return (0); }
static int _ipmi_monitoring_sel_parse_non_timestamped_oem_record (ipmi_monitoring_ctx_t c, struct ipmi_monitoring_sel_record *s) { int ret; assert (c); assert (c->magic == IPMI_MONITORING_MAGIC); assert (s); if ((ret = ipmi_sel_parse_read_oem (c->sel_parse_ctx, NULL, 0, s->oem_data, IPMI_MONITORING_OEM_DATA_MAX)) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_oem: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); return (-1); } s->oem_data_len = ret; return (0); }
static void _sel_parse_ctx_error_convert (ipmi_monitoring_ctx_t c) { int errnum; assert (c); assert (c->magic == IPMI_MONITORING_MAGIC); assert (c->ipmi_ctx); assert (c->sel_parse_ctx); errnum = ipmi_sel_ctx_errnum (c->sel_parse_ctx); /* if callback error - assume we set as needed */ if (errnum != IPMI_SEL_ERR_CALLBACK_ERROR) { if (errnum == IPMI_SEL_ERR_IPMI_ERROR) c->errnum = IPMI_MONITORING_ERR_IPMI_ERROR; else if (errnum == IPMI_SEL_ERR_OUT_OF_MEMORY) c->errnum = IPMI_MONITORING_ERR_OUT_OF_MEMORY; else if (errnum == IPMI_SEL_ERR_SYSTEM_ERROR) c->errnum = IPMI_MONITORING_ERR_SYSTEM_ERROR; else c->errnum = IPMI_MONITORING_ERR_INTERNAL_ERROR; } }
/* return -1 on failout error, 0 on invalid data */ static int _sel_parse_err_handle (pstdout_state_t pstate, ipmi_sel_ctx_t sel_ctx, int debug, const char *func) { assert (sel_ctx); assert (func); if (ipmi_sel_ctx_errnum (sel_ctx) == IPMI_SEL_ERR_INVALID_SEL_ENTRY) { /* most likely bad event data from remote system or user input */ if (debug) PSTDOUT_FPRINTF (pstate, stderr, "Invalid data\n"); return (0); } PSTDOUT_FPRINTF (pstate, stderr, "%s: %s\n", func, ipmi_sel_ctx_errormsg (sel_ctx)); return (-1); }
static int _ipmi_monitoring_sel_parse_date_range (ipmi_sel_ctx_t ctx, void *callback_data) { struct sel_parse_data *spd; uint8_t record_type; int record_type_class; assert (ctx); assert (callback_data); spd = (struct sel_parse_data *)callback_data; if (ipmi_sel_parse_read_record_type (spd->c->sel_parse_ctx, NULL, 0, &record_type) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_record_id: %s", ipmi_sel_ctx_errnum (spd->c->sel_parse_ctx))); _sel_parse_ctx_error_convert (spd->c); return (-1); } /* IPMI Workaround * * HP DL 380 G5 * * Motherboard is reporting SEL Records of record type 0x00, which * is not a valid record type. */ if (spd->sel_flags & IPMI_MONITORING_SEL_FLAGS_ASSUME_SYSTEM_EVENT_RECORD && !IPMI_SEL_RECORD_TYPE_VALID (record_type)) record_type = IPMI_SEL_RECORD_TYPE_SYSTEM_EVENT_RECORD; record_type_class = ipmi_sel_record_type_class (record_type); if (record_type_class == IPMI_SEL_RECORD_TYPE_CLASS_SYSTEM_EVENT_RECORD || record_type_class == IPMI_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD) { uint32_t timestamp; if (ipmi_sel_parse_read_timestamp (spd->c->sel_parse_ctx, NULL, 0, ×tamp) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_timestamp: %s", ipmi_sel_ctx_errnum (spd->c->sel_parse_ctx))); _sel_parse_ctx_error_convert (spd->c); return (-1); } if (timestamp >= spd->date_begin && timestamp <= spd->date_end) { if (_store_sel_record (spd->c, spd->sel_flags) < 0) return (-1); } } return (0); }
static int _ipmi_monitoring_sel_parse_sensor_types (ipmi_sel_ctx_t ctx, void *callback_data) { struct sel_parse_data *spd; uint8_t record_type; int record_type_class; assert (ctx); assert (callback_data); spd = (struct sel_parse_data *)callback_data; if (ipmi_sel_parse_read_record_type (spd->c->sel_parse_ctx, NULL, 0, &record_type) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_record_id: %s", ipmi_sel_ctx_errnum (spd->c->sel_parse_ctx))); _sel_parse_ctx_error_convert (spd->c); return (-1); } /* IPMI Workaround * * HP DL 380 G5 * * Motherboard is reporting SEL Records of record type 0x00, which * is not a valid record type. */ if (spd->sel_flags & IPMI_MONITORING_SEL_FLAGS_ASSUME_SYSTEM_EVENT_RECORD && !IPMI_SEL_RECORD_TYPE_VALID (record_type)) record_type = IPMI_SEL_RECORD_TYPE_SYSTEM_EVENT_RECORD; record_type_class = ipmi_sel_record_type_class (record_type); if (record_type_class == IPMI_SEL_RECORD_TYPE_CLASS_SYSTEM_EVENT_RECORD) { uint8_t sel_sensor_type; unsigned int i; int sensor_type; int found = 0; if (ipmi_sel_parse_read_sensor_type (spd->c->sel_parse_ctx, NULL, 0, &sel_sensor_type) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_sensor_type: %s", ipmi_sel_ctx_errnum (spd->c->sel_parse_ctx))); _sel_parse_ctx_error_convert (spd->c); return (-1); } if ((sensor_type = ipmi_monitoring_get_sensor_type (spd->c, sel_sensor_type)) < 0) return (-1); for (i = 0; i < spd->sensor_types_len; i++) { if (spd->sensor_types[i] == sensor_type) { found++; break; } } if (found) { if (_store_sel_record (spd->c, spd->sel_flags) < 0) return (-1); } } return (0); }
static int _store_sel_record (ipmi_monitoring_ctx_t c, unsigned int sel_flags) { struct ipmi_monitoring_sel_record *s = NULL; uint8_t sel_record[IPMI_SEL_RECORD_MAX_RECORD_LENGTH]; int sel_record_len; uint16_t record_id; uint8_t record_type; int record_type_class; unsigned int sel_state; assert (c); assert (c->magic == IPMI_MONITORING_MAGIC); assert (c->sel_records); if (!(s = (struct ipmi_monitoring_sel_record *)malloc (sizeof (struct ipmi_monitoring_sel_record)))) { IPMI_MONITORING_DEBUG (("malloc: %s", strerror (errno))); c->errnum = IPMI_MONITORING_ERR_OUT_OF_MEMORY; goto cleanup; } memset (s, '\0', sizeof (struct ipmi_monitoring_sel_record)); if ((sel_record_len = ipmi_sel_parse_read_record (c->sel_parse_ctx, sel_record, IPMI_SEL_RECORD_MAX_RECORD_LENGTH)) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_record: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); goto cleanup; } if (ipmi_sel_parse_read_record_id (c->sel_parse_ctx, NULL, 0, &record_id) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_record_id: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); goto cleanup; } if (ipmi_sel_parse_read_record_type (c->sel_parse_ctx, NULL, 0, &record_type) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_record_id: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); goto cleanup; } /* IPMI Workaround * * HP DL 380 G5 * * Motherboard is reporting SEL Records of record type 0x00, which * is not a valid record type. */ if (sel_flags & IPMI_MONITORING_SEL_FLAGS_ASSUME_SYSTEM_EVENT_RECORD && !IPMI_SEL_RECORD_TYPE_VALID (record_type)) record_type = IPMI_SEL_RECORD_TYPE_SYSTEM_EVENT_RECORD; s->record_id = record_id; s->record_type = record_type; if (ipmi_interpret_sel (c->interpret_ctx, sel_record, sel_record_len, &sel_state) < 0) { IPMI_MONITORING_DEBUG (("ipmi_interpret_sel: %s", ipmi_interpret_ctx_errormsg (c->interpret_ctx))); c->errnum = IPMI_MONITORING_ERR_INTERNAL_ERROR; goto cleanup; } if (sel_state == IPMI_INTERPRET_STATE_NOMINAL) s->sel_state = IPMI_MONITORING_STATE_NOMINAL; else if (sel_state == IPMI_INTERPRET_STATE_WARNING) s->sel_state = IPMI_MONITORING_STATE_WARNING; else if (sel_state == IPMI_INTERPRET_STATE_CRITICAL) s->sel_state = IPMI_MONITORING_STATE_CRITICAL; else if (sel_state == IPMI_INTERPRET_STATE_UNKNOWN) s->sel_state = IPMI_MONITORING_STATE_UNKNOWN; record_type_class = ipmi_sel_record_type_class (record_type); if (record_type_class == IPMI_SEL_RECORD_TYPE_CLASS_SYSTEM_EVENT_RECORD) { s->record_type_class = IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_SYSTEM_EVENT_RECORD; if (_ipmi_monitoring_sel_parse_system_event_record (c, s, sel_flags) < 0) goto cleanup; } else if (record_type_class == IPMI_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD) { s->record_type_class = IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD; if (_ipmi_monitoring_sel_parse_timestamped_oem_record (c, s) < 0) goto cleanup; } else if (record_type_class == IPMI_SEL_RECORD_TYPE_CLASS_NON_TIMESTAMPED_OEM_RECORD) { s->record_type_class = IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_NON_TIMESTAMPED_OEM_RECORD; if (_ipmi_monitoring_sel_parse_non_timestamped_oem_record (c, s) < 0) goto cleanup; } else s->record_type_class = IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_UNKNOWN; /* achu: should come before list_append to avoid having a freed entry on the list */ if (c->callback) { c->callback_sel_record = s; if ((*c->callback)(c, c->callback_data) < 0) { IPMI_MONITORING_DEBUG (("callback error")); c->errnum = IPMI_MONITORING_ERR_CALLBACK_ERROR; goto cleanup; } } if (!list_append (c->sel_records, s)) { IPMI_MONITORING_DEBUG (("list_append: %s", strerror (errno))); c->errnum = IPMI_MONITORING_ERR_INTERNAL_ERROR; goto cleanup; } return (0); cleanup: if (s) { free (s->event_offset_string); free (s); } return (-1); }
static int _ipmi_monitoring_sel_parse_system_event_record (ipmi_monitoring_ctx_t c, struct ipmi_monitoring_sel_record *s, unsigned int sel_flags) { uint32_t timestamp; uint8_t sel_sensor_type; uint8_t sensor_number; uint8_t event_direction; uint8_t event_offset; uint8_t event_type_code; uint8_t event_data1; uint8_t event_data2; uint8_t event_data3; char event_offset_string[IPMI_MONITORING_SEL_EVENT_OFFSET_STRING_MAX + 1]; int sensor_type; unsigned int sel_string_flags; int ret; assert (c); assert (c->magic == IPMI_MONITORING_MAGIC); assert (s); if (ipmi_sel_parse_read_timestamp (c->sel_parse_ctx, NULL, 0, ×tamp) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_timestamp: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); return (-1); } s->timestamp = timestamp; if (ipmi_sel_parse_read_sensor_type (c->sel_parse_ctx, NULL, 0, &sel_sensor_type) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_sensor_type: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); return (-1); } if ((sensor_type = ipmi_monitoring_get_sensor_type (c, sel_sensor_type)) < 0) return (-1); s->sensor_type = sensor_type; if (ipmi_sel_parse_read_sensor_number (c->sel_parse_ctx, NULL, 0, &sensor_number) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_sensor_number: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); return (-1); } s->sensor_number = sensor_number; if (ipmi_sel_parse_read_event_direction (c->sel_parse_ctx, NULL, 0, &event_direction) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_event_direction: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); return (-1); } if (event_direction == IPMI_SEL_RECORD_ASSERTION_EVENT) s->event_direction = IPMI_MONITORING_SEL_EVENT_DIRECTION_ASSERTION; else s->event_direction = IPMI_MONITORING_SEL_EVENT_DIRECTION_DEASSERTION; if (ipmi_sel_parse_read_event_data1_offset_from_event_reading_type_code (c->sel_parse_ctx, NULL, 0, &event_offset) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_event_data1_offset_from_event_reading_type_code: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); return (-1); } s->event_offset = event_offset; if (ipmi_sel_parse_read_event_type_code (c->sel_parse_ctx, NULL, 0, &event_type_code) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_event_type_code: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); return (-1); } s->event_type_code = event_type_code; if ((s->event_offset_type = _get_event_offset_type (c, event_type_code, sel_sensor_type)) < 0) return (-1); if (ipmi_sel_parse_read_event_data1 (c->sel_parse_ctx, NULL, 0, &event_data1) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_event_data1: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); return (-1); } s->event_data1 = event_data1; if (ipmi_sel_parse_read_event_data2 (c->sel_parse_ctx, NULL, 0, &event_data2) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_event_data2: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); return (-1); } s->event_data2 = event_data2; if (ipmi_sel_parse_read_event_data3 (c->sel_parse_ctx, NULL, 0, &event_data3) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_event_data3: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); return (-1); } s->event_data3 = event_data3; sel_string_flags = IPMI_SEL_STRING_FLAGS_IGNORE_UNAVAILABLE_FIELD | IPMI_SEL_STRING_FLAGS_OUTPUT_NOT_AVAILABLE; if (sel_flags & IPMI_MONITORING_SEL_FLAGS_ENTITY_SENSOR_NAMES) sel_string_flags |= IPMI_SEL_STRING_FLAGS_ENTITY_SENSOR_NAMES; if (ipmi_sel_parse_read_record_string (c->sel_parse_ctx, "%s", NULL, 0, s->sensor_name, IPMI_MONITORING_MAX_SENSOR_NAME_LENGTH, sel_string_flags) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_record_string: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); return (-1); } memset (event_offset_string, '\0', IPMI_MONITORING_SEL_EVENT_OFFSET_STRING_MAX + 1); sel_string_flags = IPMI_SEL_STRING_FLAGS_IGNORE_UNAVAILABLE_FIELD | IPMI_SEL_STRING_FLAGS_OUTPUT_NOT_AVAILABLE; if ((ret = ipmi_sel_parse_read_record_string (c->sel_parse_ctx, "%e", NULL, 0, event_offset_string, IPMI_MONITORING_SEL_EVENT_OFFSET_STRING_MAX, sel_string_flags)) < 0) { IPMI_MONITORING_DEBUG (("ipmi_sel_parse_read_record_string: %s", ipmi_sel_ctx_errnum (c->sel_parse_ctx))); _sel_parse_ctx_error_convert (c); return (-1); } if (ret) { if (!(s->event_offset_string = strdup (event_offset_string))) { IPMI_MONITORING_DEBUG (("strdup: %s", strerror (errno))); c->errnum = IPMI_MONITORING_ERR_OUT_OF_MEMORY; return (-1); } } else { /* return empty string */ if (!(s->event_offset_string = strdup (""))) { IPMI_MONITORING_DEBUG (("strdup: %s", strerror (errno))); c->errnum = IPMI_MONITORING_ERR_OUT_OF_MEMORY; return (-1); } } return (0); }