The branch, master has been updated via 00db5fa00474f8a83f1aa3b603fd756cc9b49ff4 (commit) from b940e3a24daa73ca9b2896b7a449240136442b53 (commit)
http://gitweb.samba.org/?p=ctdb.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 00db5fa00474f8a83f1aa3b603fd756cc9b49ff4 Author: Martin Schwenke <mar...@meltin.net> Date: Wed Feb 6 14:15:11 2013 +1100 Logging: Fix breakage when freeing the log ringbuffer Commit a82d3ec12f0fda16d6bfa8442a07595de897c10e broke fetching from the log ringbuffer. The solution there is still generally good: there is no need to keep the ringbuffer in children created by ctdb_fork()... except for those special children that are created to fetch data from the ringbuffer! Introduce a new function ctdb_fork_no_free_ringbuffer() that does everything ctdb_fork() needs to do except free the ringbuffer (i.e. it is the old ctdb_fork() function). The new ctdb_fork() function just calls that function and then frees the ringbuffer in the child. This means all callers of ctdb_fork() have the convenience of having the ringbuffer freed. There are 3 special cases: * Forking the recovery daemon. We want to be able to fetch from the ringbuffer there. * The ringbuffer fetching code. Change the 2 calls in this code (main daemon, recovery daemon) to call ctdb_fork_no_free_ringbuffer() instead. While we're here, clear the log ringbuffer when the recovery deamon is forked, since it will contain a copy of the messages from the main daemon. Note to self: always test... even the most obvious patches... ;-) Signed-off-by: Martin Schwenke <mar...@meltin.net> ----------------------------------------------------------------------- Summary of changes: common/ctdb_fork.c | 15 ++++++++++++--- common/ctdb_logging.c | 2 +- include/ctdb_private.h | 1 + server/ctdb_recoverd.c | 7 +++++-- 4 files changed, 19 insertions(+), 6 deletions(-) Changeset truncated at 500 lines: diff --git a/common/ctdb_fork.c b/common/ctdb_fork.c index a11f75a..9e3a06d 100644 --- a/common/ctdb_fork.c +++ b/common/ctdb_fork.c @@ -27,7 +27,7 @@ * This function forks a child process and drops the realtime * scheduler for the child process. */ -pid_t ctdb_fork(struct ctdb_context *ctdb) +pid_t ctdb_fork_no_free_ringbuffer(struct ctdb_context *ctdb) { pid_t pid; char *process; @@ -60,8 +60,6 @@ pid_t ctdb_fork(struct ctdb_context *ctdb) } ctdb->can_send_controls = false; - ctdb_log_ringbuffer_free(); - return 0; } @@ -75,6 +73,17 @@ pid_t ctdb_fork(struct ctdb_context *ctdb) return pid; } +pid_t ctdb_fork(struct ctdb_context *ctdb) +{ + pid_t pid; + + pid = ctdb_fork_no_free_ringbuffer(ctdb); + if (pid == 0) { + ctdb_log_ringbuffer_free(); + } + + return pid; +} static void ctdb_sigchld_handler(struct tevent_context *ev, diff --git a/common/ctdb_logging.c b/common/ctdb_logging.c index 105b4df..de5ca6e 100644 --- a/common/ctdb_logging.c +++ b/common/ctdb_logging.c @@ -163,7 +163,7 @@ int32_t ctdb_control_get_log(struct ctdb_context *ctdb, TDB_DATA addr) /* spawn a child process to marshall the huge log blob and send it back to the ctdb tool using a MESSAGE */ - child = ctdb_fork(ctdb); + child = ctdb_fork_no_free_ringbuffer(ctdb); if (child == (pid_t)-1) { DEBUG(DEBUG_ERR,("Failed to fork a log collector child\n")); return -1; diff --git a/include/ctdb_private.h b/include/ctdb_private.h index cf850aa..7794c4c 100644 --- a/include/ctdb_private.h +++ b/include/ctdb_private.h @@ -1072,6 +1072,7 @@ void ctdb_restore_scheduler(struct ctdb_context *ctdb); struct tevent_signal *ctdb_init_sigchld(struct ctdb_context *ctdb); pid_t ctdb_fork(struct ctdb_context *ctdb); +pid_t ctdb_fork_no_free_ringbuffer(struct ctdb_context *ctdb); int ctdb_kill(struct ctdb_context *ctdb, pid_t pid, int signum); int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb, diff --git a/server/ctdb_recoverd.c b/server/ctdb_recoverd.c index bffe2be..95172a1 100644 --- a/server/ctdb_recoverd.c +++ b/server/ctdb_recoverd.c @@ -2126,7 +2126,7 @@ static void getlog_handler(struct ctdb_context *ctdb, uint64_t srvid, } log_addr = (struct ctdb_get_log_addr *)data.dptr; - child = ctdb_fork(ctdb); + child = ctdb_fork_no_free_ringbuffer(ctdb); if (child == (pid_t)-1) { DEBUG(DEBUG_ERR,("Failed to fork a log collector child\n")); return; @@ -4014,7 +4014,7 @@ int ctdb_start_recoverd(struct ctdb_context *ctdb) ctdb->ctdbd_pid = getpid(); - ctdb->recoverd_pid = ctdb_fork(ctdb); + ctdb->recoverd_pid = ctdb_fork_no_free_ringbuffer(ctdb); if (ctdb->recoverd_pid == -1) { return -1; } @@ -4035,6 +4035,9 @@ int ctdb_start_recoverd(struct ctdb_context *ctdb) srandom(getpid() ^ time(NULL)); + /* Clear the log ringbuffer */ + ctdb_clear_log(ctdb); + if (switch_from_server_to_client(ctdb, "recoverd") != 0) { DEBUG(DEBUG_CRIT, (__location__ "ERROR: failed to switch recovery daemon into client mode. shutting down.\n")); exit(1); -- CTDB repository