Merge pull request #2046 from rubenk/cleanup-dpdk-detection
[collectd.git] / src / daemon / filter_chain.c
index c87b877..cee479a 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "configfile.h"
 #include "plugin.h"
 #include "utils_complain.h"
@@ -78,6 +79,15 @@ struct fc_chain_s /* {{{ */
   fc_chain_t  *next;
 }; /* }}} */
 
+/* Writer configuration. */
+struct fc_writer_s;
+typedef struct fc_writer_s fc_writer_t; /* {{{ */
+struct fc_writer_s
+{
+  char *plugin;
+  c_complain_t complaint;
+}; /* }}} */
+
 /*
  * Global variables
  */
@@ -165,7 +175,7 @@ static char *fc_strdup (const char *orig) /* {{{ */
     return (NULL);
 
   sz = strlen (orig) + 1;
-  dest = (char *) malloc (sz);
+  dest = malloc (sz);
   if (dest == NULL)
     return (NULL);
 
@@ -226,13 +236,12 @@ static int fc_config_add_match (fc_match_t **matches_head, /* {{{ */
     return (-1);
   }
 
-  m = (fc_match_t *) malloc (sizeof (*m));
+  m = calloc (1, sizeof (*m));
   if (m == NULL)
   {
-    ERROR ("fc_config_add_match: malloc failed.");
+    ERROR ("fc_config_add_match: calloc failed.");
     return (-1);
   }
-  memset (m, 0, sizeof (*m));
 
   sstrncpy (m->name, ptr->name, sizeof (m->name));
   memcpy (&m->proc, &ptr->proc, sizeof (m->proc));
@@ -298,13 +307,12 @@ static int fc_config_add_target (fc_target_t **targets_head, /* {{{ */
     return (-1);
   }
 
-  t = (fc_target_t *) malloc (sizeof (*t));
+  t = calloc (1, sizeof (*t));
   if (t == NULL)
   {
-    ERROR ("fc_config_add_target: malloc failed.");
+    ERROR ("fc_config_add_target: calloc failed.");
     return (-1);
   }
-  memset (t, 0, sizeof (*t));
 
   sstrncpy (t->name, ptr->name, sizeof (t->name));
   memcpy (&t->proc, &ptr->proc, sizeof (t->proc));
