diff options
author | Eric Leblond <eric@inl.fr> | 2008-08-01 11:00:22 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2008-08-01 11:00:22 +0200 |
commit | e1c1dc00eb78f4255fbed0793bd205b42b3d4141 (patch) | |
tree | afaff86db073d7ede6f92175fbc4a4787fbb0433 | |
parent | fa4eb049a549dfdd48a8f59ef2713694716a6811 (diff) | |
download | conntrack-tools-e1c1dc00eb78f4255fbed0793bd205b42b3d4141.tar.gz conntrack-tools-e1c1dc00eb78f4255fbed0793bd205b42b3d4141.zip |
commit: retry at least once if we hit ETIME or ENOMEM
Some users are reporting ETIME errors in the update. This happens
when you try to update a conntrack that is expiring. To avoid this
problem, we retry once at least. We do similar for ENOMEM errors,
although only users in virtual machines have reported this AFAIK.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | src/cache_iterators.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/src/cache_iterators.c b/src/cache_iterators.c index 562d9a2..e9ddbc0 100644 --- a/src/cache_iterators.c +++ b/src/cache_iterators.c @@ -24,6 +24,7 @@ #include "us-conntrack.h" #include <libnetfilter_conntrack/libnetfilter_conntrack.h> +#include <sched.h> #include <errno.h> #include <string.h> @@ -80,7 +81,7 @@ void cache_dump(struct cache *c, int fd, int type) /* no need to clone, called from child process */ static int do_commit(void *data1, void *data2) { - int ret; + int ret, retry = 1; struct cache *c = data1; struct us_conntrack *u = data2; struct nf_conntrack *ct = u->ct; @@ -98,7 +99,15 @@ static int do_commit(void *data1, void *data2) dlog_ct(STATE(log), ct, NFCT_O_PLAIN); break; case 0: +try_again_create: if (nl_create_conntrack(ct) == -1) { + if (errno == ENOMEM) { + if (retry) { + retry = 0; + sched_yield(); + goto try_again_create; + } + } dlog(LOG_ERR, "commit-create: %s", strerror(errno)); dlog_ct(STATE(log), ct, NFCT_O_PLAIN); c->commit_fail++; @@ -107,7 +116,15 @@ static int do_commit(void *data1, void *data2) break; case 1: c->commit_exist++; +try_again_update: if (nl_update_conntrack(ct) == -1) { + if (errno == ENOMEM || errno == ETIME) { + if (retry) { + retry = 0; + sched_yield(); + goto try_again_update; + } + } dlog(LOG_ERR, "commit-update: %s", strerror(errno)); dlog_ct(STATE(log), ct, NFCT_O_PLAIN); c->commit_fail++; |