[lxc-devel] [lxc/master] confile: add lxc.monitor.signal.pdeath

brauner on Github lxc-bot at linuxcontainers.org
Mon Jul 16 09:31:17 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 646 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180716/19c4b337/attachment.bin>
-------------- next part --------------
From f6e32eb05ba0b0565d67b63070a0f91da8729a28 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 16 Jul 2018 11:10:01 +0200
Subject: [PATCH 1/2] confile: move signal helpers to confile utils

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/confile.c       | 133 ------------------------------------------------
 src/lxc/confile_utils.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/lxc/confile_utils.h |   1 +
 3 files changed, 134 insertions(+), 133 deletions(-)

diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index d6eacf33b..2743dc847 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -238,90 +238,6 @@ static struct lxc_config_t config[] = {
 	{ "lxc.proc",                      set_config_proc,                        get_config_proc,                        clr_config_proc,                      },
 };
 
-struct signame {
-	int num;
-	const char *name;
-};
-
-static const struct signame signames[] = {
-	{ SIGHUP,    "HUP"    },
-	{ SIGINT,    "INT"    },
-	{ SIGQUIT,   "QUIT"   },
-	{ SIGILL,    "ILL"    },
-	{ SIGABRT,   "ABRT"   },
-	{ SIGFPE,    "FPE"    },
-	{ SIGKILL,   "KILL"   },
-	{ SIGSEGV,   "SEGV"   },
-	{ SIGPIPE,   "PIPE"   },
-	{ SIGALRM,   "ALRM"   },
-	{ SIGTERM,   "TERM"   },
-	{ SIGUSR1,   "USR1"   },
-	{ SIGUSR2,   "USR2"   },
-	{ SIGCHLD,   "CHLD"   },
-	{ SIGCONT,   "CONT"   },
-	{ SIGSTOP,   "STOP"   },
-	{ SIGTSTP,   "TSTP"   },
-	{ SIGTTIN,   "TTIN"   },
-	{ SIGTTOU,   "TTOU"   },
-#ifdef SIGTRAP
-	{ SIGTRAP,   "TRAP"   },
-#endif
-#ifdef SIGIOT
-	{ SIGIOT,    "IOT"    },
-#endif
-#ifdef SIGEMT
-	{ SIGEMT,    "EMT"    },
-#endif
-#ifdef SIGBUS
-	{ SIGBUS,    "BUS"    },
-#endif
-#ifdef SIGSTKFLT
-	{ SIGSTKFLT, "STKFLT" },
-#endif
-#ifdef SIGCLD
-	{ SIGCLD,    "CLD"    },
-#endif
-#ifdef SIGURG
-	{ SIGURG,    "URG"    },
-#endif
-#ifdef SIGXCPU
-	{ SIGXCPU,   "XCPU"   },
-#endif
-#ifdef SIGXFSZ
-	{ SIGXFSZ,   "XFSZ"   },
-#endif
-#ifdef SIGVTALRM
-	{ SIGVTALRM, "VTALRM" },
-#endif
-#ifdef SIGPROF
-	{ SIGPROF,   "PROF"   },
-#endif
-#ifdef SIGWINCH
-	{ SIGWINCH,  "WINCH"  },
-#endif
-#ifdef SIGIO
-	{ SIGIO,     "IO"     },
-#endif
-#ifdef SIGPOLL
-	{ SIGPOLL,   "POLL"   },
-#endif
-#ifdef SIGINFO
-	{ SIGINFO,   "INFO"   },
-#endif
-#ifdef SIGLOST
-	{ SIGLOST,   "LOST"   },
-#endif
-#ifdef SIGPWR
-	{ SIGPWR,    "PWR"    },
-#endif
-#ifdef SIGUNUSED
-	{ SIGUNUSED, "UNUSED" },
-#endif
-#ifdef SIGSYS
-	{ SIGSYS,    "SYS"    },
-#endif
-};
-
 static const size_t config_size = sizeof(config) / sizeof(struct lxc_config_t);
 
 struct lxc_config_t *lxc_get_config(const char *key)
@@ -1260,55 +1176,6 @@ static int set_config_autodev(const char *key, const char *value,
 	return 0;
 }
 
