return 0;
}
+static void sig_child_handler(struct event_context *ev,
+ struct signal_event *se, int signum, int count,
+ void *dont_care,
+ void *private_data)
+{
+// struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context);
+ int status;
+ pid_t pid = -1;
+
+ while (pid != 0) {
+ pid = waitpid(-1, &status, WNOHANG);
+ if (pid == -1) {
+ DEBUG(DEBUG_ERR, (__location__ " waitpid() returned error. errno:%d\n", errno));
+ return;
+ }
+ if (pid > 0) {
+ DEBUG(DEBUG_DEBUG, ("SIGCHLD from %d\n", (int)pid));
+ }
+ }
+}
+
/*
start the protocol going as a daemon
*/
int res, ret = -1;
struct fd_event *fde;
const char *domain_socket_name;
+ struct signal_event *se;
/* get rid of any old sockets */
unlink(ctdb->daemon.name);
/* start the transport going */
ctdb_start_transport(ctdb);
+ /* set up a handler to pick up sigchld */
+ se = event_add_signal(ctdb->ev, ctdb,
+ SIGCHLD, 0,
+ sig_child_handler,
+ ctdb);
+ if (se == NULL) {
+ DEBUG(DEBUG_CRIT,("Failed to set up signal handler for SIGCHLD\n"));
+ exit(1);
+ }
+
/* go into a wait loop to allow other nodes to complete */
event_loop_wait(ctdb->ev);
ctdb->freeze_handle = NULL;
kill(h->child, SIGKILL);
- waitpid(h->child, NULL, 0);
return 0;
}
tdb_chainlock_unmark(tdb, key);
kill(child, SIGKILL);
- waitpid(child, NULL, 0);
talloc_free(tmp_ctx);
}
{
h->ctdb->statistics.pending_lockwait_calls--;
kill(h->child, SIGKILL);
- waitpid(h->child, NULL, 0);
return 0;
}
{
h->ctdb->statistics.pending_childwrite_calls--;
kill(h->child, SIGKILL);
- waitpid(h->child, NULL, 0);
return 0;
}
callback(c, p);
kill(child, SIGKILL);
- waitpid(child, NULL, 0);
talloc_free(tmp_ctx);
}
static int set_recmode_destructor(struct ctdb_set_recmode_state *state)
{
kill(state->child, SIGKILL);
- waitpid(state->child, NULL, 0);
return 0;
}
{
struct ctdb_context *ctdb = talloc_get_type(p, struct ctdb_context);
- /* make sure we harvest the child if signals are blocked for some
- reason
- */
- waitpid(ctdb->recoverd_pid, 0, WNOHANG);
-
if (kill(ctdb->recoverd_pid, 0) != 0) {
DEBUG(DEBUG_ERR,("Recovery daemon (pid:%d) is no longer running. Shutting down main daemon\n", (int)ctdb->recoverd_pid));
ctdb_check_recd, ctdb);
}
+static void recd_sig_child_handler(struct event_context *ev,
+ struct signal_event *se, int signum, int count,
+ void *dont_care,
+ void *private_data)
+{
+// struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context);
+ int status;
+ pid_t pid = -1;
+
+ while (pid != 0) {
+ pid = waitpid(-1, &status, WNOHANG);
+ if (pid == -1) {
+ DEBUG(DEBUG_ERR, (__location__ " waitpid() returned error. errno:%d\n", errno));
+ return;
+ }
+ if (pid > 0) {
+ DEBUG(DEBUG_DEBUG, ("RECD SIGCHLD from %d\n", (int)pid));
+ }
+ }
+}
+
/*
startup the recovery daemon as a child of the main ctdb daemon
*/
{
int ret;
int fd[2];
+ struct signal_event *se;
if (pipe(fd) != 0) {
return -1;
exit(1);
}
+ /* set up a handler to pick up sigchld */
+ se = event_add_signal(ctdb->ev, ctdb,
+ SIGCHLD, 0,
+ recd_sig_child_handler,
+ ctdb);
+ if (se == NULL) {
+ DEBUG(DEBUG_CRIT,("Failed to set up signal handler for SIGCHLD in recovery daemon\n"));
+ exit(1);
+ }
+
monitor_cluster(ctdb);
DEBUG(DEBUG_ALERT,("ERROR: ctdb_recoverd finished!?\n"));
static int traverse_local_destructor(struct ctdb_traverse_local_handle *h)
{
kill(h->child, SIGKILL);
- waitpid(h->child, NULL, 0);
return 0;
}
{
struct ctdb_event_script_state *state =
talloc_get_type(p, struct ctdb_event_script_state);
- int status = -1;
void (*callback)(struct ctdb_context *, int, void *) = state->callback;
void *private_data = state->private_data;
struct ctdb_context *ctdb = state->ctdb;
+ signed char rt = -1;
+
+ read(state->fd[0], &rt, sizeof(rt));
- waitpid(state->child, &status, 0);
- if (status != -1) {
- status = WEXITSTATUS(status);
- }
talloc_set_destructor(state, NULL);
talloc_free(state);
- callback(ctdb, status, private_data);
+ callback(ctdb, rt, private_data);
ctdb->event_script_timeouts = 0;
}
{
DEBUG(DEBUG_ERR,(__location__ " Sending SIGTERM to child pid:%d\n", state->child));
kill(state->child, SIGTERM);
- waitpid(state->child, NULL, 0);
return 0;
}
}
if (state->child == 0) {
+ signed char rt;
+
close(state->fd[0]);
if (ctdb->do_setsched) {
ctdb_restore_scheduler(ctdb);
}
set_close_on_exec(state->fd[1]);
- ret = ctdb_event_script_v(ctdb, state->options);
- _exit(ret);
+ rt = ctdb_event_script_v(ctdb, state->options);
+ while ((ret = write(state->fd[1], &rt, sizeof(rt))) != sizeof(rt)) {
+ sleep(1);
+ }
+ _exit(rt);
}
talloc_set_destructor(state, event_script_destructor);