diff options
author | Martin Schwenke <martin@meltin.net> | 2018-09-12 17:51:47 +1000 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2018-09-20 09:13:11 +0200 |
commit | eb498ec2baea154bdba313fc495a9dc7e0322f77 (patch) | |
tree | 2cecb3937331d3ceab1ac4a4fb080acd8980889a /ctdb/server | |
parent | 1954a94203789422b163b4f257aa3c9ab83fa9a2 (diff) | |
download | samba-eb498ec2baea154bdba313fc495a9dc7e0322f77.tar.gz |
ctdb-cluster-mutex: Block signals around fork
If SIGTERM is received and the tevent signal handler setup in the
recovery daemon is still enabled then the signal is handled and a
corresponding event is queued. The child never runs an event loop so
the signal is effectively ignored.
Resetting the SIGTERM handler isn't enough. A signal can arrive
before that.
Block SIGTERM before forking and then immediately unblock it in the
parent.
In the child, unblock SIGTERM after the signal handler is reset. An
explicit unblock is needed because according to sigprocmask(2) "the
signal mask is preserved across execve(2)".
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13617
Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
(cherry picked from commit e789d0da57fc3fc6d22bfa00577a2e65034ca27a)
Diffstat (limited to 'ctdb/server')
-rw-r--r-- | ctdb/server/ctdb_cluster_mutex.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/ctdb/server/ctdb_cluster_mutex.c b/ctdb/server/ctdb_cluster_mutex.c index e8c75debfb8..330d5fd1d90 100644 --- a/ctdb/server/ctdb_cluster_mutex.c +++ b/ctdb/server/ctdb_cluster_mutex.c @@ -196,6 +196,7 @@ ctdb_cluster_mutex(TALLOC_CTX *mem_ctx, { struct ctdb_cluster_mutex_handle *h; char **args; + sigset_t sigset_term; int ret; h = talloc(mem_ctx, struct ctdb_cluster_mutex_handle); @@ -225,11 +226,22 @@ ctdb_cluster_mutex(TALLOC_CTX *mem_ctx, return NULL; } + sigemptyset(&sigset_term); + sigaddset(&sigset_term, SIGTERM); + ret = sigprocmask(SIG_BLOCK, &sigset_term, NULL); + if (ret != 0) { + DBG_WARNING("Failed to block SIGTERM (%d)\n", errno); + } + h->child = ctdb_fork(ctdb); if (h->child == (pid_t)-1) { close(h->fd[0]); close(h->fd[1]); talloc_free(h); + ret = sigprocmask(SIG_UNBLOCK, &sigset_term, NULL); + if (ret != 0) { + DBG_WARNING("Failed to unblock SIGTERM (%d)\n", errno); + } return NULL; } @@ -244,6 +256,11 @@ ctdb_cluster_mutex(TALLOC_CTX *mem_ctx, errno); } + ret = sigprocmask(SIG_UNBLOCK, &sigset_term, NULL); + if (ret != 0) { + DBG_WARNING("Failed to unblock SIGTERM (%d)\n", errno); + } + /* Make stdout point to the pipe */ close(STDOUT_FILENO); dup2(h->fd[1], STDOUT_FILENO); @@ -258,6 +275,11 @@ ctdb_cluster_mutex(TALLOC_CTX *mem_ctx, /* Parent */ + ret = sigprocmask(SIG_UNBLOCK, &sigset_term, NULL); + if (ret != 0) { + DBG_WARNING("Failed to unblock SIGTERM (%d)\n", errno); + } + DEBUG(DEBUG_DEBUG, (__location__ " Created PIPE FD:%d\n", h->fd[0])); set_close_on_exec(h->fd[0]); |