-static int sig_num(const char *sig)
-{
-	unsigned int signum;
-
-	if (lxc_safe_uint(sig, &signum) < 0)
-		return -1;
-
-	return signum;
-}
-
-static int rt_sig_num(const char *signame)
-{
-	int rtmax = 0, sig_n = 0;
-
-	if (strncasecmp(signame, "max-", 4) == 0) {
-		rtmax = 1;
-	}
-
-	signame += 4;
-	if (!isdigit(*signame))
-		return -1;
-
-	sig_n = sig_num(signame);
-	sig_n = rtmax ? SIGRTMAX - sig_n : SIGRTMIN + sig_n;
-	if (sig_n > SIGRTMAX || sig_n < SIGRTMIN)
-		return -1;
-
-	return sig_n;
-}
-
-static int sig_parse(const char *signame)
-{
-	size_t n;
-
-	if (isdigit(*signame)) {
-		return sig_num(signame);
-	} else if (strncasecmp(signame, "sig", 3) == 0) {
-		signame += 3;
-		if (strncasecmp(signame, "rt", 2) == 0)
-			return rt_sig_num(signame + 2);
-		for (n = 0; n < sizeof(signames) / sizeof((signames)[0]); n++) {
-			if (strcasecmp(signames[n].name, signame) == 0)
-				return signames[n].num;
-		}
-	}
-
-	return -1;
-}
-
 static int set_config_signal_halt(const char *key, const char *value,
 				 struct lxc_conf *lxc_conf, void *data)
 {
diff --git a/src/lxc/confile_utils.c b/src/lxc/confile_utils.c
index 8100cf741..ff563e0ac 100644
--- a/src/lxc/confile_utils.c
+++ b/src/lxc/confile_utils.c
@@ -778,3 +778,136 @@ int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath,
 
 	return fd;
 }
