From d0dacf05a66b8f791650855673782649ee36a4a7 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Sun, 27 Nov 2016 01:43:37 +0100 Subject: [PATCH] lxc_monitord: make lxc-monitord async signal safe Before lxc_monitord called lxc_monitord_cleanup() from a signal handler. This function calls a bunch of async signal unsafe functions and basically begs for deadlocks. This commit switches lxc-monitord to using sigsetjmp() and siglongjmp() in the signal handler to jump to a cleanup label that call lxc_monitord_cleanup(). In this way, we avoid using async signal unsafe functions. Signed-off-by: Christian Brauner --- src/lxc/lxc_monitord.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/lxc/lxc_monitord.c b/src/lxc/lxc_monitord.c index 2500571c2..2fbb3574f 100644 --- a/src/lxc/lxc_monitord.c +++ b/src/lxc/lxc_monitord.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,8 @@ lxc_log_define(lxc_monitord, lxc); +sigjmp_buf mark; + static void lxc_monitord_cleanup(void); /* @@ -336,9 +339,7 @@ static void lxc_monitord_cleanup(void) static void lxc_monitord_sig_handler(int sig) { - INFO("Caught signal %d.", sig); - lxc_monitord_cleanup(); - exit(EXIT_SUCCESS); + siglongjmp(mark, 1); } int main(int argc, char *argv[]) @@ -384,6 +385,9 @@ int main(int argc, char *argv[]) signal(SIGBUS, lxc_monitord_sig_handler); signal(SIGTERM, lxc_monitord_sig_handler); + if (sigsetjmp(mark, 1) != 0) + goto on_signal; + ret = EXIT_FAILURE; memset(&mon, 0, sizeof(mon)); mon.lxcpath = lxcpath; @@ -427,4 +431,8 @@ int main(int argc, char *argv[]) on_error: exit(ret); + +on_signal: + lxc_monitord_cleanup(); + exit(EXIT_SUCCESS); }