[lxc-devel] [lxc/master] lxc_monitord: make lxc-monitord async signal safe

brauner on Github lxc-bot at linuxcontainers.org
Sun Nov 27 03:33:18 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 755 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20161127/27f86bb3/attachment.bin>
-------------- next part --------------
From d0dacf05a66b8f791650855673782649ee36a4a7 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
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 <christian.brauner at ubuntu.com>
---
 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 2500571..2fbb357 100644
--- a/src/lxc/lxc_monitord.c
+++ b/src/lxc/lxc_monitord.c
@@ -31,6 +31,7 @@
 #include <unistd.h>
 #include <net/if.h>
 #include <netinet/in.h>
+#include <setjmp.h>
 #include <sys/epoll.h>
 #include <sys/param.h>
 #include <sys/socket.h>
@@ -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);
 }


More information about the lxc-devel mailing list