Unverified Commit 112a5798 by Stéphane Graber Committed by GitHub

Merge pull request #2470 from brauner/2018-07-16/monitor_signal_pdeath

confile: add lxc.monitor.signal.pdeath
parents 63f9c9e6 258f8051
...@@ -2380,6 +2380,21 @@ dev/null proc/kcore none bind,relative 0 0 ...@@ -2380,6 +2380,21 @@ dev/null proc/kcore none bind,relative 0 0
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <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> <option>lxc.group</option>
</term> </term>
<listitem> <listitem>
......
...@@ -2673,6 +2673,7 @@ struct lxc_conf *lxc_conf_init(void) ...@@ -2673,6 +2673,7 @@ struct lxc_conf *lxc_conf_init(void)
new->console.name[0] = '\0'; new->console.name[0] = '\0';
memset(&new->console.ringbuf, 0, sizeof(struct lxc_ringbuf)); memset(&new->console.ringbuf, 0, sizeof(struct lxc_ringbuf));
new->maincmd_fd = -1; new->maincmd_fd = -1;
new->monitor_signal_pdeath = SIGKILL;
new->nbd_idx = -1; new->nbd_idx = -1;
new->rootfs.mount = strdup(default_rootfs_mount); new->rootfs.mount = strdup(default_rootfs_mount);
if (!new->rootfs.mount) { if (!new->rootfs.mount) {
......
...@@ -303,6 +303,7 @@ struct lxc_conf { ...@@ -303,6 +303,7 @@ struct lxc_conf {
/* unshare the mount namespace in the monitor */ /* unshare the mount namespace in the monitor */
unsigned int monitor_unshare; unsigned int monitor_unshare;
unsigned int monitor_signal_pdeath;
/* list of included files */ /* list of included files */
struct lxc_list includes; struct lxc_list includes;
......
...@@ -111,6 +111,7 @@ lxc_config_define(log_file); ...@@ -111,6 +111,7 @@ lxc_config_define(log_file);
lxc_config_define(log_level); lxc_config_define(log_level);
lxc_config_define(log_syslog); lxc_config_define(log_syslog);
lxc_config_define(monitor); lxc_config_define(monitor);
lxc_config_define(monitor_signal_pdeath);
lxc_config_define(mount); lxc_config_define(mount);
lxc_config_define(mount_auto); lxc_config_define(mount_auto);
lxc_config_define(mount_fstab); lxc_config_define(mount_fstab);
...@@ -194,6 +195,7 @@ static struct lxc_config_t config[] = { ...@@ -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.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.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.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.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.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, }, { "lxc.mount.fstab", set_config_mount_fstab, get_config_mount_fstab, clr_config_mount_fstab, },
...@@ -238,90 +240,6 @@ static struct lxc_config_t config[] = { ...@@ -238,90 +240,6 @@ static struct lxc_config_t config[] = {
{ "lxc.proc", set_config_proc, get_config_proc, clr_config_proc, }, { "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); static const size_t config_size = sizeof(config) / sizeof(struct lxc_config_t);
struct lxc_config_t *lxc_get_config(const char *key) struct lxc_config_t *lxc_get_config(const char *key)
...@@ -1060,6 +978,28 @@ static int set_config_monitor(const char *key, const char *value, ...@@ -1060,6 +978,28 @@ static int set_config_monitor(const char *key, const char *value,
return -1; 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, static int set_config_group(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data) struct lxc_conf *lxc_conf, void *data)
{ {
...@@ -1260,55 +1200,6 @@ static int set_config_autodev(const char *key, const char *value, ...@@ -1260,55 +1200,6 @@ static int set_config_autodev(const char *key, const char *value,
return 0; 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, static int set_config_signal_halt(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data) struct lxc_conf *lxc_conf, void *data)
{ {
...@@ -3553,6 +3444,13 @@ static int get_config_monitor(const char *key, char *retv, int inlen, ...@@ -3553,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); 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, static int get_config_group(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data) struct lxc_conf *c, void *data)
{ {
...@@ -4104,6 +4002,13 @@ static inline int clr_config_monitor(const char *key, struct lxc_conf *c, ...@@ -4104,6 +4002,13 @@ static inline int clr_config_monitor(const char *key, struct lxc_conf *c,
return 0; 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, static inline int clr_config_group(const char *key, struct lxc_conf *c,
void *data) void *data)
{ {
......
...@@ -778,3 +778,136 @@ int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath, ...@@ -778,3 +778,136 @@ int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath,
return fd; 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;
}
...@@ -92,5 +92,6 @@ extern int lxc_get_conf_uint64(struct lxc_conf *c, char *retv, int inlen, uint64 ...@@ -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 bool parse_limit_value(const char **value, rlim_t *res);
extern int lxc_inherit_namespace(const char *lxcname_or_pid, extern int lxc_inherit_namespace(const char *lxcname_or_pid,
const char *lxcpath, const char *namespace); const char *lxcpath, const char *namespace);
extern int sig_parse(const char *signame);
#endif /* __LXC_CONFILE_UTILS_H */ #endif /* __LXC_CONFILE_UTILS_H */
...@@ -1370,6 +1370,15 @@ static int do_start(void *data) ...@@ -1370,6 +1370,15 @@ static int do_start(void *data)
goto out_warn_father; goto out_warn_father;
} }
if (handler->conf->monitor_signal_pdeath != SIGKILL) {
ret = lxc_set_death_signal(handler->conf->monitor_signal_pdeath);
if (ret < 0) {
SYSERROR("Failed to set PR_SET_PDEATHSIG to %d",
handler->conf->monitor_signal_pdeath);
goto out_warn_father;
}
}
/* After this call, we are in error because this ops should not return /* After this call, we are in error because this ops should not return
* as it execs. * as it execs.
*/ */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment