X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fconfigfile.c;h=be777c52a02cbb0074c405fa7909ab0a3968c3b9;hb=178db08806318e0b01de2e7a9261f18d6f7ca72d;hp=4fe50cc2e11ee71a00dcd53bd843460cf68a5973;hpb=45aa67ef031ed2b8083f92efa2cbb76e0da8c02e;p=collectd.git diff --git a/src/configfile.c b/src/configfile.c index 4fe50cc2..be777c52 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -46,6 +46,7 @@ typedef struct cf_callback int (*callback) (const char *, const char *); const char **keys; int keys_num; + plugin_ctx_t ctx; struct cf_callback *next; } cf_callback_t; @@ -53,6 +54,7 @@ typedef struct cf_complex_callback_s { char *type; int (*callback) (oconfig_item_t *); + plugin_ctx_t ctx; struct cf_complex_callback_s *next; } cf_complex_callback_t; @@ -96,7 +98,7 @@ static cf_global_option_t cf_global_options[] = {"PIDFile", NULL, PIDFILE}, {"Hostname", NULL, NULL}, {"FQDNLookup", NULL, "true"}, - {"Interval", NULL, "10"}, + {"Interval", NULL, NULL}, {"ReadThreads", NULL, "5"}, {"Timeout", NULL, "2"}, {"PreCacheChain", NULL, "PreCache"}, @@ -128,6 +130,7 @@ static int cf_dispatch (const char *type, const char *orig_key, const char *orig_value) { cf_callback_t *cf_cb; + plugin_ctx_t old_ctx; char *key; char *value; int ret; @@ -156,6 +159,8 @@ static int cf_dispatch (const char *type, const char *orig_key, ret = -1; + old_ctx = plugin_set_ctx (cf_cb->ctx); + for (i = 0; i < cf_cb->keys_num; i++) { if ((cf_cb->keys[i] != NULL) @@ -166,6 +171,8 @@ static int cf_dispatch (const char *type, const char *orig_key, } } + plugin_set_ctx (old_ctx); + if (i >= cf_cb->keys_num) WARNING ("Plugin `%s' did not register for value `%s'.", type, key); @@ -244,6 +251,10 @@ static int dispatch_loadplugin (const oconfig_item_t *ci) int i; const char *name; unsigned int flags = 0; + plugin_ctx_t ctx; + plugin_ctx_t old_ctx; + int ret_val; + assert (strcasecmp (ci->key, "LoadPlugin") == 0); if (ci->values_num != 1) @@ -253,6 +264,10 @@ static int dispatch_loadplugin (const oconfig_item_t *ci) name = ci->values[0].value.string; + /* default to the global interval set before loading this plugin */ + memset (&ctx, 0, sizeof (ctx)); + ctx.interval = cf_get_default_interval (); + /* * XXX: Magic at work: * @@ -271,6 +286,16 @@ static int dispatch_loadplugin (const oconfig_item_t *ci) for (i = 0; i < ci->children_num; ++i) { if (strcasecmp("Globals", ci->children[i].key) == 0) cf_util_get_flag (ci->children + i, &flags, PLUGIN_FLAGS_GLOBAL); + else if (strcasecmp ("Interval", ci->children[i].key) == 0) { + double interval = 0.0; + + if (cf_util_get_double (ci->children + i, &interval) != 0) { + /* cf_util_get_double will log an error */ + continue; + } + + ctx.interval = DOUBLE_TO_CDTIME_T (interval); + } else { WARNING("Ignoring unknown LoadPlugin option \"%s\" " "for plugin \"%s\"", @@ -278,7 +303,12 @@ static int dispatch_loadplugin (const oconfig_item_t *ci) } } - return (plugin_load (name, (uint32_t) flags)); + old_ctx = plugin_set_ctx (ctx); + ret_val = plugin_load (name, (uint32_t) flags); + /* reset to the "global" context */ + plugin_set_ctx (old_ctx); + + return (ret_val); } /* int dispatch_value_loadplugin */ static int dispatch_value_plugin (const char *plugin, oconfig_item_t *ci) @@ -357,8 +387,18 @@ static int dispatch_block_plugin (oconfig_item_t *ci) /* Check for a complex callback first */ for (cb = complex_callback_head; cb != NULL; cb = cb->next) + { if (strcasecmp (name, cb->type) == 0) - return (cb->callback (ci)); + { + plugin_ctx_t old_ctx; + int ret_val; + + old_ctx = plugin_set_ctx (cb->ctx); + ret_val = (cb->callback (ci)); + plugin_set_ctx (old_ctx); + return (ret_val); + } + } /* Hm, no complex plugin found. Dispatch the values one by one */ for (i = 0; i < ci->children_num; i++) @@ -524,7 +564,7 @@ static int cf_include_all (oconfig_item_t *root, int depth) new = cf_read_generic (old->values[0].value.string, depth + 1); if (new == NULL) - continue; + return (-1); /* Now replace the i'th child in `root' with `new'. */ cf_ci_replace_child (root, new, i); @@ -542,6 +582,7 @@ static int cf_include_all (oconfig_item_t *root, int depth) static oconfig_item_t *cf_read_file (const char *file, int depth) { oconfig_item_t *root; + int status; assert (depth < CF_MAX_DEPTH); @@ -552,7 +593,12 @@ static oconfig_item_t *cf_read_file (const char *file, int depth) return (NULL); } - cf_include_all (root, depth); + status = cf_include_all (root, depth); + if (status != 0) + { + oconfig_free (root); + return (NULL); + } return (root); } /* oconfig_item_t *cf_read_file */ @@ -743,12 +789,6 @@ static oconfig_item_t *cf_read_generic (const char *path, int depth) wordfree (&we); - if (root->children == NULL) - { - oconfig_free (root); - return (NULL); - } - return (root); } /* oconfig_item_t *cf_read_generic */ /* #endif HAVE_WORDEXP_H */ @@ -828,6 +868,29 @@ const char *global_option_get (const char *option) : cf_global_options[i].def); } /* char *global_option_get */ +cdtime_t cf_get_default_interval (void) +{ + char const *str = global_option_get ("Interval"); + double interval_double = COLLECTD_DEFAULT_INTERVAL; + + if (str != NULL) + { + char *endptr = NULL; + double tmp = strtod (str, &endptr); + + if ((endptr == NULL) || (endptr == str) || (*endptr != 0)) + ERROR ("cf_get_default_interval: Unable to parse string \"%s\" " + "as number.", str); + else if (tmp <= 0.0) + ERROR ("cf_get_default_interval: Interval must be a positive number. " + "The current number is %g.", tmp); + else + interval_double = tmp; + } + + return (DOUBLE_TO_CDTIME_T (interval_double)); +} /* }}} cdtime_t cf_get_default_interval */ + void cf_unregister (const char *type) { cf_callback_t *this, *prev; @@ -884,6 +947,7 @@ void cf_register (const char *type, cf_cb->callback = callback; cf_cb->keys = keys; cf_cb->keys_num = keys_num; + cf_cb->ctx = plugin_get_ctx (); cf_cb->next = first_callback; first_callback = cf_cb; @@ -907,6 +971,8 @@ int cf_register_complex (const char *type, int (*callback) (oconfig_item_t *)) new->callback = callback; new->next = NULL; + new->ctx = plugin_get_ctx (); + if (complex_callback_head == NULL) { complex_callback_head = new; @@ -933,6 +999,12 @@ int cf_read (char *filename) ERROR ("Unable to read config file %s.", filename); return (-1); } + else if (conf->children_num == 0) + { + ERROR ("Configuration file %s is empty.", filename); + oconfig_free (conf); + return (-1); + } for (i = 0; i < conf->children_num; i++) { @@ -1015,6 +1087,23 @@ int cf_util_get_int (const oconfig_item_t *ci, int *ret_value) /* {{{ */ return (0); } /* }}} int cf_util_get_int */ +int cf_util_get_double (const oconfig_item_t *ci, double *ret_value) /* {{{ */ +{ + if ((ci == NULL) || (ret_value == NULL)) + return (EINVAL); + + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) + { + ERROR ("cf_util_get_double: The %s option requires " + "exactly one numeric argument.", ci->key); + return (-1); + } + + *ret_value = ci->values[0].value.number; + + return (0); +} /* }}} int cf_util_get_double */ + int cf_util_get_boolean (const oconfig_item_t *ci, _Bool *ret_bool) /* {{{ */ { if ((ci == NULL) || (ret_bool == NULL))