summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Leblond <eric@inl.fr>2008-08-01 11:00:22 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2008-08-01 11:00:22 +0200
commite1c1dc00eb78f4255fbed0793bd205b42b3d4141 (patch)
treeafaff86db073d7ede6f92175fbc4a4787fbb0433
parentfa4eb049a549dfdd48a8f59ef2713694716a6811 (diff)
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.c19
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++;