[lxc-devel] [PATCH 0/7] Last minute signal stuff

Ferenc Wagner wferi at niif.hu
Sun Jun 6 20:56:48 UTC 2010


Hi,

The first part is some tinkering to make lxc compile under Debian Lenny.

The "dangerous" part is the signal forwarding and the process group
business I was playing with recently.  It contains Greg's idea about
setting the foreground process group and also inverts the signal
selection logic.

Which means it's only slightly tested in its present form, but I
wanted to get this out of the door ASAP, so you can get an idea what
I'm up to.  I'll continue testing it tomorrow and will followup with
the results.

Regards,
Feri.


Ferenc Wagner (7):
  conditional use of new capabilities
  uint32_t is defined in stdint.h
  .gitignore new components
  start child in its own process group, and put it into the foreground
  lxc-start isn't in the foreground anymore, so TTY signals don't reach it
  forward signals to the container init
  generalize the name of the signal handler

 .gitignore      |    3 ++
 src/lxc/conf.c  |    4 +++
 src/lxc/start.c |   59 ++++++++++++++++++++++++++++++++++--------------------
 src/lxc/utils.h |   27 -------------------------
 4 files changed, 44 insertions(+), 49 deletions(-)

>From 3ef956ffcb44276159d603ce6f6845ce15f15d65 Mon Sep 17 00:00:00 2001
Message-Id: <3ef956ffcb44276159d603ce6f6845ce15f15d65.1275856857.git.wferi at niif.hu>
In-Reply-To: <cover.1275856857.git.wferi at niif.hu>
References: <cover.1275856857.git.wferi at niif.hu>
From: Ferenc Wagner <wferi at niif.hu>
Date: Sun, 6 Jun 2010 15:25:55 +0200
Subject: [PATCH 1/7] conditional use of new capabilities


