]> git.ipfire.org Git - thirdparty/ulogd2.git/commitdiff
ulogd: fix double call of stop for reused input plugins
authorPablo Neira Ayuso <pablo@netfilter.org>
Fri, 7 Jan 2011 12:19:25 +0000 (13:19 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 7 Jan 2011 12:19:25 +0000 (13:19 +0100)
This patch adds reference counting for plugins. This is used to fix
a double stop for input plugins that are reused.

This problem was reported by Salih Gonullu <sag@open.ch>:

http://marc.info/?l=netfilter&m=129439584700693&w=2

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/ulogd/ulogd.h
src/ulogd.c

index 2d1b348dd82f198535e4abd1b3c5e3a03310b11b..e48caf851b857efcd75f488362f077e591594a52 100644 (file)
@@ -208,6 +208,8 @@ struct ulogd_plugin {
        char name[ULOGD_MAX_KEYLEN+1];
        /* ID for this plugin (dynamically assigned) */
        unsigned int id;
+       /* how many stacks are using this plugin? initially set to zero. */
+       unsigned int usage;
 
        struct ulogd_keyset input;
        struct ulogd_keyset output;
index f378c6f5319ea92176268f8f15e05ad801104d5e..a4b0ed135608d363444f0a1ec33bc6a443b6b5ee 100644 (file)
@@ -762,6 +762,15 @@ static int pluginstance_started(struct ulogd_pluginstance *npi)
        return 0;
 }
 
+static int pluginstance_stop(struct ulogd_pluginstance *npi)
+{
+       if (--npi->plugin->usage > 0 &&
+           npi->plugin->input.type == ULOGD_DTYPE_SOURCE) {
+               return 0;
+       }
+       return 1;
+}
+
 static int create_stack_start_instances(struct ulogd_pluginstance_stack *stack)
 {
        int ret;
@@ -839,6 +848,7 @@ static int create_stack(const char *option)
                        ret = -ENODEV;
                        goto out;
                }
+               pl->usage++;
 
                /* allocate */
                pi = pluginstance_alloc_init(pl, pi_id, stack);
@@ -989,8 +999,8 @@ static void stop_pluginstances()
 
        llist_for_each_entry(stack, &ulogd_pi_stacks, stack_list) {
                llist_for_each_entry_safe(pi, npi, &stack->list, list) {
-                       if (((pi->plugin->priv_size == 0) || pi->private[0])
-                                       && *pi->plugin->stop) {
+                       if ((pi->plugin->priv_size > 0 || *pi->plugin->stop) &&
+                           pluginstance_stop(pi)) {
                                ulogd_log(ULOGD_DEBUG, "calling stop for %s\n",
                                          pi->plugin->name);
                                (*pi->plugin->stop)(pi);