From a80ed3053a3b161d23e7bd57bd227671df047ed0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Tue, 29 Sep 2015 12:19:00 -0400 Subject: [PATCH] Fix: Log and ignore SIGINT and SIGTERM in run_as worker MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The run_as worker is in the same process group as its parent and will receive both SIGINT and SIGTERM. However, we want to give the worker a chance to tear itself down gracefully when its parent closes the command socket. The run_as worker will now ignore these signals (although it will log them) and wait for the parent to induce the teardown. Signed-off-by: Jérémie Galarneau --- src/common/runas.c | 65 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/src/common/runas.c b/src/common/runas.c index 2f2c0c7c3..3826c6175 100644 --- a/src/common/runas.c +++ b/src/common/runas.c @@ -528,9 +528,9 @@ int run_as_rmdir_recursive(const char *path, uid_t uid, gid_t gid) } static -void reset_sighandler(void) +int reset_sighandler(void) { - int sig; + int sig, ret = 0; DBG("Resetting run_as worker signal handlers to default"); for (sig = SIGHUP; sig <= SIGUNUSED; sig++) { @@ -540,8 +540,67 @@ void reset_sighandler(void) } if (signal(sig, SIG_DFL) == SIG_ERR) { PERROR("reset signal %d", sig); + ret = -1; + goto end; } } +end: + return ret; +} + +static +void worker_sighandler(int sig) +{ + const char *signame; + + /* + * The worker will its parent's signals since they are part of the same + * process group. However, in the case of SIGINT and SIGTERM, we want + * to give the worker a chance to teardown gracefully when its parent + * closes the command socket. + */ + switch (sig) { + case SIGINT: + signame = "SIGINT"; + break; + case SIGTERM: + signame = "SIGTERM"; + break; + default: + signame = "Unknown"; + } + + DBG("run_as worker received signal %s", signame); +} + +static +int set_worker_sighandlers(void) +{ + int ret = 0; + sigset_t sigset; + struct sigaction sa; + + if ((ret = sigemptyset(&sigset)) < 0) { + PERROR("sigemptyset"); + goto end; + } + + sa.sa_handler = worker_sighandler; + sa.sa_mask = sigset; + sa.sa_flags = 0; + if ((ret = sigaction(SIGINT, &sa, NULL)) < 0) { + PERROR("sigaction SIGINT"); + goto end; + } + + if ((ret = sigaction(SIGTERM, &sa, NULL)) < 0) { + PERROR("sigaction SIGTERM"); + goto end; + } + + DBG("run_as signal handler set for SIGTERM and SIGINT"); +end: + return ret; } LTTNG_HIDDEN @@ -585,6 +644,8 @@ int run_as_create_worker(char *procname) reset_sighandler(); + set_worker_sighandlers(); + /* The child has no use for this lock. */ pthread_mutex_unlock(&worker_lock); /* Just close, no shutdown. */ -- 2.34.1