X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fipmi.c;h=0b79823d50a13c1d497b540fc1c343c3e308779f;hb=b72d521340383b6418fa6a75faca3bc45f06b14a;hp=7ae54a01825da420369a6ff9f6326d1e9d20197a;hpb=de235d849bf5c9d6d2b7438adcb7ed18bf46b3d1;p=collectd.git diff --git a/src/ipmi.c b/src/ipmi.c index 7ae54a01..0b79823d 100644 --- a/src/ipmi.c +++ b/src/ipmi.c @@ -1,6 +1,7 @@ /** * collectd - src/ipmi.c * Copyright (C) 2008 Florian octo Forster + * Copyright (C) 2008 Peter Holik * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -17,6 +18,7 @@ * * Authors: * Florian octo Forster + * Peter Holik **/ #include "collectd.h" @@ -43,6 +45,7 @@ struct c_ipmi_sensor_list_s ipmi_sensor_id_t sensor_id; char sensor_name[DATA_MAX_NAME_LEN]; char sensor_type[DATA_MAX_NAME_LEN]; + int sensor_not_present; c_ipmi_sensor_list_t *next; }; @@ -52,18 +55,26 @@ struct c_ipmi_sensor_list_s static pthread_mutex_t sensor_list_lock = PTHREAD_MUTEX_INITIALIZER; static c_ipmi_sensor_list_t *sensor_list = NULL; +static int c_ipmi_init_in_progress = 0; static int c_ipmi_active = 0; static pthread_t thread_id = (pthread_t) 0; static const char *config_keys[] = { "Sensor", - "IgnoreSelected" + "IgnoreSelected", + "NotifySensorAdd", + "NotifySensorRemove", + "NotifySensorNotPresent" }; static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); static ignorelist_t *ignorelist = NULL; +static int c_ipmi_nofiy_add = 0; +static int c_ipmi_nofiy_remove = 0; +static int c_ipmi_nofiy_notpresent = 0; + /* * Misc private functions */ @@ -100,9 +111,9 @@ static int sensor_list_remove (ipmi_sensor_t *sensor); static void sensor_read_handler (ipmi_sensor_t *sensor, int err, enum ipmi_value_present_e value_present, - unsigned int raw_value, + unsigned int __attribute__((unused)) raw_value, double value, - ipmi_states_t *states, + ipmi_states_t __attribute__((unused)) *states, void *user_data) { value_t values[1]; @@ -112,12 +123,84 @@ static void sensor_read_handler (ipmi_sensor_t *sensor, if (err != 0) { - INFO ("ipmi plugin: sensor_read_handler: Removing sensor %s, " - "because it failed with status %#x.", - list_item->sensor_name, err); - sensor_list_remove (sensor); + if ((err & 0xff) == IPMI_NOT_PRESENT_CC) + { + if (list_item->sensor_not_present == 0) + { + list_item->sensor_not_present = 1; + + INFO ("ipmi plugin: sensor_read_handler: sensor %s " + "not present.", list_item->sensor_name); + + if (c_ipmi_nofiy_notpresent) + { + notification_t n = { NOTIF_WARNING, time(NULL), "", "", "ipmi", + "", "", "", NULL }; + + sstrncpy (n.host, hostname_g, sizeof (n.host)); + sstrncpy (n.type_instance, list_item->sensor_name, + sizeof (n.type_instance)); + sstrncpy (n.type, list_item->sensor_type, sizeof (n.type)); + ssnprintf (n.message, sizeof (n.message), + "sensor %s not present", list_item->sensor_name); + + plugin_dispatch_notification (&n); + } + } + } + else if (IPMI_IS_IPMI_ERR(err) && IPMI_GET_IPMI_ERR(err) == IPMI_NOT_SUPPORTED_IN_PRESENT_STATE_CC) + { + INFO ("ipmi plugin: sensor_read_handler: Sensor %s not ready", + list_item->sensor_name); + } + else + { + if (IPMI_IS_IPMI_ERR(err)) + INFO ("ipmi plugin: sensor_read_handler: Removing sensor %s, " + "because it failed with IPMI error %#x.", + list_item->sensor_name, IPMI_GET_IPMI_ERR(err)); + else if (IPMI_IS_OS_ERR(err)) + INFO ("ipmi plugin: sensor_read_handler: Removing sensor %s, " + "because it failed with OS error %#x.", + list_item->sensor_name, IPMI_GET_OS_ERR(err)); + else if (IPMI_IS_RMCPP_ERR(err)) + INFO ("ipmi plugin: sensor_read_handler: Removing sensor %s, " + "because it failed with RMCPP error %#x.", + list_item->sensor_name, IPMI_GET_RMCPP_ERR(err)); + else if (IPMI_IS_SOL_ERR(err)) + INFO ("ipmi plugin: sensor_read_handler: Removing sensor %s, " + "because it failed with RMCPP error %#x.", + list_item->sensor_name, IPMI_GET_SOL_ERR(err)); + else + INFO ("ipmi plugin: sensor_read_handler: Removing sensor %s, " + "because it failed with error %#x. of class %#x", + list_item->sensor_name, err & 0xff, err & 0xffffff00); + sensor_list_remove (sensor); + } return; } + else if (list_item->sensor_not_present == 1) + { + list_item->sensor_not_present = 0; + + INFO ("ipmi plugin: sensor_read_handler: sensor %s present.", + list_item->sensor_name); + + if (c_ipmi_nofiy_notpresent) + { + notification_t n = { NOTIF_OKAY, time(NULL), "", "", "ipmi", + "", "", "", NULL }; + + sstrncpy (n.host, hostname_g, sizeof (n.host)); + sstrncpy (n.type_instance, list_item->sensor_name, + sizeof (n.type_instance)); + sstrncpy (n.type, list_item->sensor_type, sizeof (n.type)); + ssnprintf (n.message, sizeof (n.message), + "sensor %s present", list_item->sensor_name); + + plugin_dispatch_notification (&n); + } + } if (value_present != IPMI_BOTH_VALUES_PRESENT) { @@ -136,7 +219,6 @@ static void sensor_read_handler (ipmi_sensor_t *sensor, vl.values = values; vl.values_len = 1; - vl.time = time (NULL); sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "ipmi", sizeof (vl.plugin)); @@ -258,6 +340,21 @@ static int sensor_list_add (ipmi_sensor_t *sensor) pthread_mutex_unlock (&sensor_list_lock); + if (c_ipmi_nofiy_add && (c_ipmi_init_in_progress == 0)) + { + notification_t n = { NOTIF_OKAY, time(NULL), "", "", "ipmi", + "", "", "", NULL }; + + sstrncpy (n.host, hostname_g, sizeof (n.host)); + sstrncpy (n.type_instance, list_item->sensor_name, + sizeof (n.type_instance)); + sstrncpy (n.type, list_item->sensor_type, sizeof (n.type)); + ssnprintf (n.message, sizeof (n.message), + "sensor %s added", list_item->sensor_name); + + plugin_dispatch_notification (&n); + } + return (0); } /* int sensor_list_add */ @@ -297,6 +394,21 @@ static int sensor_list_remove (ipmi_sensor_t *sensor) pthread_mutex_unlock (&sensor_list_lock); + if (c_ipmi_nofiy_remove && c_ipmi_active) + { + notification_t n = { NOTIF_WARNING, time(NULL), "", "", + "ipmi", "", "", "", NULL }; + + sstrncpy (n.host, hostname_g, sizeof (n.host)); + sstrncpy (n.type_instance, list_item->sensor_name, + sizeof (n.type_instance)); + sstrncpy (n.type, list_item->sensor_type, sizeof (n.type)); + ssnprintf (n.message, sizeof (n.message), + "sensor %s removed", list_item->sensor_name); + + plugin_dispatch_notification (&n); + } + free (list_item); return (0); } /* int sensor_list_remove */ @@ -347,9 +459,9 @@ static int sensor_list_remove_all (void) * Entity handlers */ static void entity_sensor_update_handler (enum ipmi_update_e op, - ipmi_entity_t *entity, + ipmi_entity_t __attribute__((unused)) *entity, ipmi_sensor_t *sensor, - void *user_data) + void __attribute__((unused)) *user_data) { /* TODO: Ignore sensors we cannot read */ @@ -368,9 +480,9 @@ static void entity_sensor_update_handler (enum ipmi_update_e op, * Domain handlers */ static void domain_entity_update_handler (enum ipmi_update_e op, - ipmi_domain_t *domain, + ipmi_domain_t __attribute__((unused)) *domain, ipmi_entity_t *entity, - void *user_data) + void __attribute__((unused)) *user_data) { int status; @@ -403,7 +515,7 @@ static void domain_connection_change_handler (ipmi_domain_t *domain, { int status; - printf ("domain_connection_change_handler (domain = %p, err = %i, " + DEBUG ("domain_connection_change_handler (domain = %p, err = %i, " "conn_num = %u, port_num = %u, still_connected = %i, " "user_data = %p);\n", (void *) domain, err, conn_num, port_num, still_connected, user_data); @@ -462,7 +574,7 @@ static int thread_init (os_handler_t **ret_os_handler) return (0); } /* int thread_init */ -static void *thread_main (void *user_data) +static void *thread_main (void __attribute__((unused)) *user_data) { int status; os_handler_t *os_handler = NULL; @@ -470,7 +582,7 @@ static void *thread_main (void *user_data) status = thread_init (&os_handler); if (status != 0) { - fprintf (stderr, "ipmi plugin: thread_init failed.\n"); + ERROR ("ipmi plugin: thread_init failed.\n"); return ((void *) -1); } @@ -500,11 +612,32 @@ static int c_ipmi_config (const char *key, const char *value) { int invert = 1; if ((strcasecmp ("True", value) == 0) - || (strcasecmp ("Yes", value) == 0) - || (strcasecmp ("On", value) == 0)) + || (strcasecmp ("Yes", value) == 0) + || (strcasecmp ("On", value) == 0)) invert = 0; ignorelist_set_invert (ignorelist, invert); } + else if (strcasecmp ("NotifySensorAdd", key) == 0) + { + if ((strcasecmp ("True", value) == 0) + || (strcasecmp ("Yes", value) == 0) + || (strcasecmp ("On", value) == 0)) + c_ipmi_nofiy_add = 1; + } + else if (strcasecmp ("NotifySensorRemove", key) == 0) + { + if ((strcasecmp ("True", value) == 0) + || (strcasecmp ("Yes", value) == 0) + || (strcasecmp ("On", value) == 0)) + c_ipmi_nofiy_remove = 1; + } + else if (strcasecmp ("NotifySensorNotPresent", key) == 0) + { + if ((strcasecmp ("True", value) == 0) + || (strcasecmp ("Yes", value) == 0) + || (strcasecmp ("On", value) == 0)) + c_ipmi_nofiy_notpresent = 1; + } else { return (-1); @@ -517,6 +650,9 @@ static int c_ipmi_init (void) { int status; + /* Don't send `ADD' notifications during startup (~ 1 minute) */ + c_ipmi_init_in_progress = 1 + (60 / interval_g); + c_ipmi_active = 1; status = pthread_create (&thread_id, /* attr = */ NULL, thread_main, @@ -541,7 +677,12 @@ static int c_ipmi_read (void) } sensor_list_read_all (); - + + if (c_ipmi_init_in_progress > 0) + c_ipmi_init_in_progress--; + else + c_ipmi_init_in_progress = 0; + return (0); } /* int c_ipmi_read */