diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2009-07-19 15:28:34 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2009-07-19 15:28:34 +0200 |
commit | 651794575c844fe25a717d77bd088c51383067f0 (patch) | |
tree | d4dd79f189ebdb933266d354aa66f42b7571f4b4 /src/sync-mode.c | |
parent | a1d03b775376aa8545ec9a0e89381b659e4d28ed (diff) | |
download | conntrack-tools-651794575c844fe25a717d77bd088c51383067f0.tar.gz conntrack-tools-651794575c844fe25a717d77bd088c51383067f0.zip |
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.c | 38 |
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))) { |