summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 7ca2b1a)
raw | patch | inline | side by side (parent: 7ca2b1a)
author | Florian Forster <octo@crystal.wlan.home.verplant.org> | |
Mon, 17 Sep 2007 07:32:23 +0000 (09:32 +0200) | ||
committer | Florian Forster <octo@crystal.wlan.home.verplant.org> | |
Mon, 17 Sep 2007 07:32:23 +0000 (09:32 +0200) |
This is done recursively so that you can have a depth of up to `n' (currently eight).
ChangeLog | patch | blob | history | |
src/collectd.conf.pod | patch | blob | history | |
src/configfile.c | patch | blob | history |
diff --git a/ChangeLog b/ChangeLog
index 259f40c3586be82e490a0708cc6a835c1329aef6..49e6c31bfc89148d0e007e849817d795de3a3e49 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
yyyy-mm-dd, Version 4.2.0
+ * collectd: The new config option `Include' lets you include other
+ configfiles and thus split up your config into smaller parts. This
+ may be especially interresting for the snmp plugin to keep the data
+ definitions seperate from the host definitions.
* snmp plugin: Added the options `Scale' and `Shift' to Data-blocks to
correct the values returned by SNMP-agents.
diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod
index 29e26af4dddc34a57e46a617193ebfe099d80270..27c506564356c0fbd5e3431c90977cfb43facec2 100644 (file)
--- a/src/collectd.conf.pod
+++ b/src/collectd.conf.pod
Loads the plugin I<Plugin>. There must be at least one such line or B<collectd>
will be mostly useless.
+=item B<Include> I<File>
+
+Includes the file I<File> as if it was copy and pasted here. To prevent loops
+and shooting yourself in the foot in interesting ways the nesting is limited to
+a depth of 8E<nbsp>levels, which should be sufficient for most uses.
+
+It is no problem to have a block like C<E<lt>Plugin fooE<gt>> in more than one
+file, but you cannot include files from within blocks.
+
=item B<PIDFile> I<File>
Sets where to write the PID file to. This file is overwritten when it exists
diff --git a/src/configfile.c b/src/configfile.c
index f4e9c604fe26cafd75ee04620158b11f5aed6726..0310ca8aff417f37036a737ee55043f5182bc955 100644 (file)
--- a/src/configfile.c
+++ b/src/configfile.c
return (0);
}
+#define CF_MAX_DEPTH 8
+static oconfig_item_t *cf_read_file (const char *file, int depth);
+
+static int cf_include_all (oconfig_item_t *root, int depth)
+{
+ int i;
+
+ for (i = 0; i < root->children_num; i++)
+ {
+ oconfig_item_t *new;
+ oconfig_item_t *old;
+
+ /* Ignore all blocks, including `Include' blocks. */
+ if (root->children[i].children_num != 0)
+ continue;
+
+ if (strcasecmp (root->children[i].key, "Include") != 0)
+ continue;
+
+ old = root->children + i;
+
+ if ((old->values_num != 1)
+ || (old->values[0].type != OCONFIG_TYPE_STRING))
+ {
+ ERROR ("configfile: `Include' needs exactly one string argument.");
+ continue;
+ }
+
+ new = cf_read_file (old->values[0].value.string, depth + 1);
+ if (new == NULL)
+ continue;
+
+ /* There are more children now. We need to expand
+ * root->children. */
+ if (new->children_num > 1)
+ {
+ oconfig_item_t *temp;
+
+ DEBUG ("configfile: Resizing root-children from %i to %i elements.",
+ root->children_num,
+ root->children_num + new->children_num - 1);
+
+ temp = (oconfig_item_t *) realloc (root->children,
+ sizeof (oconfig_item_t)
+ * (root->children_num + new->children_num - 1));
+ if (temp == NULL)
+ {
+ ERROR ("configfile: realloc failed.");
+ oconfig_free (new);
+ continue;
+ }
+ root->children = temp;
+ }
+
+ /* Clean up the old include directive while we still have a
+ * valid pointer */
+ DEBUG ("configfile: Cleaning up `old'");
+ /* sfree (old->values[0].value.string); */
+ sfree (old->values);
+
+ /* If there are trailing children and the number of children
+ * changes, we need to move the trailing ones either one to the
+ * front or (new->num - 1) to the back */
+ if (((root->children_num - i) > 1)
+ && (new->children_num != 1))
+ {
+ DEBUG ("configfile: Moving trailing children.");
+ memmove (root->children + i + new->children_num,
+ root->children + i + 1,
+ sizeof (oconfig_item_t)
+ * (root->children_num - (i + 1)));
+ }
+
+ /* Now copy the new children to where the include statement was */
+ if (new->children_num > 0)
+ {
+ DEBUG ("configfile: Copying new children.");
+ memcpy (root->children + i,
+ new->children,
+ sizeof (oconfig_item_t)
+ * new->children_num);
+ }
+
+ /* Adjust the number of children and the position in the list. */
+ root->children_num = root->children_num + new->children_num - 1;
+ i = i + new->children_num - 1;
+
+ /* Clean up the `new' struct. We set `new->children' to NULL so
+ * the stuff we've just copied pointers to isn't freed by
+ * `oconfig_free' */
+ DEBUG ("configfile: Cleaning up `new'");
+ sfree (new->values); /* should be NULL anyway */
+ sfree (new);
+ new = NULL;
+ } /* for (i = 0; i < root->children_num; i++) */
+
+ return (0);
+} /* int cf_include_all */
+
+static oconfig_item_t *cf_read_file (const char *file, int depth)
+{
+ oconfig_item_t *root;
+
+ if (depth >= CF_MAX_DEPTH)
+ {
+ ERROR ("configfile: Not including `%s' because the maximum nesting depth has been reached.",
+ file);
+ return (NULL);
+ }
+
+ root = oconfig_parse_file (file);
+ if (root == NULL)
+ {
+ ERROR ("configfile: Cannot read file `%s'.", file);
+ return (NULL);
+ }
+
+ cf_include_all (root, depth);
+
+ return (root);
+} /* oconfig_item_t *cf_read_file */
+
/*
* Public functions
*/
oconfig_item_t *conf;
int i;
- conf = oconfig_parse_file (filename);
+ conf = cf_read_file (filename, 0 /* depth */);
if (conf == NULL)
{
ERROR ("Unable to read config file %s.", filename);