ipmi plugin: Add SELSensor and SELIgnoreSelected config options.
authorMariusz Szafranski <mariuszx.szafranski@intel.com>
Thu, 17 May 2018 12:19:37 +0000 (13:19 +0100)
committerMariusz Szafranski <mariuszx.szafranski@intel.com>
Fri, 18 May 2018 09:23:53 +0000 (10:23 +0100)
Functionality is similar to existing options 'Sensor' and 'IgnoreSelected',
which are used now for filtering metrics. New options will allow independent
filtering of SEL events.

Change-Id: I0fde54a25577e61a4c90a4ff52f62117540a4343
Signed-off-by: Mariusz Szafranski <mariuszx.szafranski@intel.com>
src/collectd.conf.in
src/collectd.conf.pod
src/ipmi.c

index 14e8e98..da33dbf 100644 (file)
 #              NotifySensorNotPresent false
 #              NotifyIPMIConnectionState false
 #              SELEnabled false
+#              SELSensor "some_sensor"
+#              SELSensor "another_one"
+#              SELIgnoreSelected false
 #              SELClearEvent false
 #      </Instance>
 #      <Instance "remote">
 #              NotifySensorNotPresent false
 #              NotifyIPMIConnectionState false
 #              SELEnabled false
+#              SELSensor "some_sensor"
+#              SELSensor "another_one"
+#              SELIgnoreSelected false
 #              SELClearEvent false
 #      </Instance>
 #</Plugin>
index ef79f88..dda3a18 100644 (file)
@@ -3453,8 +3453,23 @@ a notification is sent. Defaults to B<false>.
 
 If system event log (SEL) is enabled, plugin will listen for sensor threshold
 and discrete events. When event is received the notification is sent.
+SEL event filtering can be configured using B<SELSensor> and B<SELIgnoreSelected>
+config options.
 Defaults to B<false>.
 
+=item B<SELSensor> I<SELSensor>
+
+Selects sensors to get events from or to ignore, depending on B<SELIgnoreSelected>.
+
+See F</"IGNORELISTS"> for details.
+
+=item B<SELIgnoreSelected> I<true>|I<false>
+
+If no configuration is given, the B<ipmi> plugin will pass events from all
+sensors. This option enables you to do that: By setting B<SELIgnoreSelected>
+to I<true> the effect of B<SELSensor> is inverted: All events from selected
+sensors are ignored and all events from other sensors are passed.
+
 =item B<SELClearEvent> I<true>|I<false>
 
 If SEL clear event is enabled, plugin will delete event from SEL list after