Signed-off-by: Ferenc Wagner <wferi at niif.hu>
---
 src/lxc/conf.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 3d550a7..9565d91 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -170,8 +170,12 @@ static struct caps_opt caps_opt[] = {
 	{ "sys_tty_config",    CAP_SYS_TTY_CONFIG    },
 	{ "mknod",             CAP_MKNOD             },
 	{ "lease",             CAP_LEASE             },
+#ifdef CAP_AUDIT_WRITE
 	{ "audit_write",       CAP_AUDIT_WRITE       },
+#endif
+#ifdef CAP_AUDIT_CONTROL
 	{ "audit_control",     CAP_AUDIT_CONTROL     },
+#endif
 	{ "setfcap",           CAP_SETFCAP           },
 	{ "mac_override",      CAP_MAC_OVERRIDE      },
 	{ "mac_admin",         CAP_MAC_ADMIN         },
-- 
1.6.5


>From 48d88b7c9003274924f9474ee104f3c1dfffd01b Mon Sep 17 00:00:00 2001
Message-Id: <48d88b7c9003274924f9474ee104f3c1dfffd01b.1275856857.git.wferi at niif.hu>
In-Reply-To: <cover.1275856857.git.wferi at niif.hu>
References: <cover.1275856857.git.wferi at niif.hu>
From: Ferenc Wagner <wferi at niif.hu>
Date: Sun, 6 Jun 2010 15:26:39 +0200
Subject: [PATCH 2/7] uint32_t is defined in stdint.h


Signed-off-by: Ferenc Wagner <wferi at niif.hu>
---
 src/lxc/start.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/src/lxc/start.c b/src/lxc/start.c
index 2d45396..b69ac88 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -49,6 +49,7 @@
 #  include <sys/signalfd.h>
 #else
 /* assume kernel headers are too old */
+#include <stdint.h>
 struct signalfd_siginfo
 {
 	uint32_t ssi_signo;
-- 
1.6.5


>From abd69d96d0dd13989caf8a735e972e27663fff40 Mon Sep 17 00:00:00 2001
Message-Id: <abd69d96d0dd13989caf8a735e972e27663fff40.1275856857.git.wferi at niif.hu>
In-Reply-To: <cover.1275856857.git.wferi at niif.hu>
References: <cover.1275856857.git.wferi at niif.hu>
From: Ferenc Wagner <wferi at niif.hu>
Date: Sun, 6 Jun 2010 15:29:29 +0200
Subject: [PATCH 3/7] .gitignore new components


Signed-off-by: Ferenc Wagner <wferi at niif.hu>
---
 .gitignore |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore
index 83979f9..ce56094 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,10 +25,12 @@ lxc.spec
 lxc.pc
 
 scripts/lxc-debian
+scripts/lxc-ubuntu
 scripts/lxc-fedora
 scripts/lxc-sshd
 scripts/lxc-busybox
 
+src/lxc/lxc-attach
 src/lxc/lxc-cgroup
 src/lxc/lxc-checkconfig
 src/lxc/lxc-checkpoint
@@ -43,6 +45,7 @@ src/lxc/lxc-execute
 src/lxc/lxc-freeze
 src/lxc/lxc-info
 src/lxc/lxc-init
+src/lxc/lxc-kill
 src/lxc/lxc-ls
 src/lxc/lxc-monitor
 src/lxc/lxc-netstat
-- 
1.6.5


>From e0c67ce4113c5fc6ec76b6154a8d35852f8b2978 Mon Sep 17 00:00:00 2001
Message-Id: <e0c67ce4113c5fc6ec76b6154a8d35852f8b2978.1275856857.git.wferi at niif.hu>
In-Reply-To: <cover.1275856857.git.wferi at niif.hu>
References: <cover.1275856857.git.wferi at niif.hu>
From: Ferenc Wagner <wferi at niif.hu>
Date: Sun, 6 Jun 2010 16:50:12 +0200
Subject: [PATCH 4/7] start child in its own process group, and put it into the foreground


Signed-off-by: Ferenc Wagner <wferi at niif.hu>
---
 src/lxc/start.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/src/lxc/start.c b/src/lxc/start.c
index b69ac88..851d383 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -463,6 +463,7 @@ int lxc_spawn(struct lxc_handler *handler)
 	int clone_flags;
 	int failed_before_rename = 0;
 	const char *name = handler->name;
+	int ctty;
 
 	if (lxc_sync_init(handler))
 		return -1;
@@ -509,6 +510,22 @@ int lxc_spawn(struct lxc_handler *handler)
 		}
 	}
 
+	if (setpgid(handler->pid, 0)) {
+		SYSERROR("failed to create new process group");
+		goto out_delete_net;
+	}
+	DEBUG("created new process group %d", handler->pid);
+	ctty = open("/dev/tty", O_RDONLY);
+	if (ctty) {
+		int ret = tcsetpgrp(ctty, handler->pid);
+		close(ctty);
+		if (ret) {
+			SYSERROR("failed to set terminal foreground process group");
+			goto out_delete_net;
+		}
+		DEBUG("set terminal foreground process group");
+	}
+	
 	/* Tell the child to continue its initialization and wait for
 	 * it to exec or return an error
 	 */
-- 
1.6.5


>From 40bff6da66936282308a2399a1f1f4d8f3942767 Mon Sep 17 00:00:00 2001
Message-Id: <40bff6da66936282308a2399a1f1f4d8f3942767.1275856857.git.wferi at niif.hu>
In-Reply-To: <cover.1275856857.git.wferi at niif.hu>
References: <cover.1275856857.git.wferi at niif.hu>
From: Ferenc Wagner <wferi at niif.hu>
Date: Sun, 6 Jun 2010 16:55:43 +0200
Subject: [PATCH 5/7] lxc-start isn't in the foreground anymore, so TTY signals don't reach it


Signed-off-by: Ferenc Wagner <wferi at niif.hu>
---
 src/lxc/start.c |    9 ---------
 src/lxc/utils.h |   27 ---------------------------
 2 files changed, 0 insertions(+), 36 deletions(-)

diff --git a/src/lxc/start.c b/src/lxc/start.c
index 851d383..ee79892 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -129,9 +129,6 @@ int signalfd(int fd, const sigset_t *mask, int flags)
 
 lxc_log_define(lxc_start, lxc);
 
-LXC_TTY_HANDLER(SIGINT);
-LXC_TTY_HANDLER(SIGQUIT);
-
 static int match_fd(int fd)
 {
 	return (fd == 0 || fd == 1 || fd == 2);
@@ -574,10 +571,6 @@ int __lxc_start(const char *name, struct lxc_conf *conf,
 		goto out_fini;
 	}
 
-	/* Avoid signals from terminal */
-	LXC_TTY_ADD_HANDLER(SIGINT);
-	LXC_TTY_ADD_HANDLER(SIGQUIT);
-
 	err = lxc_poll(name, handler);
 	if (err) {
 		ERROR("mainloop exited with an error");
@@ -589,8 +582,6 @@ int __lxc_start(const char *name, struct lxc_conf *conf,
 
 	err =  lxc_error_set_and_log(handler->pid, status);
 out_fini:
-	LXC_TTY_DEL_HANDLER(SIGQUIT);
-	LXC_TTY_DEL_HANDLER(SIGINT);
 	lxc_unlink_nsgroup(name);
 	lxc_fini(name, handler);
 	return err;
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 114b668..b800b1e 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -23,33 +23,6 @@
 #ifndef _utils_h
 #define _utils_h
 
-#define LXC_TTY_HANDLER(s) \
-	static struct sigaction lxc_tty_sa_##s;				\
-	static void tty_##s##_handler(int sig, siginfo_t *info, void *ctx) \
-	{								\
-		if (lxc_tty_sa_##s.sa_handler == SIG_DFL ||		\
-		    lxc_tty_sa_##s.sa_handler == SIG_IGN)		\
-			return;						\
-		(*lxc_tty_sa_##s.sa_sigaction)(sig, info, ctx);	\
-	}
-
-#define LXC_TTY_ADD_HANDLER(s) \
-	do { \
-		struct sigaction sa; \
-		sa.sa_sigaction = tty_##s##_handler; \
-		sa.sa_flags = SA_SIGINFO; \
-		sigfillset(&sa.sa_mask); \
-		/* No error expected with sigaction. */ \
-		sigaction(s, &sa, &lxc_tty_sa_##s); \
-	} while (0)
-
-#define LXC_TTY_DEL_HANDLER(s) \
-	do { \
-		sigaction(s, &lxc_tty_sa_##s, NULL); \
-	} while (0)
-
-#endif
-
 extern int lxc_copy_file(const char *src, const char *dst);
 extern int lxc_setup_fs(void);
 extern int get_u16(ushort *val, const char *arg, int base);
-- 
1.6.5


>From c3b7beac193527f100bcea8fe52682700d011423 Mon Sep 17 00:00:00 2001
Message-Id: <c3b7beac193527f100bcea8fe52682700d011423.1275856857.git.wferi at niif.hu>
In-Reply-To: <cover.1275856857.git.wferi at niif.hu>
References: <cover.1275856857.git.wferi at niif.hu>
From: Ferenc Wagner <wferi at niif.hu>
Date: Sun, 6 Jun 2010 21:37:50 +0200
Subject: [PATCH 6/7] forward signals to the container init


Signed-off-by: Ferenc Wagner <wferi at niif.hu>
---
 src/lxc/start.c |   22 ++++++++++++++--------
 1 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/src/lxc/start.c b/src/lxc/start.c
index ee79892..b8ccd31 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -192,13 +192,13 @@ static int setup_sigchld_fd(sigset_t *oldmask)
 	sigset_t mask;
 	int fd;
 
-	if (sigprocmask(SIG_BLOCK, NULL, &mask)) {
-		SYSERROR("failed to get mask signal");
-		return -1;
-	}
-
-	if (sigaddset(&mask, SIGCHLD) || sigprocmask(SIG_BLOCK, &mask, oldmask)) {
-		SYSERROR("failed to set mask signal");
+	/* Block everything except serious error signals */
+	if (sigfillset(&mask) ||
+	    sigdelset(&mask, SIGILL) ||
+	    sigdelset(&mask, SIGSEGV) ||
+	    sigdelset(&mask, SIGBUS) ||
+	    sigprocmask(SIG_BLOCK, &mask, oldmask)) {
+		SYSERROR("failed to set signal mask");
 		return -1;
 	}
 
@@ -228,7 +228,7 @@ static int sigchld_handler(int fd, void *data,
 
 	ret = read(fd, &siginfo, sizeof(siginfo));
 	if (ret < 0) {
-		ERROR("failed to read sigchld info");
+		ERROR("failed to read signal info");
 		return -1;
 	}
 
@@ -237,6 +237,12 @@ static int sigchld_handler(int fd, void *data,
 		return -1;
 	}
 
+	if (siginfo.ssi_signo != SIGCHLD) {
+		kill(*pid, siginfo.ssi_signo);
+		INFO("forwarded signal %d to pid %d", siginfo.ssi_signo, *pid);
+		return 0;
+	}
+
 	if (siginfo.ssi_code == CLD_STOPPED ||
 	    siginfo.ssi_code == CLD_CONTINUED) {
 		INFO("container init process was stopped/continued");
-- 
1.6.5


>From b45ceb7514f51413b724267a657347e8088370d3 Mon Sep 17 00:00:00 2001
Message-Id: <b45ceb7514f51413b724267a657347e8088370d3.1275856857.git.wferi at niif.hu>
In-Reply-To: <cover.1275856857.git.wferi at niif.hu>
References: <cover.1275856857.git.wferi at niif.hu>
From: Ferenc Wagner <wferi at niif.hu>
Date: Sun, 6 Jun 2010 21:39:03 +0200
Subject: [PATCH 7/7] generalize the name of the signal handler


Signed-off-by: Ferenc Wagner <wferi at niif.hu>
---
 src/lxc/start.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/lxc/start.c b/src/lxc/start.c
index b8ccd31..23f148e 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -187,7 +187,7 @@ int lxc_check_inherited(int fd_to_ignore)
 	return ret;
 }
 
-static int setup_sigchld_fd(sigset_t *oldmask)
+static int setup_signal_fd(sigset_t *oldmask)
 {
 	sigset_t mask;
 	int fd;
@@ -219,7 +219,7 @@ static int setup_sigchld_fd(sigset_t *oldmask)
 	return fd;
 }
 
-static int sigchld_handler(int fd, void *data,
+static int signal_handler(int fd, void *data,
 			   struct lxc_epoll_descr *descr)
 {
 	struct signalfd_siginfo siginfo;
@@ -302,7 +302,7 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
 		goto out_sigfd;
 	}
 
-	if (lxc_mainloop_add_handler(&descr, sigfd, sigchld_handler, &pid)) {
+	if (lxc_mainloop_add_handler(&descr, sigfd, signal_handler, &pid)) {
 		ERROR("failed to add handler for the signal");
 		goto out_mainloop_open;
 	}
@@ -368,7 +368,7 @@ struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf)
 	/* the signal fd has to be created before forking otherwise
 	 * if the child process exits before we setup the signal fd,
 	 * the event will be lost and the command will be stuck */
-	handler->sigfd = setup_sigchld_fd(&handler->oldmask);
+	handler->sigfd = setup_signal_fd(&handler->oldmask);
 	if (handler->sigfd < 0) {
 		ERROR("failed to set sigchild fd handler");
 		goto out_delete_console;
@@ -399,7 +399,7 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
 	lxc_set_state(name, handler, STOPPING);
 	lxc_set_state(name, handler, STOPPED);
 
-	/* reset mask set by setup_sigchld_fd */
+	/* reset mask set by setup_signal_fd */
 	if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL))
 		WARN("failed to restore sigprocmask");
 
-- 
1.6.5





More information about the lxc-devel mailing list