From: Ronnie Sahlberg Date: Mon, 10 Jan 2011 02:57:49 +0000 (+1100) Subject: Add ctdb_fork(0 which will fork a child process and drop the real-time X-Git-Url: http://git.samba.org/?p=sahlberg%2Fctdb.git;a=commitdiff_plain;h=ebbebeec3b511ffb66bca506abc1bb867911ae95 Add ctdb_fork(0 which will fork a child process and drop the real-time scheduler for the child. Use ctdb_fork() from callers where we dont want the child to be running at real-time privilege. --- diff --git a/common/ctdb_logging.c b/common/ctdb_logging.c index de6e039d..dee4dfdb 100644 --- a/common/ctdb_logging.c +++ b/common/ctdb_logging.c @@ -157,7 +157,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 = fork(); + child = ctdb_fork(ctdb); if (child == (pid_t)-1) { DEBUG(DEBUG_ERR,("Failed to fork a log collector child\n")); return -1; diff --git a/common/ctdb_util.c b/common/ctdb_util.c index 80390899..1ff4c1f9 100644 --- a/common/ctdb_util.c +++ b/common/ctdb_util.c @@ -334,15 +334,20 @@ void ctdb_restore_scheduler(struct ctdb_context *ctdb) } /* - make ourselves slightly nicer: eg. a ctdb child. + * This function forks a child process and drops the realtime + * scheduler for the child process. */ -void ctdb_reduce_priority(struct ctdb_context *ctdb) +pid_t ctdb_fork(struct ctdb_context *ctdb) { - errno = 0; - if (nice(10) == -1 && errno != 0) { - DEBUG(DEBUG_WARNING,("Unable to lower priority: %s\n", - strerror(errno))); + pid_t pid; + + pid = fork(); + if (pid == 0) { + if (ctdb->do_setsched) { + ctdb_restore_scheduler(ctdb); + } } + return pid; } void set_nonblocking(int fd) diff --git a/include/ctdb_private.h b/include/ctdb_private.h index deba46b2..2d9315f6 100644 --- a/include/ctdb_private.h +++ b/include/ctdb_private.h @@ -993,6 +993,7 @@ void ctdb_node_connected(struct ctdb_node *node); 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); int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb, struct ctdb_req_control *c, TDB_DATA indata, diff --git a/server/ctdb_lockwait.c b/server/ctdb_lockwait.c index 48198fd1..1d3a5976 100644 --- a/server/ctdb_lockwait.c +++ b/server/ctdb_lockwait.c @@ -117,7 +117,7 @@ struct lockwait_handle *ctdb_lockwait(struct ctdb_db_context *ctdb_db, return NULL; } - result->child = fork(); + result->child = ctdb_fork(ctdb_db->ctdb); if (result->child == (pid_t)-1) { close(result->fd[0]); diff --git a/server/ctdb_logging.c b/server/ctdb_logging.c index 7e5367ea..27b990ef 100644 --- a/server/ctdb_logging.c +++ b/server/ctdb_logging.c @@ -96,7 +96,7 @@ int start_syslog_daemon(struct ctdb_context *ctdb) return -1; } - ctdb->syslogd_pid = fork(); + ctdb->syslogd_pid = ctdb_fork(ctdb); if (ctdb->syslogd_pid == (pid_t)-1) { printf("Failed to create syslog child process\n"); close(state->fd[0]); @@ -454,7 +454,7 @@ struct ctdb_log_state *ctdb_fork_with_logging(TALLOC_CTX *mem_ctx, goto free_log; } - *pid = fork(); + *pid = ctdb_fork(ctdb); /* Child? */ if (*pid == 0) { diff --git a/server/ctdb_monitor.c b/server/ctdb_monitor.c index 7f5da5c3..fa642fb3 100644 --- a/server/ctdb_monitor.c +++ b/server/ctdb_monitor.c @@ -83,7 +83,7 @@ void ctdb_run_notification_script(struct ctdb_context *ctdb, const char *event) return; } - child = fork(); + child = ctdb_fork(ctdb); if (child == (pid_t)-1) { DEBUG(DEBUG_ERR,("Failed to fork() a notification child process\n")); return; diff --git a/server/ctdb_persistent.c b/server/ctdb_persistent.c index 9346f7d0..f9a20510 100644 --- a/server/ctdb_persistent.c +++ b/server/ctdb_persistent.c @@ -524,7 +524,7 @@ struct childwrite_handle *ctdb_childwrite(struct ctdb_db_context *ctdb_db, return NULL; } - result->child = fork(); + result->child = ctdb_fork(ctdb_db->ctdb); if (result->child == (pid_t)-1) { close(result->fd[0]); diff --git a/server/ctdb_recoverd.c b/server/ctdb_recoverd.c index 9caa5024..b2c08ced 100644 --- a/server/ctdb_recoverd.c +++ b/server/ctdb_recoverd.c @@ -2768,7 +2768,7 @@ static int check_recovery_lock(struct ctdb_context *ctdb) return -1; } - state->child = fork(); + state->child = ctdb_fork(ctdb); if (state->child == (pid_t)-1) { DEBUG(DEBUG_CRIT,(__location__ " fork() failed in check_reclock child\n")); close(state->fd[0]); diff --git a/server/ctdb_traverse.c b/server/ctdb_traverse.c index dcb16b22..5ad374f0 100644 --- a/server/ctdb_traverse.c +++ b/server/ctdb_traverse.c @@ -153,7 +153,7 @@ static struct ctdb_traverse_local_handle *ctdb_traverse_local(struct ctdb_db_con return NULL; } - h->child = fork(); + h->child = ctdb_fork(ctdb_db->ctdb); if (h->child == (pid_t)-1) { close(h->fd[0]); diff --git a/server/ctdb_vacuum.c b/server/ctdb_vacuum.c index 4104853d..4aac302d 100644 --- a/server/ctdb_vacuum.c +++ b/server/ctdb_vacuum.c @@ -836,7 +836,7 @@ ctdb_vacuum_event(struct event_context *ev, struct timed_event *te, return; } - child_ctx->child_pid = fork(); + child_ctx->child_pid = ctdb_fork(ctdb); if (child_ctx->child_pid == (pid_t)-1) { close(child_ctx->fd[0]); close(child_ctx->fd[1]); diff --git a/server/eventscript.c b/server/eventscript.c index ce2fd89e..9ba3a5d9 100644 --- a/server/eventscript.c +++ b/server/eventscript.c @@ -511,9 +511,8 @@ static void debug_timeout(struct ctdb_event_script_state *state) sprintf(buf, "{ pstree -p; cat /proc/locks; ls -li /var/ctdb/ /var/ctdb/persistent; }" " >/tmp/ctdb.event.%s.%d", tbuf, getpid()); - pid = fork(); + pid = ctdb_fork(state->ctdb); if (pid == 0) { - ctdb_reduce_priority(state->ctdb); system(buf); /* Now we can kill the child */ kill(state->child, SIGTERM);