From e1c1dc00eb78f4255fbed0793bd205b42b3d4141 Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Fri, 1 Aug 2008 11:00:22 +0200 Subject: 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 --- src/cache_iterators.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) 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 +#include #include #include @@ -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++; -- cgit v1.2.3