From 7dca954f276e3d1786b7c447c3aa63e2743987a8 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 24 Nov 2008 12:05:24 +0100 Subject: [PATCH] src/filter_chain.[ch]: Implement the built-in `return' target. The `stop' target now aborts all processing of the value completely, `return' only stops the current chain and continues processing the parent chain. The collectd.conf(5) manual page has been updated and the `FC_ACTION_*' defines have been renamed to `FC_TARGET_*'. --- src/collectd.conf.pod | 64 ++++++++++++++++++++++------------ src/filter_chain.c | 80 +++++++++++++++++++++++++++++++++---------- src/filter_chain.h | 5 +-- src/target_set.c | 2 +- 4 files changed, 107 insertions(+), 44 deletions(-) diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index a1846003..87e86d46 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -2623,10 +2623,31 @@ plugins to be loaded: =over 4 +=item B + +Signals the "return" condition. This causes the current chain to stop +processing the value and returns control to the calling chain. The calling +chain will continue processing targets and rules just after the B target +(see below). This is very similar to the B target of iptables, see +L. + +This target does not have any options. + +Example: + + Target "return" + =item B -Does nothing except returning with the stop condition, causing processing of -the current chain to be aborted. +Signals the "stop" condition, causing processing of the value to be aborted +immediately. This is similar to the B target of iptables, see +L. + +This target does not have any options. + +Example: + + Target "stop" =item B @@ -2641,10 +2662,6 @@ Available options: Name of the write plugin to which the data should be sent. This option may be given multiple times to send the data to more than one write plugin. -Example: - - Target "stop" - =back If no plugin is explicitly specified, the values will be sent to all available @@ -2661,6 +2678,8 @@ Example: Starts processing the rules of another chain. If the end of that chain is reached, or a stop condition is encountered, processing will continue right after the B target, i.Ee. with the next target or the next rule. +This is similar to the B<-j> command line option of iptables, see +L. Available options: @@ -2680,22 +2699,6 @@ Example: =back -=head2 Backwards compatibility - -If you use collectd with an old configuration, i.Ee. one without a -B block, it will behave as it used to. This is equivalent to the -following configuration: - - - Target "write" - - -If you specify a B block anywhere, the B target will not be added -anywhere and you will have to make sure that it is called where appropriate. We -suggest to add the above snippet as default target to your main chain. - -TODO: Notifications will be implemented using chains, too. Describe that here! - =head2 Available matches =over 4 @@ -2768,6 +2771,22 @@ Example: =back +=head2 Backwards compatibility + +If you use collectd with an old configuration, i.Ee. one without a +B block, it will behave as it used to. This is equivalent to the +following configuration: + + + Target "write" + + +If you specify a B block anywhere, the B target will not be added +anywhere and you will have to make sure that it is called where appropriate. We +suggest to add the above snippet as default target to your main chain. + +TODO: Notifications will be implemented using chains, too. Describe that here! + =head2 Examples Ignore all values, where the hostname does not contain a dot, i.Ee. can't @@ -2791,6 +2810,7 @@ L, L, L, L, +L, L, L, L, diff --git a/src/filter_chain.c b/src/filter_chain.c index 109a32a0..01cd224c 100644 --- a/src/filter_chain.c +++ b/src/filter_chain.c @@ -567,8 +567,7 @@ int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */ DEBUG ("fc_process_chain (chain = %s);", chain->name); - status = FC_ACTION_CONTINUE; - + status = FC_TARGET_CONTINUE; for (rule = chain->rules; rule != NULL; rule = rule->next) { fc_match_t *match; @@ -595,7 +594,10 @@ int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */ /* for-loop has been aborted: Either error or no match. */ if (match != NULL) + { + status = FC_TARGET_CONTINUE; continue; + } if (rule->name[0] != 0) { @@ -614,9 +616,11 @@ int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */ WARNING ("fc_process_chain (%s): A target failed.", chain->name); continue; } - else if (status == FC_ACTION_CONTINUE) + else if (status == FC_TARGET_CONTINUE) continue; - else if (status == FC_ACTION_STOP) + else if (status == FC_TARGET_STOP) + break; + else if (status == FC_TARGET_RETURN) break; else { @@ -626,25 +630,37 @@ int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */ } } - if (status == FC_ACTION_STOP) + if ((status == FC_TARGET_STOP) + || (status == FC_TARGET_RETURN)) { if (rule->name[0] != 0) { DEBUG ("fc_process_chain (%s): Rule `%s' signaled " - "the stop condition.", - chain->name, rule->name); + "the %s condition.", + chain->name, rule->name, + (status == FC_TARGET_STOP) ? "stop" : "return"); } break; } + else + { + status = FC_TARGET_CONTINUE; + } } /* for (rule) */ - /* for-loop has been aborted: A target returned `FC_ACTION_STOP' */ + 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 (0); + return (FC_TARGET_CONTINUE); DEBUG ("fc_process_chain (%s): Executing the default targets.", chain->name); + status = FC_TARGET_CONTINUE; for (target = chain->targets; target != NULL; target = target->next) { /* If we get here, all matches have matched the value. Execute the @@ -656,9 +672,11 @@ int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */ WARNING ("fc_process_chain (%s): The default target failed.", chain->name); } - else if (status == FC_ACTION_CONTINUE) + else if (status == FC_TARGET_CONTINUE) continue; - else if (status == FC_ACTION_STOP) + else if (status == FC_TARGET_STOP) + break; + else if (status == FC_TARGET_RETURN) break; else { @@ -668,14 +686,24 @@ int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */ } } - if (target != NULL) + if ((status == FC_TARGET_STOP) + || (status == FC_TARGET_RETURN)) { + assert (target != NULL); DEBUG ("fc_process_chain (%s): Default target `%s' signaled " - "the stop condition.", - chain->name, target->name); + "the %s condition.", + chain->name, target->name, + (status == FC_TARGET_STOP) ? "stop" : "return"); + if (status == FC_TARGET_STOP) + return (FC_TARGET_STOP); + else + return (FC_TARGET_CONTINUE); } - return (0); + DEBUG ("fc_process_chain (%s): Signaling `continue' at end of chain.", + chain->name); + + return (FC_TARGET_CONTINUE); } /* }}} int fc_process_chain */ /* @@ -756,16 +784,24 @@ static int fc_bit_jump_invoke (const data_set_t *ds, /* {{{ */ status = fc_process_chain (ds, vl, chain); if (status < 0) return (status); - - return (FC_ACTION_CONTINUE); + else if (status == FC_TARGET_STOP) + return (FC_TARGET_STOP); + else + return (FC_TARGET_CONTINUE); } /* }}} int fc_bit_jump_invoke */ static int fc_bit_stop_invoke (const data_set_t *ds, /* {{{ */ value_list_t *vl, notification_meta_t **meta, void **user_data) { - return (FC_ACTION_STOP); + return (FC_TARGET_STOP); } /* }}} int fc_bit_stop_invoke */ +static int fc_bit_return_invoke (const data_set_t *ds, /* {{{ */ + value_list_t *vl, notification_meta_t **meta, void **user_data) +{ + return (FC_TARGET_RETURN); +} /* }}} int fc_bit_return_invoke */ + static int fc_bit_write_create (const oconfig_item_t *ci, /* {{{ */ void **user_data) { @@ -876,7 +912,7 @@ static int fc_bit_write_invoke (const data_set_t *ds, /* {{{ */ } /* for (i = 0; plugin_list[i] != NULL; i++) */ } - return (FC_ACTION_CONTINUE); + return (FC_TARGET_CONTINUE); } /* }}} int fc_bit_write_invoke */ static int fc_init_once (void) /* {{{ */ @@ -899,6 +935,12 @@ static int fc_init_once (void) /* {{{ */ tproc.invoke = fc_bit_stop_invoke; fc_register_target ("stop", tproc); + memset (&tproc, 0, sizeof (tproc)); + tproc.create = NULL; + tproc.destroy = NULL; + tproc.invoke = fc_bit_return_invoke; + fc_register_target ("return", tproc); + memset (&tproc, 0, sizeof (tproc)); tproc.create = fc_bit_write_create; tproc.destroy = fc_bit_write_destroy; diff --git a/src/filter_chain.h b/src/filter_chain.h index f2e22af2..2fd78d97 100644 --- a/src/filter_chain.h +++ b/src/filter_chain.h @@ -28,8 +28,9 @@ #define FC_MATCH_NO_MATCH 0 #define FC_MATCH_MATCHES 1 -#define FC_ACTION_CONTINUE 0 -#define FC_ACTION_STOP 1 +#define FC_TARGET_CONTINUE 0 +#define FC_TARGET_STOP 1 +#define FC_TARGET_RETURN 2 /* * Match functions diff --git a/src/target_set.c b/src/target_set.c index e328da31..70b0fdfc 100644 --- a/src/target_set.c +++ b/src/target_set.c @@ -249,7 +249,7 @@ static int ts_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */ /* SET_FIELD (type); */ SET_FIELD (type_instance); - return (0); + return (FC_TARGET_CONTINUE); } /* }}} int ts_invoke */ void module_register (void) -- 2.30.2