+
+struct signame {
+	int num;
+	const char *name;
+};
+
+static const struct signame signames[] = {
+	{ SIGHUP,    "HUP"    },
+	{ SIGINT,    "INT"    },
+	{ SIGQUIT,   "QUIT"   },
+	{ SIGILL,    "ILL"    },
+	{ SIGABRT,   "ABRT"   },
+	{ SIGFPE,    "FPE"    },
+	{ SIGKILL,   "KILL"   },
+	{ SIGSEGV,   "SEGV"   },
+	{ SIGPIPE,   "PIPE"   },
+	{ SIGALRM,   "ALRM"   },
+	{ SIGTERM,   "TERM"   },
+	{ SIGUSR1,   "USR1"   },
+	{ SIGUSR2,   "USR2"   },
+	{ SIGCHLD,   "CHLD"   },
+	{ SIGCONT,   "CONT"   },
+	{ SIGSTOP,   "STOP"   },
+	{ SIGTSTP,   "TSTP"   },
+	{ SIGTTIN,   "TTIN"   },
+	{ SIGTTOU,   "TTOU"   },
+#ifdef SIGTRAP
+	{ SIGTRAP,   "TRAP"   },
+#endif
+#ifdef SIGIOT
+	{ SIGIOT,    "IOT"    },
+#endif
+#ifdef SIGEMT
+	{ SIGEMT,    "EMT"    },
+#endif
+#ifdef SIGBUS
+	{ SIGBUS,    "BUS"    },
+#endif
+#ifdef SIGSTKFLT
+	{ SIGSTKFLT, "STKFLT" },
+#endif
+#ifdef SIGCLD
+	{ SIGCLD,    "CLD"    },
+#endif
+#ifdef SIGURG
+	{ SIGURG,    "URG"    },
+#endif
+#ifdef SIGXCPU
+	{ SIGXCPU,   "XCPU"   },
+#endif
+#ifdef SIGXFSZ
+	{ SIGXFSZ,   "XFSZ"   },
+#endif
+#ifdef SIGVTALRM
+	{ SIGVTALRM, "VTALRM" },
+#endif
+#ifdef SIGPROF
+	{ SIGPROF,   "PROF"   },
+#endif
+#ifdef SIGWINCH
+	{ SIGWINCH,  "WINCH"  },
+#endif
+#ifdef SIGIO
+	{ SIGIO,     "IO"     },
+#endif
+#ifdef SIGPOLL
+	{ SIGPOLL,   "POLL"   },
+#endif
+#ifdef SIGINFO
+	{ SIGINFO,   "INFO"   },
+#endif
+#ifdef SIGLOST
+	{ SIGLOST,   "LOST"   },
+#endif
+#ifdef SIGPWR
+	{ SIGPWR,    "PWR"    },
+#endif
+#ifdef SIGUNUSED
+	{ SIGUNUSED, "UNUSED" },
+#endif
+#ifdef SIGSYS
+	{ SIGSYS,    "SYS"    },
+#endif
+};
+
+static int sig_num(const char *sig)
+{
+	unsigned int signum;
+
+	if (lxc_safe_uint(sig, &signum) < 0)
+		return -1;
+
+	return signum;
+}
+
+static int rt_sig_num(const char *signame)
+{
+	int rtmax = 0, sig_n = 0;
+
+	if (strncasecmp(signame, "max-", 4) == 0) {
+		rtmax = 1;
+	}
+
+	signame += 4;
+	if (!isdigit(*signame))
+		return -1;
+
+	sig_n = sig_num(signame);
+	sig_n = rtmax ? SIGRTMAX - sig_n : SIGRTMIN + sig_n;
+	if (sig_n > SIGRTMAX || sig_n < SIGRTMIN)
+		return -1;
+
+	return sig_n;
+}
+
+int sig_parse(const char *signame)
+{
+	size_t n;
+
+	if (isdigit(*signame)) {
+		return sig_num(signame);
+	} else if (strncasecmp(signame, "sig", 3) == 0) {
+		signame += 3;
+		if (strncasecmp(signame, "rt", 2) == 0)
+			return rt_sig_num(signame + 2);
+		for (n = 0; n < sizeof(signames) / sizeof((signames)[0]); n++) {
+			if (strcasecmp(signames[n].name, signame) == 0)
+				return signames[n].num;
+		}
+	}
+
+	return -1;
+}
diff --git a/src/lxc/confile_utils.h b/src/lxc/confile_utils.h
index a5b76820e..ef11969fc 100644
--- a/src/lxc/confile_utils.h
+++ b/src/lxc/confile_utils.h
@@ -92,5 +92,6 @@ extern int lxc_get_conf_uint64(struct lxc_conf *c, char *retv, int inlen, uint64
 extern bool parse_limit_value(const char **value, rlim_t *res);
 extern int lxc_inherit_namespace(const char *lxcname_or_pid,
 				 const char *lxcpath, const char *namespace);
+extern int sig_parse(const char *signame);
 
 #endif /* __LXC_CONFILE_UTILS_H */

From 4faba94e5066a51844ec0a47bc8f5996cd40129e Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 16 Jul 2018 11:07:58 +0200
Subject: [PATCH 2/2] confile: add lxc.monitor.signal.pdeath

Set the signal to be sent to the container's init when the lxc monitor exits.
By default it is set to SIGKILL which will cause all container processes to be
killed when the lxc monitor process dies.
To ensure that containers stay alive even if lxc monitor dies set this to 0.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 doc/lxc.container.conf.sgml.in | 15 +++++++++++++++
 src/lxc/conf.c                 |  1 +
 src/lxc/conf.h                 |  1 +
 src/lxc/confile.c              | 38 ++++++++++++++++++++++++++++++++++++++
 src/lxc/start.c                | 36 +++++++++++++++++++++---------------
 5 files changed, 76 insertions(+), 15 deletions(-)

diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in
index 4b2183435..9808ade6c 100644
--- a/doc/lxc.container.conf.sgml.in
+++ b/doc/lxc.container.conf.sgml.in
@@ -2378,6 +2378,21 @@ dev/null proc/kcore none bind,relative 0 0
             </para>
           </listitem>
         </varlistentry>
+        <varlistentry>
+          <term>
+            <option>lxc.monitor.signal.pdeath</option>
+          </term>
+          <listitem>
+            <para>
+              Set the signal to be sent to the container's init when the lxc
+              monitor exits. By default it is set to SIGKILL which will cause
+              all container processes to be killed when the lxc monitor process
+              dies.
+              To ensure that containers stay alive even if lxc monitor dies set
+              this to 0.
+            </para>
+          </listitem>
+        </varlistentry>
         <varlistentry>
           <term>
             <option>lxc.group</option>
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 1ff2f5e0a..33beb43d1 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -2673,6 +2673,7 @@ struct lxc_conf *lxc_conf_init(void)
 	new->console.name[0] = '\0';
 	memset(&new->console.ringbuf, 0, sizeof(struct lxc_ringbuf));
 	new->maincmd_fd = -1;
+	new->monitor_signal_pdeath = SIGKILL;
 	new->nbd_idx = -1;
 	new->rootfs.mount = strdup(default_rootfs_mount);
 	if (!new->rootfs.mount) {
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index ea3a71dfb..f7a879c30 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -303,6 +303,7 @@ struct lxc_conf {
 
 	/* unshare the mount namespace in the monitor */
 	unsigned int monitor_unshare;
+	unsigned int monitor_signal_pdeath;
 
 	/* list of included files */
 	struct lxc_list includes;
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 2743dc847..5a18d11bf 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -111,6 +111,7 @@ lxc_config_define(log_file);
 lxc_config_define(log_level);
 lxc_config_define(log_syslog);
 lxc_config_define(monitor);
+lxc_config_define(monitor_signal_pdeath);
 lxc_config_define(mount);
 lxc_config_define(mount_auto);
 lxc_config_define(mount_fstab);
@@ -194,6 +195,7 @@ static struct lxc_config_t config[] = {
 	{ "lxc.log.level",                 set_config_log_level,                   get_config_log_level,                   clr_config_log_level,                 },
 	{ "lxc.log.syslog",                set_config_log_syslog,                  get_config_log_syslog,                  clr_config_log_syslog,                },
 	{ "lxc.monitor.unshare",           set_config_monitor,                     get_config_monitor,                     clr_config_monitor,                   },
+	{ "lxc.monitor.signal.pdeath",     set_config_monitor_signal_pdeath,       get_config_monitor_signal_pdeath,       clr_config_monitor_signal_pdeath,     },
 	{ "lxc.mount.auto",                set_config_mount_auto,                  get_config_mount_auto,                  clr_config_mount_auto,                },
 	{ "lxc.mount.entry",               set_config_mount,                       get_config_mount,                       clr_config_mount,                     },
 	{ "lxc.mount.fstab",               set_config_mount_fstab,                 get_config_mount_fstab,                 clr_config_mount_fstab,               },
@@ -976,6 +978,28 @@ static int set_config_monitor(const char *key, const char *value,
 	return -1;
 }
 
+static int set_config_monitor_signal_pdeath(const char *key, const char *value,
+					    struct lxc_conf *lxc_conf, void *data)
+{
+	if (lxc_config_value_empty(value)) {
+		lxc_conf->monitor_signal_pdeath = 0;
+		return 0;
+	}
+
+	if (strcmp(key + 12, "signal.pdeath") == 0) {
+		int sig_n;
+
+		sig_n = sig_parse(value);
+		if (sig_n < 0)
+			return -1;
+
+		lxc_conf->monitor_signal_pdeath = sig_n;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
 static int set_config_group(const char *key, const char *value,
 			    struct lxc_conf *lxc_conf, void *data)
 {
@@ -3420,6 +3444,13 @@ static int get_config_monitor(const char *key, char *retv, int inlen,
 	return lxc_get_conf_int(c, retv, inlen, c->monitor_unshare);
 }
 
+static int get_config_monitor_signal_pdeath(const char *key, char *retv,
+					    int inlen, struct lxc_conf *c,
+					    void *data)
+{
+	return lxc_get_conf_int(c, retv, inlen, c->monitor_signal_pdeath);
+}
+
 static int get_config_group(const char *key, char *retv, int inlen,
 			    struct lxc_conf *c, void *data)
 {
@@ -3971,6 +4002,13 @@ static inline int clr_config_monitor(const char *key, struct lxc_conf *c,
 	return 0;
 }
 
+static inline int clr_config_monitor_signal_pdeath(const char *key,
+						   struct lxc_conf *c, void *data)
+{
+	c->monitor_signal_pdeath = 0;
+	return 0;
+}
+
 static inline int clr_config_group(const char *key, struct lxc_conf *c,
 				   void *data)
 {
diff --git a/src/lxc/start.c b/src/lxc/start.c
index f100b9515..a13d8450c 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1047,16 +1047,19 @@ static int do_start(void *data)
 
 	lxc_sync_fini_parent(handler);
 
-	/* This prctl must be before the synchro, so if the parent dies before
-	 * we set the parent death signal, we will detect its death with the
-	 * synchro right after, otherwise we have a window where the parent can
-	 * exit before we set the pdeath signal leading to a unsupervized
-	 * container.
-	 */
-	ret = lxc_set_death_signal(SIGKILL);
-	if (ret < 0) {
-		SYSERROR("Failed to set PR_SET_PDEATHSIG to SIGKILL");
-		goto out_warn_father;
+	if (handler->conf->monitor_signal_pdeath > 0) {
+		/* This prctl must be before the synchro, so if the parent dies
+		 * before we set the parent death signal, we will detect its
+		 * death with the synchro right after, otherwise we have a
+		 * window where the parent can exit before we set the pdeath
+		 * signal leading to a unsupervized container.
+		 */
+		ret = lxc_set_death_signal(SIGKILL);
+		if (ret < 0) {
+			SYSERROR("Failed to set PR_SET_PDEATHSIG to %d",
+				 handler->conf->monitor_signal_pdeath);
+			goto out_warn_father;
+		}
 	}
 
 	ret = lxc_ambient_caps_up();
@@ -1131,11 +1134,14 @@ static int do_start(void *data)
 		if (ret < 0)
 			goto out_warn_father;
 
-		/* set{g,u}id() clears deathsignal */
-		ret = lxc_set_death_signal(SIGKILL);
-		if (ret < 0) {
-			SYSERROR("Failed to set PR_SET_PDEATHSIG to SIGKILL");
-			goto out_warn_father;
+		if (handler->conf->monitor_signal_pdeath > 0) {
+			/* set{g,u}id() clears deathsignal */
+			ret = lxc_set_death_signal(SIGKILL);
+			if (ret < 0) {
+				SYSERROR("Failed to set PR_SET_PDEATHSIG to %d",
+					 handler->conf->monitor_signal_pdeath);
+				goto out_warn_father;
+			}
 		}
 	}
 


More information about the lxc-devel mailing list