Fix compile time issues
[collectd.git] / src / threshold.c
index a4a999f..e74dfc2 100644 (file)
@@ -25,9 +25,9 @@
 
 #include "collectd.h"
 
-#include "common.h"
 #include "plugin.h"
-#include "utils_avltree.h"
+#include "utils/avltree/avltree.h"
+#include "utils/common/common.h"
 #include "utils_cache.h"
 #include "utils_threshold.h"
 
@@ -55,20 +55,20 @@ static int ut_threshold_add(const threshold_t *th) { /* {{{ */
   if (format_name(name, sizeof(name), th->host, th->plugin, th->plugin_instance,
                   th->type, th->type_instance) != 0) {
     ERROR("ut_threshold_add: format_name failed.");
-    return (-1);
+    return -1;
   }
 
   name_copy = strdup(name);
   if (name_copy == NULL) {
     ERROR("ut_threshold_add: strdup failed.");
-    return (-1);
+    return -1;
   }
 
   th_copy = malloc(sizeof(*th_copy));
   if (th_copy == NULL) {
     sfree(name_copy);
     ERROR("ut_threshold_add: malloc failed.");
-    return (-1);
+    return -1;
   }
   memcpy(th_copy, th, sizeof(threshold_t));
 
@@ -100,7 +100,7 @@ static int ut_threshold_add(const threshold_t *th) { /* {{{ */
     sfree(th_copy);
   }
 
-  return (status);
+  return status;
 } /* }}} int ut_threshold_add */
 
 /*
@@ -109,90 +109,6 @@ static int ut_threshold_add(const threshold_t *th) { /* {{{ */
  * The following approximately two hundred functions are used to handle the
  * configuration and fill the threshold list.
  * {{{ */
-static int ut_config_type_datasource(threshold_t *th, oconfig_item_t *ci) {
-  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
-    WARNING("threshold values: The `DataSource' option needs exactly one "
-            "string argument.");
-    return (-1);
-  }
-
-  sstrncpy(th->data_source, ci->values[0].value.string,
-           sizeof(th->data_source));
-
-  return (0);
-} /* int ut_config_type_datasource */
-
-static int ut_config_type_instance(threshold_t *th, oconfig_item_t *ci) {
-  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
-    WARNING("threshold values: The `Instance' option needs exactly one "
-            "string argument.");
-    return (-1);
-  }
-
-  sstrncpy(th->type_instance, ci->values[0].value.string,
-           sizeof(th->type_instance));
-
-  return (0);
-} /* int ut_config_type_instance */
-
-static int ut_config_type_max(threshold_t *th, oconfig_item_t *ci) {
-  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) {
-    WARNING("threshold values: The `%s' option needs exactly one "
-            "number argument.",
-            ci->key);
-    return (-1);
-  }
-
-  if (strcasecmp(ci->key, "WarningMax") == 0)
-    th->warning_max = ci->values[0].value.number;
-  else
-    th->failure_max = ci->values[0].value.number;
-
-  return (0);
-} /* int ut_config_type_max */
-
-static int ut_config_type_min(threshold_t *th, oconfig_item_t *ci) {
-  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) {
-    WARNING("threshold values: The `%s' option needs exactly one "
-            "number argument.",
-            ci->key);
-    return (-1);
-  }
-
-  if (strcasecmp(ci->key, "WarningMin") == 0)
-    th->warning_min = ci->values[0].value.number;
-  else
-    th->failure_min = ci->values[0].value.number;
-
-  return (0);
-} /* int ut_config_type_min */
-
-static int ut_config_type_hits(threshold_t *th, oconfig_item_t *ci) {
-  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) {
-    WARNING("threshold values: The `%s' option needs exactly one "
-            "number argument.",
-            ci->key);
-    return (-1);
-  }
-
-  th->hits = ci->values[0].value.number;
-
-  return (0);
-} /* int ut_config_type_hits */
-
-static int ut_config_type_hysteresis(threshold_t *th, oconfig_item_t *ci) {
-  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) {
-    WARNING("threshold values: The `%s' option needs exactly one "
-            "number argument.",
-            ci->key);
-    return (-1);
-  }
-
-  th->hysteresis = ci->values[0].value.number;
-
-  return (0);
-} /* int ut_config_type_hysteresis */
-
 static int ut_config_type(const threshold_t *th_orig, oconfig_item_t *ci) {
   threshold_t th;
   int status = 0;
@@ -200,12 +116,12 @@ static int ut_config_type(const threshold_t *th_orig, oconfig_item_t *ci) {
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
     WARNING("threshold values: The `Type' block needs exactly one string "
             "argument.");
-    return (-1);
+    return -1;
   }
 
   if (ci->children_num < 1) {
     WARNING("threshold values: The `Type' block needs at least one option.");
-    return (-1);
+    return -1;
   }
 
   memcpy(&th, th_orig, sizeof(th));
@@ -223,15 +139,19 @@ static int ut_config_type(const threshold_t *th_orig, oconfig_item_t *ci) {
     oconfig_item_t *option = ci->children + i;
 
     if (strcasecmp("Instance", option->key) == 0)
-      status = ut_config_type_instance(&th, option);
+      status = cf_util_get_string_buffer(option, th.type_instance,
+                                         sizeof(th.type_instance));
     else if (strcasecmp("DataSource", option->key) == 0)
-      status = ut_config_type_datasource(&th, option);
-    else if ((strcasecmp("WarningMax", option->key) == 0) ||
-             (strcasecmp("FailureMax", option->key) == 0))
-      status = ut_config_type_max(&th, option);
-    else if ((strcasecmp("WarningMin", option->key) == 0) ||
-             (strcasecmp("FailureMin", option->key) == 0))
-      status = ut_config_type_min(&th, option);
+      status = cf_util_get_string_buffer(option, th.data_source,
+                                         sizeof(th.data_source));
+    else if (strcasecmp("WarningMax", option->key) == 0)
+      status = cf_util_get_double(option, &th.warning_max);
+    else if (strcasecmp("FailureMax", option->key) == 0)
+      status = cf_util_get_double(option, &th.failure_max);
+    else if (strcasecmp("WarningMin", option->key) == 0)
+      status = cf_util_get_double(option, &th.warning_min);
+    else if (strcasecmp("FailureMin", option->key) == 0)
+      status = cf_util_get_double(option, &th.failure_min);
     else if (strcasecmp("Interesting", option->key) == 0)
       status = cf_util_get_flag(option, &th.flags, UT_FLAG_INTERESTING);
     else if (strcasecmp("Invert", option->key) == 0)
@@ -243,9 +163,9 @@ static int ut_config_type(const threshold_t *th_orig, oconfig_item_t *ci) {
     else if (strcasecmp("Percentage", option->key) == 0)
       status = cf_util_get_flag(option, &th.flags, UT_FLAG_PERCENTAGE);
     else if (strcasecmp("Hits", option->key) == 0)
-      status = ut_config_type_hits(&th, option);
+      status = cf_util_get_int(option, &th.hits);
     else if (strcasecmp("Hysteresis", option->key) == 0)
-      status = ut_config_type_hysteresis(&th, option);
+      status = cf_util_get_double(option, &th.hysteresis);
     else {
       WARNING("threshold values: Option `%s' not allowed inside a `Type' "
               "block.",
@@ -261,22 +181,9 @@ static int ut_config_type(const threshold_t *th_orig, oconfig_item_t *ci) {
     status = ut_threshold_add(&th);
   }
 
-  return (status);
+  return status;
 } /* int ut_config_type */
 
-static int ut_config_plugin_instance(threshold_t *th, oconfig_item_t *ci) {
-  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
-    WARNING("threshold values: The `Instance' option needs exactly one "
-            "string argument.");
-    return (-1);
-  }
-
-  sstrncpy(th->plugin_instance, ci->values[0].value.string,
-           sizeof(th->plugin_instance));
-
-  return (0);
-} /* int ut_config_plugin_instance */
-
 static int ut_config_plugin(const threshold_t *th_orig, oconfig_item_t *ci) {
   threshold_t th;
   int status = 0;
@@ -284,13 +191,13 @@ static int ut_config_plugin(const threshold_t *th_orig, oconfig_item_t *ci) {
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
     WARNING("threshold values: The `Plugin' block needs exactly one string "
             "argument.");
-    return (-1);
+    return -1;
   }
 
   if (ci->children_num < 1) {
     WARNING("threshold values: The `Plugin' block needs at least one nested "
             "block.");
-    return (-1);
+    return -1;
   }
 
   memcpy(&th, th_orig, sizeof(th));
@@ -302,7 +209,8 @@ static int ut_config_plugin(const threshold_t *th_orig, oconfig_item_t *ci) {
     if (strcasecmp("Type", option->key) == 0)
       status = ut_config_type(&th, option);
     else if (strcasecmp("Instance", option->key) == 0)
-      status = ut_config_plugin_instance(&th, option);
+      status = cf_util_get_string_buffer(option, th.plugin_instance,
+                                         sizeof(th.plugin_instance));
     else {
       WARNING("threshold values: Option `%s' not allowed inside a `Plugin' "
               "block.",
@@ -314,7 +222,7 @@ static int ut_config_plugin(const threshold_t *th_orig, oconfig_item_t *ci) {
       break;
   }
 
-  return (status);
+  return status;
 } /* int ut_config_plugin */
 
 static int ut_config_host(const threshold_t *th_orig, oconfig_item_t *ci) {
@@ -324,13 +232,13 @@ static int ut_config_host(const threshold_t *th_orig, oconfig_item_t *ci) {
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
     WARNING("threshold values: The `Host' block needs exactly one string "
             "argument.");
-    return (-1);
+    return -1;
   }
 
   if (ci->children_num < 1) {
     WARNING("threshold values: The `Host' block needs at least one nested "
             "block.");
-    return (-1);
+    return -1;
   }
 
   memcpy(&th, th_orig, sizeof(th));
@@ -354,11 +262,11 @@ static int ut_config_host(const threshold_t *th_orig, oconfig_item_t *ci) {
       break;
   }
 
-  return (status);
+  return status;
 } /* int ut_config_host */
-  /*
  * End of the functions used to configure threshold values.
  */
+/*
+ * End of the functions used to configure threshold values.
+ */
 /* }}} */
 
 /*
@@ -392,7 +300,7 @@ static int ut_report_state(const data_set_t *ds, const value_list_t *vl,
       DEBUG("ut_report_state: th->hits = %d, uc_get_hits = %d", th->hits,
             uc_get_hits(ds, vl));
       (void)uc_inc_hits(ds, vl, 1); /* increase hit counter */
-      return (0);
+      return 0;
     }
   } /* end check hits */
 
@@ -401,10 +309,13 @@ static int ut_report_state(const data_set_t *ds, const value_list_t *vl,
   /* If the state didn't change, report if `persistent' is specified. If the
    * state is `okay', then only report if `persist_ok` flag is set. */
   if (state == state_old) {
-    if ((th->flags & UT_FLAG_PERSIST) == 0)
-      return (0);
+    if (state == STATE_UNKNOWN) {
+      /* From UNKNOWN to UNKNOWN. Persist doesn't apply here. */
+      return 0;
+    } else if ((th->flags & UT_FLAG_PERSIST) == 0)
+      return 0;
     else if ((state == STATE_OKAY) && ((th->flags & UT_FLAG_PERSIST_OK) == 0))
-      return (0);
+      return 0;
   }
 
   if (state != state_old)
@@ -456,9 +367,14 @@ static int ut_report_state(const data_set_t *ds, const value_list_t *vl,
     if (state_old == STATE_MISSING)
       ssnprintf(buf, bufsize, ": Value is no longer missing.");
     else
-      ssnprintf(buf, bufsize, ": All data sources are within range again. "
-                              "Current value of \"%s\" is %f.",
+      ssnprintf(buf, bufsize,
+                ": All data sources are within range again. "
+                "Current value of \"%s\" is %f.",
                 ds->ds[ds_index].name, values[ds_index]);
+  } else if (state == STATE_UNKNOWN) {
+    ERROR("ut_report_state: metric transition to UNKNOWN from a different "
+          "state. This shouldn't happen.");
+    return 0;
   } else {
     double min;
     double max;
@@ -476,8 +392,9 @@ static int ut_report_state(const data_set_t *ds, const value_list_t *vl,
                   ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "", max,
                   ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "");
       } else {
-        ssnprintf(buf, bufsize, ": Data source \"%s\" is currently "
-                                "%f. That is %s the %s threshold of %f%s.",
+        ssnprintf(buf, bufsize,
+                  ": Data source \"%s\" is currently "
+                  "%f. That is %s the %s threshold of %f%s.",
                   ds->ds[ds_index].name, values[ds_index],
                   isnan(min) ? "below" : "above",
                   (state == STATE_ERROR) ? "failure" : "warning",
@@ -510,8 +427,9 @@ static int ut_report_state(const data_set_t *ds, const value_list_t *vl,
                 (value < min) ? min : max);
     } else /* is not inverted */
     {
-      ssnprintf(buf, bufsize, ": Data source \"%s\" is currently "
-                              "%f. That is %s the %s threshold of %f.",
+      ssnprintf(buf, bufsize,
+                ": Data source \"%s\" is currently "
+                "%f. That is %s the %s threshold of %f.",
                 ds->ds[ds_index].name, values[ds_index],
                 (values[ds_index] < min) ? "below" : "above",
                 (state == STATE_ERROR) ? "failure" : "warning",
@@ -522,7 +440,7 @@ static int ut_report_state(const data_set_t *ds, const value_list_t *vl,
   plugin_dispatch_notification(&n);
 
   plugin_notification_meta_free(n.meta);
-  return (0);
+  return 0;
 } /* }}} int ut_report_state */
 
 /*
@@ -547,7 +465,7 @@ static int ut_check_one_data_source(
   if (ds != NULL) {
     ds_name = ds->ds[ds_index].name;
     if ((th->data_source[0] != 0) && (strcmp(ds_name, th->data_source) != 0))
-      return (STATE_OKAY);
+      return STATE_UNKNOWN;
   }
 
   if ((th->flags & UT_FLAG_INVERT) != 0) {
@@ -576,6 +494,7 @@ static int ut_check_one_data_source(
     case STATE_WARNING:
       hysteresis_for_warning = th->hysteresis;
       break;
+    case STATE_UNKNOWN:
     case STATE_OKAY:
       /* do nothing -- the hysteresis only applies to the non-normal states */
       break;
@@ -604,12 +523,12 @@ static int ut_check_one_data_source(
   }
 
   if (is_failure != 0)
-    return (STATE_ERROR);
+    return STATE_ERROR;
 
   if (is_warning != 0)
-    return (STATE_WARNING);
+    return STATE_WARNING;
 
-  return (STATE_OKAY);
+  return STATE_OKAY;
 } /* }}} int ut_check_one_data_source */
 
 /*
@@ -617,7 +536,8 @@ static int ut_check_one_data_source(
  *
  * Checks all data sources of a value list against the given threshold, using
  * the ut_check_one_data_source function above. Returns the worst status,
- * which is `okay' if nothing has failed.
+ * which is `okay' if nothing has failed or `unknown' if no valid datasource was
+ * defined.
  * Returns less than zero if the data set doesn't have any data sources.
  */
 static int ut_check_one_threshold(const data_set_t *ds, const value_list_t *vl,
@@ -674,7 +594,7 @@ static int ut_check_one_threshold(const data_set_t *ds, const value_list_t *vl,
   if (ret_ds_index != NULL)
     *ret_ds_index = ds_index;
 
-  return (ret);
+  return ret;
 } /* }}} int ut_check_one_threshold */
 
 /*
@@ -698,7 +618,7 @@ static int ut_check_threshold(const data_set_t *ds, const value_list_t *vl,
   int worst_ds_index = -1;
 
   if (threshold_tree == NULL)
-    return (0);
+    return 0;
 
   /* Is this lock really necessary? So far, thresholds are only inserted at
    * startup. -octo */
@@ -706,13 +626,13 @@ static int ut_check_threshold(const data_set_t *ds, const value_list_t *vl,
   th = threshold_search(vl);
   pthread_mutex_unlock(&threshold_lock);
   if (th == NULL)
-    return (0);
+    return 0;
 
   DEBUG("ut_check_threshold: Found matching threshold(s)");
 
   values = uc_get_rate(ds, vl);
   if (values == NULL)
-    return (0);
+    return 0;
 
   while (th != NULL) {
     int ds_index = -1;
@@ -721,7 +641,7 @@ static int ut_check_threshold(const data_set_t *ds, const value_list_t *vl,
     if (status < 0) {
       ERROR("ut_check_threshold: ut_check_one_threshold failed.");
       sfree(values);
-      return (-1);
+      return -1;
     }
 
     if (worst_state < status) {
@@ -738,12 +658,12 @@ static int ut_check_threshold(const data_set_t *ds, const value_list_t *vl,
   if (status != 0) {
     ERROR("ut_check_threshold: ut_report_state failed.");
     sfree(values);
-    return (-1);
+    return -1;
   }
 
   sfree(values);
 
-  return (0);
+  return 0;
 } /* }}} int ut_check_threshold */
 
 /*
@@ -760,12 +680,12 @@ static int ut_missing(const value_list_t *vl,
   cdtime_t now;
 
   if (threshold_tree == NULL)
-    return (0);
+    return 0;
 
   th = threshold_search(vl);
   /* dispatch notifications for "interesting" values only */
   if ((th == NULL) || ((th->flags & UT_FLAG_INTERESTING) == 0))
-    return (0);
+    return 0;
 
   now = cdtime();
   missing_time = now - vl->time;
@@ -779,7 +699,7 @@ static int ut_missing(const value_list_t *vl,
 
   plugin_dispatch_notification(&n);
 
-  return (0);
+  return 0;
 } /* }}} int ut_missing */
 
 static int ut_config(oconfig_item_t *ci) { /* {{{ */
@@ -790,7 +710,7 @@ static int ut_config(oconfig_item_t *ci) { /* {{{ */
     threshold_tree = c_avl_create((int (*)(const void *, const void *))strcmp);
     if (threshold_tree == NULL) {
       ERROR("ut_config: c_avl_create failed.");
-      return (-1);
+      return -1;
     }
   }
 
@@ -828,7 +748,7 @@ static int ut_config(oconfig_item_t *ci) { /* {{{ */
                           /* user data = */ NULL);
   }
 
-  return (status);
+  return status;
 } /* }}} int um_config */
 
 void module_register(void) {