Logging: Fix breakage when freeing the log ringbuffer
authorMartin Schwenke <martin@meltin.net>
Fri, 19 Apr 2013 04:35:49 +0000 (14:35 +1000)
committerAmitay Isaacs <amitay@gmail.com>
Fri, 19 Apr 2013 06:27:08 +0000 (16:27 +1000)
Commit c6e1b84595039edb5c49a5851b440710dc0e2ac1 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, apart from the special case in the ringbuffer
fetching code where we call ctdb_fork_no_free_ringbuffer() instead.

Signed-off-by: Martin Schwenke <martin@meltin.net>
(backported from commit 00db5fa00474f8a83f1aa3b603fd756cc9b49ff4)

common/ctdb_logging.c
common/ctdb_util.c
include/ctdb_private.h

index bcc954a8906918a62919dd11e1a420fcbfca03ae..66eaec3dab34889ca20f19f49d9462d0c45c35af 100644 (file)
@@ -164,7 +164,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;
index d8d5ed7d3fd3eac07f8842efa4d73fc3d78e2501..724233a4cdae9f86fdc5c388a7087f67bed1f329 100644 (file)
@@ -361,7 +361,7 @@ void ctdb_restore_scheduler(struct ctdb_context *ctdb)
  * 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;
 
@@ -388,12 +388,23 @@ pid_t ctdb_fork(struct ctdb_context *ctdb)
                        ctdb_restore_scheduler(ctdb);
                }
                ctdb->can_send_controls = false;
+       }
+       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;
 }
 
+
 void set_nonblocking(int fd)
 {
        unsigned v;
index 0477628362362f2315115008eb0204fdcf10f332..62c3e0c9334157a044820162c72f828bdcec2578 100644 (file)
@@ -1034,6 +1034,7 @@ bool ctdb_blocking_freeze(struct ctdb_context *ctdb);
 void ctdb_set_scheduler(struct ctdb_context *ctdb);
 void ctdb_restore_scheduler(struct ctdb_context *ctdb);
 pid_t ctdb_fork(struct ctdb_context *ctdb);
+pid_t ctdb_fork_no_free_ringbuffer(struct ctdb_context *ctdb);
 int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb, 
                                 struct ctdb_req_control *c,
                                 TDB_DATA indata,