1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-26 10:04:02 +03:00

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 <martin@meltin.net>

(This used to be ctdb commit 00db5fa00474f8a83f1aa3b603fd756cc9b49ff4)
This commit is contained in:
Martin Schwenke 2013-02-06 14:15:11 +11:00 committed by Amitay Isaacs
parent 140be1e267
commit 689384a7b4
4 changed files with 19 additions and 6 deletions

View File

@ -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,

View File

@ -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;

View File

@ -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,

View File

@ -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);