summaryrefslogtreecommitdiffstats
path: root/src/sync-mode.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2009-07-19 15:28:34 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2009-07-19 15:28:34 +0200
commit651794575c844fe25a717d77bd088c51383067f0 (patch)
treed4dd79f189ebdb933266d354aa66f42b7571f4b4 /src/sync-mode.c
parenta1d03b775376aa8545ec9a0e89381b659e4d28ed (diff)
conntrackd: rework commit not to fork a child process
This patch reworks the commit phase to avoid the forking. This is particularly useful in active-active setups in which one node has to commit the external cache while it is receiving new entries to be added in the external cache. This results in really high commit times due to the penalty of the copy-on-write that fork performs. The default number of steps in one run loop is limited to 64 by now. No option to tune this parameter is still available via the configuration file. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/sync-mode.c')
-rw-r--r--src/sync-mode.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/src/sync-mode.c b/src/sync-mode.c
index b0e2b02..7853d91 100644
--- a/src/sync-mode.c
+++ b/src/sync-mode.c
@@ -298,12 +298,22 @@ static int init_sync(void)
STATE(fds)) == -1)
return -1;
- STATE_SYNC(commit) = nfct_open(CONNTRACK, 0);
- if (STATE_SYNC(commit) == NULL) {
+ STATE_SYNC(commit).h = nfct_open(CONNTRACK, 0);
+ if (STATE_SYNC(commit).h == NULL) {
dlog(LOG_ERR, "can't create handler to commit");
return -1;
}
- origin_register(STATE_SYNC(commit), CTD_ORIGIN_COMMIT);
+ origin_register(STATE_SYNC(commit).h, CTD_ORIGIN_COMMIT);
+
+ STATE_SYNC(commit).evfd = create_evfd();
+ if (STATE_SYNC(commit).evfd == NULL) {
+ dlog(LOG_ERR, "can't create eventfd to commit");
+ return -1;
+ }
+ if (register_fd(get_read_evfd(STATE_SYNC(commit).evfd),
+ STATE(fds)) == -1) {
+ return -1;
+ }
init_alarm(&STATE_SYNC(reset_cache_alarm), NULL, do_reset_cache_alarm);
@@ -329,6 +339,11 @@ static void run_sync(fd_set *readfds)
if (FD_ISSET(nlif_fd(STATE_SYNC(interface)), readfds))
interface_handler();
+ if (FD_ISSET(get_read_evfd(STATE_SYNC(commit).evfd), readfds)) {
+ read_evfd(STATE_SYNC(commit).evfd);
+ cache_commit(STATE_SYNC(external), STATE_SYNC(commit).h, 0);
+ }
+
/* flush pending messages */
multichannel_send_flush(STATE_SYNC(channel));
}
@@ -344,8 +359,9 @@ static void kill_sync(void)
queue_destroy(STATE_SYNC(tx_queue));
- origin_unregister(STATE_SYNC(commit));
- nfct_close(STATE_SYNC(commit));
+ origin_unregister(STATE_SYNC(commit).h);
+ nfct_close(STATE_SYNC(commit).h);
+ destroy_evfd(STATE_SYNC(commit).evfd);
if (STATE_SYNC(sync)->kill)
STATE_SYNC(sync)->kill();
@@ -438,14 +454,10 @@ static int local_handler_sync(int fd, int type, void *data)
/* delete the reset alarm if any before committing */
del_alarm(&STATE_SYNC(reset_cache_alarm));
- /* fork new process and insert it the process list */
- ret = fork_process_new(CTD_PROC_COMMIT, CTD_PROC_F_EXCL,
- NULL, NULL);
- if (ret == 0) {
- dlog(LOG_NOTICE, "committing external cache");
- cache_commit(STATE_SYNC(external), STATE_SYNC(commit));
- exit(EXIT_SUCCESS);
- }
+ dlog(LOG_NOTICE, "committing external cache");
+ cache_commit(STATE_SYNC(external), STATE_SYNC(commit).h, fd);
+ /* Keep the client socket open, we want synchronous commits. */
+ ret = LOCAL_RET_STOLEN;
break;
case RESET_TIMERS:
if (!alarm_pending(&STATE_SYNC(reset_cache_alarm))) {