X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fethstat.c;h=8971f4dfcc2cb0cc10dbf7cf4c8e6ca271fbdc52;hb=354f9991530248e45207d236eb74c1cc3d5238ef;hp=7507bd97851cbbb12ee256a1e067fa1196b9343b;hpb=46ba00ecd986212d2519791244c50b33e1b81397;p=collectd.git diff --git a/src/ethstat.c b/src/ethstat.c index 7507bd97..8971f4df 100644 --- a/src/ethstat.c +++ b/src/ethstat.c @@ -1,6 +1,7 @@ /** * collectd - src/ethstat.c * Copyright (C) 2011 Cyril Feraudet + * Copyright (C) 2012 Florian "octo" Forster * * 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 @@ -18,6 +19,7 @@ * * Authors: * Cyril Feraudet + * Florian "octo" Forster **/ #include "collectd.h" @@ -25,6 +27,7 @@ #include "plugin.h" #include "configfile.h" #include "utils_avltree.h" +#include "utils_complain.h" #if HAVE_SYS_IOCTL_H # include @@ -51,6 +54,8 @@ static size_t interfaces_num = 0; static c_avl_tree_t *value_map = NULL; +static _Bool collect_mapped_only = 0; + static int ethstat_add_interface (const oconfig_item_t *ci) /* {{{ */ { char **tmp; @@ -61,13 +66,14 @@ static int ethstat_add_interface (const oconfig_item_t *ci) /* {{{ */ if (tmp == NULL) return (-1); interfaces = tmp; + interfaces[interfaces_num] = NULL; status = cf_util_get_string (ci, interfaces + interfaces_num); if (status != 0) return (status); interfaces_num++; - INFO("ethstat plugin: Registred interface %s", + INFO("ethstat plugin: Registered interface %s", interfaces[interfaces_num - 1]); return (0); @@ -77,6 +83,7 @@ static int ethstat_add_map (const oconfig_item_t *ci) /* {{{ */ { value_map_t *map; int status; + char *key; if ((ci->values_num < 2) || (ci->values_num > 3) @@ -90,16 +97,23 @@ static int ethstat_add_map (const oconfig_item_t *ci) /* {{{ */ return (-1); } - map = malloc (sizeof (*map)); + key = strdup (ci->values[0].value.string); + if (key == NULL) + { + ERROR ("ethstat plugin: strdup(3) failed."); + return (ENOMEM); + } + + map = calloc (1, sizeof (*map)); if (map == NULL) { - ERROR ("ethstat plugin: malloc(3) failed."); + sfree (key); + ERROR ("ethstat plugin: calloc failed."); return (ENOMEM); } - memset (map, 0, sizeof (*map)); sstrncpy (map->type, ci->values[1].value.string, sizeof (map->type)); - if (ci->values_num == 2) + if (ci->values_num == 3) sstrncpy (map->type_instance, ci->values[2].value.string, sizeof (map->type_instance)); @@ -109,23 +123,24 @@ static int ethstat_add_map (const oconfig_item_t *ci) /* {{{ */ if (value_map == NULL) { sfree (map); + sfree (key); ERROR ("ethstat plugin: c_avl_create() failed."); return (-1); } } status = c_avl_insert (value_map, - /* key = */ ci->values[0].value.string, + /* key = */ key, /* value = */ map); if (status != 0) { - sfree (map); if (status > 0) - ERROR ("ethstat plugin: Multiple mappings for \"%s\".", - ci->values[0].value.string); + ERROR ("ethstat plugin: Multiple mappings for \"%s\".", key); else - ERROR ("ethstat plugin: c_avl_insert(\"%s\") failed.", - ci->values[0].value.string); + ERROR ("ethstat plugin: c_avl_insert(\"%s\") failed.", key); + + sfree (map); + sfree (key); return (-1); } @@ -144,6 +159,8 @@ static int ethstat_config (oconfig_item_t *ci) /* {{{ */ ethstat_add_interface (child); else if (strcasecmp ("Map", child->key) == 0) ethstat_add_map (child); + else if (strcasecmp ("MappedOnly", child->key) == 0) + (void) cf_util_get_boolean (child, &collect_mapped_only); else WARNING ("ethstat plugin: The config option \"%s\" is unknown.", child->key); @@ -155,6 +172,8 @@ static int ethstat_config (oconfig_item_t *ci) /* {{{ */ static void ethstat_submit_value (const char *device, const char *type_instance, derive_t value) { + static c_complain_t complain_no_map = C_COMPLAIN_INIT_STATIC; + value_t values[1]; value_list_t vl = VALUE_LIST_INIT; value_map_t *map = NULL; @@ -162,6 +181,16 @@ static void ethstat_submit_value (const char *device, if (value_map != NULL) c_avl_get (value_map, type_instance, (void *) &map); + /* If the "MappedOnly" option is specified, ignore unmapped values. */ + if (collect_mapped_only && (map == NULL)) + { + if (value_map == NULL) + c_complain (LOG_WARNING, &complain_no_map, + "ethstat plugin: The \"MappedOnly\" option has been set to true, " + "but no mapping has been configured. All values will be ignored!"); + return; + } + values[0].derive = value; vl.values = values; vl.values_len = 1; @@ -243,7 +272,7 @@ static int ethstat_read_interface (char *device) close (fd); sfree (strings); sfree (stats); - ERROR("ethstat plugin: malloc(3) failed."); + ERROR("ethstat plugin: malloc failed."); return (-1); } @@ -284,10 +313,9 @@ static int ethstat_read_interface (char *device) { const char *stat_name; - stat_name = (void *) &strings->data[i * ETH_GSTRING_LEN], - DEBUG("ethstat plugin: device = \"%s\": %s = %"PRIu64, - device, stat_name, - (uint64_t) stats->data[i]); + stat_name = (void *) &strings->data[i * ETH_GSTRING_LEN]; + DEBUG("ethstat plugin: device = \"%s\": %s = %"PRIu64, + device, stat_name, (uint64_t) stats->data[i]); ethstat_submit_value (device, stat_name, (derive_t) stats->data[i]); } @@ -309,10 +337,31 @@ static int ethstat_read(void) return 0; } +static int ethstat_shutdown (void) +{ + void *key = NULL; + void *value = NULL; + + if (value_map == NULL) + return (0); + + while (c_avl_pick (value_map, &key, &value) == 0) + { + sfree (key); + sfree (value); + } + + c_avl_destroy (value_map); + value_map = NULL; + + return (0); +} + void module_register (void) { plugin_register_complex_config ("ethstat", ethstat_config); plugin_register_read ("ethstat", ethstat_read); + plugin_register_shutdown ("ethstat", ethstat_shutdown); } /* vim: set sw=2 sts=2 et fdm=marker : */