index 67fd949..2642f64 100644 (file)
@@ -49,6 +49,7 @@ typedef struct c_ipmi_sensor_list_s c_ipmi_sensor_list_t;
 struct c_ipmi_instance_s {
   char *name;
   ignorelist_t *ignorelist;
+  ignorelist_t *sel_ignorelist;
   bool notify_add;
   bool notify_remove;
   bool notify_notpresent;
@@ -770,6 +771,40 @@ static int sensor_discrete_event_handler(ipmi_sensor_t *sensor,
   return IPMI_EVENT_NOT_HANDLED;
 } /* int sensor_discrete_event_handler */
 
+static int sel_list_add(c_ipmi_instance_t *st, ipmi_sensor_t *sensor) {
+  char sensor_name[DATA_MAX_NAME_LEN] = {0};
+  int status = 0;
+
+  /* Check if sensor on sel_ignorelist */
+  sensor_get_name(sensor, sensor_name, sizeof(sensor_name));
+  if (ignorelist_match(st->sel_ignorelist, sensor_name) != 0)
+    return 0;
+
+  /* register threshold event if threshold sensor support events */
+  if (ipmi_sensor_get_event_reading_type(sensor) ==
+      IPMI_EVENT_READING_TYPE_THRESHOLD)
+    status = ipmi_sensor_add_threshold_event_handler(
+        sensor, sensor_threshold_event_handler, st);
+  /* register discrete handler if discrete/specific sensor support events */
+  else if (ipmi_sensor_get_event_support(sensor) != IPMI_EVENT_SUPPORT_NONE)
+    status = ipmi_sensor_add_discrete_event_handler(
+        sensor, sensor_discrete_event_handler, st);
+
+  if (status)
+    ERROR("Unable to add sensor %s event handler, status: %d", sensor_name,
+          status);
+  return status;
+}
+
+static void sel_list_remove(c_ipmi_instance_t *st, ipmi_sensor_t *sensor) {
+  if (ipmi_sensor_get_event_reading_type(sensor) ==
+      IPMI_EVENT_READING_TYPE_THRESHOLD)
+    ipmi_sensor_remove_threshold_event_handler(
+        sensor, sensor_threshold_event_handler, st);
+  else
+    ipmi_sensor_remove_discrete_event_handler(
+        sensor, sensor_discrete_event_handler, st);
+}
 /*
  * Entity handlers
  */
@@ -782,37 +817,12 @@ entity_sensor_update_handler(enum ipmi_update_e op,
   if ((op == IPMI_ADDED) || (op == IPMI_CHANGED)) {
     /* Will check for duplicate entries.. */
     sensor_list_add(st, sensor);
-
-    if (st->sel_enabled) {
-      int status = 0;
-      /* register threshold event handler */
-      if (ipmi_sensor_get_event_reading_type(sensor) ==
-          IPMI_EVENT_READING_TYPE_THRESHOLD)
-        status = ipmi_sensor_add_threshold_event_handler(
-            sensor, sensor_threshold_event_handler, st);
-      /* register discrete handler if discrete/specific sensor support events */
-      else if (ipmi_sensor_get_event_support(sensor) != IPMI_EVENT_SUPPORT_NONE)
-        status = ipmi_sensor_add_discrete_event_handler(
-            sensor, sensor_discrete_event_handler, st);
-
-      if (status) {
-        char buf[DATA_MAX_NAME_LEN] = {0};
-        sensor_get_name(sensor, buf, sizeof(buf));
-        ERROR("Unable to add sensor %s event handler, status: %d", buf, status);
-      }
-    }
+    if (st->sel_enabled)
+      sel_list_add(st, sensor);
   } else if (op == IPMI_DELETED) {
     sensor_list_remove(st, sensor);
-
-    if (st->sel_enabled) {
-      if (ipmi_sensor_get_event_reading_type(sensor) ==
-          IPMI_EVENT_READING_TYPE_THRESHOLD)
-        ipmi_sensor_remove_threshold_event_handler(
-            sensor, sensor_threshold_event_handler, st);
-      else
-        ipmi_sensor_remove_discrete_event_handler(
-            sensor, sensor_discrete_event_handler, st);
-    }
+    if (st->sel_enabled)
+      sel_list_remove(st, sensor);
   }
 } /* void entity_sensor_update_handler */
 
@@ -1000,6 +1010,15 @@ static c_ipmi_instance_t *c_ipmi_init_instance() {
     return NULL;
   }
 
+  st->sel_ignorelist = ignorelist_create(/* invert = */ 1);
+  if (st->sel_ignorelist == NULL) {
+    ignorelist_free(st->ignorelist);
+    sfree(st->name);
+    sfree(st);
+    ERROR("ipmi plugin: SEL ignorelist_create() failed.");
+    return NULL;
+  }
+
   st->sensor_list = NULL;
   pthread_mutex_init(&st->sensor_list_lock, /* attr = */ NULL);
 
@@ -1026,6 +1045,7 @@ static void c_ipmi_free_instance(c_ipmi_instance_t *st) {
   sfree(st->username);
   sfree(st->password);
 
+  ignorelist_free(st->sel_ignorelist);
   ignorelist_free(st->ignorelist);
   pthread_mutex_destroy(&st->sensor_list_lock);
   sfree(st);
@@ -1083,6 +1103,19 @@ static int c_ipmi_config_add_instance(oconfig_item_t *ci) {
       status = cf_util_get_boolean(child, &st->notify_remove);
     } else if (strcasecmp("NotifySensorNotPresent", child->key) == 0) {
       status = cf_util_get_boolean(child, &st->notify_notpresent);
+    } else if (strcasecmp("SELSensor", child->key) == 0) {
+      char *value = NULL;
+      status = cf_util_get_string(child, &value);
+      if (status != 0)
+        break;
+      ignorelist_add(st->sel_ignorelist, value);
+      sfree(value);
+    } else if (strcasecmp("SELIgnoreSelected", child->key) == 0) {
+      bool t;
+      status = cf_util_get_boolean(child, &t);
+      if (status != 0)
+        break;
+      ignorelist_set_invert(st->sel_ignorelist, /* invert = */ !t);
     } else if (strcasecmp("SELEnabled", child->key) == 0) {
       status = cf_util_get_boolean(child, &st->sel_enabled);
     } else if (strcasecmp("SELClearEvent", child->key) == 0) {