@@ -326,7 +334,7 @@ static int fc_config_add_target (fc_target_t **targets_head, /* {{{ */
   {
     t->user_data = NULL;
   }
-  
+
   if (*targets_head != NULL)
   {
     ptr = *targets_head;
@@ -349,7 +357,6 @@ static int fc_config_add_rule (fc_chain_t *chain, /* {{{ */
   fc_rule_t *rule;
   char rule_name[2*DATA_MAX_NAME_LEN] = "Unnamed rule";
   int status = 0;
-  int i;
 
   if (ci->values_num > 1)
   {
@@ -364,14 +371,12 @@ static int fc_config_add_rule (fc_chain_t *chain, /* {{{ */
     return (-1);
   }
 
-  rule = (fc_rule_t *) malloc (sizeof (*rule));
+  rule = calloc (1, sizeof (*rule));
   if (rule == NULL)
   {
-    ERROR ("fc_config_add_rule: malloc failed.");
+    ERROR ("fc_config_add_rule: calloc failed.");
     return (-1);
   }
-  memset (rule, 0, sizeof (*rule));
-  rule->next = NULL;
 
   if (ci->values_num == 1)
   {
@@ -380,10 +385,9 @@ static int fc_config_add_rule (fc_chain_t *chain, /* {{{ */
         ci->values[0].value.string);
   }
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
-    status = 0;
 
     if (strcasecmp ("Match", option->key) == 0)
       status = fc_config_add_match (&rule->matches, option);
@@ -442,7 +446,6 @@ static int fc_config_add_chain (const oconfig_item_t *ci) /* {{{ */
 {
   fc_chain_t *chain = NULL;
   int status = 0;
-  int i;
   int new_chain = 1;
 
   if ((ci->values_num != 1)
@@ -461,23 +464,18 @@ static int fc_config_add_chain (const oconfig_item_t *ci) /* {{{ */
 
   if (chain == NULL)
   {
-    chain = (fc_chain_t *) malloc (sizeof (*chain));
+    chain = calloc (1, sizeof (*chain));
     if (chain == NULL)
     {
-      ERROR ("fc_config_add_chain: malloc failed.");
+      ERROR ("fc_config_add_chain: calloc failed.");
       return (-1);
     }
-    memset (chain, 0, sizeof (*chain));
     sstrncpy (chain->name, ci->values[0].value.string, sizeof (chain->name));
-    chain->rules = NULL;
-    chain->targets = NULL;
-    chain->next = NULL;
   }
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
-    status = 0;
 
     if (strcasecmp ("Rule", option->key) == 0)
       status = fc_config_add_rule (chain, option);
@@ -625,19 +623,13 @@ static int fc_bit_return_invoke (const data_set_t __attribute__((unused)) *ds, /
 static int fc_bit_write_create (const oconfig_item_t *ci, /* {{{ */
     void **user_data)
 {
-  int i;
+  fc_writer_t *plugin_list = NULL;
+  size_t plugin_list_len = 0;
 
-  char **plugin_list;
-  size_t plugin_list_len;
-
-  plugin_list = NULL;
-  plugin_list_len = 0;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
-    char **temp;
-    int j;
+    fc_writer_t *temp;
 
     if (strcasecmp ("Plugin", child->key) != 0)
     {
@@ -647,16 +639,19 @@ static int fc_bit_write_create (const oconfig_item_t *ci, /* {{{ */
       continue;
     }
 
-    for (j = 0; j < child->values_num; j++)
+    for (int j = 0; j < child->values_num; j++)
     {
+      char *plugin;
+
       if (child->values[j].type != OCONFIG_TYPE_STRING)
       {
         ERROR ("Filter subsystem: Built-in target `write': "
             "The `Plugin' option accepts only string arguments.");
         continue;
       }
+      plugin = child->values[j].value.string;
 
-      temp = (char **) realloc (plugin_list, (plugin_list_len + 2)
+      temp = realloc (plugin_list, (plugin_list_len + 2)
           * (sizeof (*plugin_list)));
       if (temp == NULL)
       {
@@ -665,14 +660,15 @@ static int fc_bit_write_create (const oconfig_item_t *ci, /* {{{ */
       }
       plugin_list = temp;
 
-      plugin_list[plugin_list_len] = fc_strdup (child->values[j].value.string);
-      if (plugin_list[plugin_list_len] == NULL)
+      plugin_list[plugin_list_len].plugin = fc_strdup (plugin);
+      if (plugin_list[plugin_list_len].plugin == NULL)
       {
         ERROR ("fc_bit_write_create: fc_strdup failed.");
         continue;
       }
+      C_COMPLAIN_INIT (&plugin_list[plugin_list_len].complaint);
       plugin_list_len++;
-      plugin_list[plugin_list_len] = NULL;
+      plugin_list[plugin_list_len].plugin = NULL;
     } /* for (j = 0; j < child->values_num; j++) */
   } /* for (i = 0; i < ci->children_num; i++) */
 
@@ -683,16 +679,15 @@ static int fc_bit_write_create (const oconfig_item_t *ci, /* {{{ */
 
 static int fc_bit_write_destroy (void **user_data) /* {{{ */
 {
-  char **plugin_list;
-  size_t i;
+  fc_writer_t *plugin_list;
 
   if ((user_data == NULL) || (*user_data == NULL))
     return (0);
 
   plugin_list = *user_data;
 
-  for (i = 0; plugin_list[i] != NULL; i++)
-    free (plugin_list[i]);
+  for (size_t i = 0; plugin_list[i].plugin != NULL; i++)
+    free (plugin_list[i].plugin);
   free (plugin_list);
 
   return (0);
@@ -702,52 +697,65 @@ static int fc_bit_write_invoke (const data_set_t *ds, /* {{{ */
     value_list_t *vl, notification_meta_t __attribute__((unused)) **meta,
     void **user_data)
 {
-  char **plugin_list;
+  fc_writer_t *plugin_list;
   int status;
 
   plugin_list = NULL;
   if (user_data != NULL)
     plugin_list = *user_data;
 
-  if ((plugin_list == NULL) || (plugin_list[0] == NULL))
+  if ((plugin_list == NULL) || (plugin_list[0].plugin == NULL))
   {
-    static c_complain_t enoent_complaint = C_COMPLAIN_INIT_STATIC;
+    static c_complain_t write_complaint = C_COMPLAIN_INIT_STATIC;
 
     status = plugin_write (/* plugin = */ NULL, ds, vl);
     if (status == ENOENT)
     {
       /* in most cases this is a permanent error, so use the complain
        * mechanism rather than spamming the logs */
-      c_complain (LOG_INFO, &enoent_complaint,
+      c_complain (LOG_INFO, &write_complaint,
           "Filter subsystem: Built-in target `write': Dispatching value to "
           "all write plugins failed with status %i (ENOENT). "
           "Most likely this means you didn't load any write plugins.",
           status);
+
+      plugin_log_available_writers ();
     }
     else if (status != 0)
     {
-      INFO ("Filter subsystem: Built-in target `write': Dispatching value to "
+      /* often, this is a permanent error (e.g. target system unavailable),
+       * so use the complain mechanism rather than spamming the logs */
+      c_complain (LOG_INFO, &write_complaint,
+          "Filter subsystem: Built-in target `write': Dispatching value to "
           "all write plugins failed with status %i.", status);
     }
     else
     {
       assert (status == 0);
-      c_release (LOG_INFO, &enoent_complaint, "Filter subsystem: "
+      c_release (LOG_INFO, &write_complaint, "Filter subsystem: "
           "Built-in target `write': Some write plugin is back to normal "
           "operation. `write' succeeded.");
     }
   }
   else
   {
-    size_t i;
-
-    for (i = 0; plugin_list[i] != NULL; i++)
+    for (size_t i = 0; plugin_list[i].plugin != NULL; i++)
     {
-      status = plugin_write (plugin_list[i], ds, vl);
+      status = plugin_write (plugin_list[i].plugin, ds, vl);
       if (status != 0)
       {
-        INFO ("Filter subsystem: Built-in target `write': Dispatching value to "
-            "the `%s' plugin failed with status %i.", plugin_list[i], status);
+        c_complain (LOG_INFO, &plugin_list[i].complaint,
+            "Filter subsystem: Built-in target `write': Dispatching value to "
+            "the `%s' plugin failed with status %i.",
+            plugin_list[i].plugin, status);
+
+        plugin_log_available_writers ();
+      }
+      else
+      {
+        c_release (LOG_INFO, &plugin_list[i].complaint,
+            "Filter subsystem: Built-in target `write': Plugin `%s' is back "
+            "to normal operation. `write' succeeded.", plugin_list[i].plugin);
       }
     } /* for (i = 0; plugin_list[i] != NULL; i++) */
   }
@@ -758,12 +766,11 @@ static int fc_bit_write_invoke (const data_set_t *ds, /* {{{ */
 static int fc_init_once (void) /* {{{ */
 {
   static int done = 0;
-  target_proc_t tproc;
+  target_proc_t tproc = { 0 };
 
   if (done != 0)
     return (0);
 
-  memset (&tproc, 0, sizeof (tproc));
   tproc.create  = fc_bit_jump_create;
   tproc.destroy = fc_bit_jump_destroy;
   tproc.invoke  = fc_bit_jump_invoke;
@@ -801,14 +808,12 @@ int fc_register_match (const char *name, match_proc_t proc) /* {{{ */
 
   DEBUG ("fc_register_match (%s);", name);
 
-  m = (fc_match_t *) malloc (sizeof (*m));
+  m = calloc (1, sizeof (*m));
   if (m == NULL)
     return (-ENOMEM);
-  memset (m, 0, sizeof (*m));
 
   sstrncpy (m->name, name, sizeof (m->name));
   memcpy (&m->proc, &proc, sizeof (m->proc));
-  m->next = NULL;
 
   if (match_list_head == NULL)
   {
@@ -835,14 +840,12 @@ int fc_register_target (const char *name, target_proc_t proc) /* {{{ */
 
   DEBUG ("fc_register_target (%s);", name);
 
-  t = (fc_target_t *) malloc (sizeof (*t));
+  t = calloc (1, sizeof (*t));
   if (t == NULL)
     return (-ENOMEM);
-  memset (t, 0, sizeof (*t));
 
   sstrncpy (t->name, name, sizeof (t->name));
   memcpy (&t->proc, &proc, sizeof (t->proc));
-  t->next = NULL;
 
   if (target_list_head == NULL)
   {
@@ -864,12 +867,10 @@ int fc_register_target (const char *name, target_proc_t proc) /* {{{ */
 
 fc_chain_t *fc_chain_get_by_name (const char *chain_name) /* {{{ */
 {
-  fc_chain_t *chain;
-
   if (chain_name == NULL)
     return (NULL);
 
-  for (chain = chain_list_head; chain != NULL; chain = chain->next)
+  for (fc_chain_t *chain = chain_list_head; chain != NULL; chain = chain->next)
     if (strcasecmp (chain_name, chain->name) == 0)
       return (chain);
 
@@ -879,19 +880,18 @@ fc_chain_t *fc_chain_get_by_name (const char *chain_name) /* {{{ */
 int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */
     fc_chain_t *chain)
 {
-  fc_rule_t *rule;
   fc_target_t *target;
-  int status;
+  int status = FC_TARGET_CONTINUE;
 
   if (chain == NULL)
     return (-1);
 
   DEBUG ("fc_process_chain (chain = %s);", chain->name);
 
-  status = FC_TARGET_CONTINUE;
-  for (rule = chain->rules; rule != NULL; rule = rule->next)
+  for (fc_rule_t *rule = chain->rules; rule != NULL; rule = rule->next)
   {
     fc_match_t *match;
+    status = FC_TARGET_CONTINUE;
 
     if (rule->name[0] != 0)
     {
@@ -953,8 +953,7 @@ int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */
       }
     }
 
-    if ((status == FC_TARGET_STOP)
-        || (status == FC_TARGET_RETURN))
+    if ((status == FC_TARGET_STOP) || (status == FC_TARGET_RETURN))
     {
       if (rule->name[0] != 0)
       {
@@ -965,20 +964,10 @@ int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */
       }
       break;
     }
-    else
-    {
-      status = FC_TARGET_CONTINUE;
-    }
   } /* for (rule) */
 
-  if (status == FC_TARGET_STOP)
-    return (FC_TARGET_STOP);
-  else if (status == FC_TARGET_RETURN)
-    return (FC_TARGET_CONTINUE);
-
-  /* for-loop has been aborted: A target returned `FC_TARGET_STOP' */
-  if (rule != NULL)
-    return (FC_TARGET_CONTINUE);
+  if ((status == FC_TARGET_STOP) || (status == FC_TARGET_RETURN))
+    return (status);
 
   DEBUG ("fc_process_chain (%s): Executing the default targets.",
       chain->name);