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)
/* 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;
* 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;
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;
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,