Quoting Alexander Vladimirov (alexander.idkfa.vladimi...@gmail.com): > I remember discussion about implementing proper way to shutdown > guests using different signals, so here's a patch proposal. > It allows to use specific signal numbers to shutdown guests > gracefully, for example SIGRTMIN+4 starts poweroff.target in > systemd.
> Signed-off-by: Alexander Vladimirov <alexander.idkfa.vladimi...@gmail.com> Looks good to me. Acked-by: Serge E. Hallyn <serge.hal...@ubuntu.com> > --- > doc/lxc.conf.sgml.in | 23 ++++++++++++++ > src/lxc/conf.h | 1 + > src/lxc/confile.c | 90 > ++++++++++++++++++++++++++++++++++++++++++++++++++++ > src/lxc/stop.c | 6 +++- > 4 files changed, 119 insertions(+), 1 deletion(-) > > diff --git a/doc/lxc.conf.sgml.in b/doc/lxc.conf.sgml.in > index ae91221..8ff1f20 100644 > --- a/doc/lxc.conf.sgml.in > +++ b/doc/lxc.conf.sgml.in > @@ -130,6 +130,29 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA > 02111-1307 USA > </refsect2> > > <refsect2> > + <title>Stop signal</title> > + <para> > + Allows to specify signal name or number, sent by lxc-stop to > + shutdown the container. Different init systems could use > + different signals to perform clean shutdown sequence. Option > + allows signal to be specified in kill(1) fashion, e.g. > + SIGKILL, SIGRTMIN+14, SIGRTMAX-10 or plain number. > + </para> > + <variablelist> > + <varlistentry> > + <term> > + <option>lxc.stopsignal</option> > + </term> > + <listitem> > + <para> > + specify the signal used to stop the container > + </para> > + </listitem> > + </varlistentry> > + </variablelist> > + </refsect2> > + > + <refsect2> > <title>Network</title> > <para> > The network section defines how the network is virtualized in > diff --git a/src/lxc/conf.h b/src/lxc/conf.h > index f20fb2f..61456ae 100644 > --- a/src/lxc/conf.h > +++ b/src/lxc/conf.h > @@ -277,6 +277,7 @@ struct lxc_conf { > #endif > int maincmd_fd; > int autodev; // if 1, mount and fill a /dev at start > + int stopsignal; // signal used to stop container > char *rcfile; // Copy of the top level rcfile we read > }; > > diff --git a/src/lxc/confile.c b/src/lxc/confile.c > index d350f01..8dbe83d 100644 > --- a/src/lxc/confile.c > +++ b/src/lxc/confile.c > @@ -27,6 +27,8 @@ > #include <unistd.h> > #include <errno.h> > #include <fcntl.h> > +#include <ctype.h> > +#include <signal.h> > #include <sys/stat.h> > #include <sys/types.h> > #include <sys/param.h> > @@ -87,6 +89,7 @@ static int config_seccomp(const char *, const char *, > struct lxc_conf *); > static int config_includefile(const char *, const char *, struct lxc_conf *); > static int config_network_nic(const char *, const char *, struct lxc_conf *); > static int config_autodev(const char *, const char *, struct lxc_conf *); > +static int config_stopsignal(const char *, const char *, struct lxc_conf *); > > static struct lxc_config_t config[] = { > > @@ -134,6 +137,34 @@ static struct lxc_config_t config[] = { > { "lxc.seccomp", config_seccomp }, > { "lxc.include", config_includefile }, > { "lxc.autodev", config_autodev }, > + { "lxc.stopsignal", config_stopsignal }, > +}; > + > +struct signame { > + int num; > + char *name; > +}; > + > +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" }, > }; > > static const size_t config_size = sizeof(config)/sizeof(struct lxc_config_t); > @@ -959,6 +990,65 @@ static int config_autodev(const char *key, const char > *value, > return 0; > } > > +static int sig_num(const char *sig) > +{ > + int n; > + char *endp = NULL; > + > + errno = 0; > + n = strtol(sig, &endp, 10); > + if (sig == endp || n < 0 || errno != 0) > + return -1; > + return n; > +} > + > +static int rt_sig_num(const char *signame) > +{ > + int sig_n = 0; > + int rtmax = 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) { > + int 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 config_stopsignal(const char *key, const char *value, > + struct lxc_conf *lxc_conf) > +{ > + int sig_n = sig_parse(value); > + > + if (sig_n < 0) > + return -1; > + lxc_conf->stopsignal = sig_n; > + > + return 0; > +} > + > static int config_cgroup(const char *key, const char *value, > struct lxc_conf *lxc_conf) > { > diff --git a/src/lxc/stop.c b/src/lxc/stop.c > index 851a4bf..7fea6b6 100644 > --- a/src/lxc/stop.c > +++ b/src/lxc/stop.c > @@ -34,6 +34,7 @@ > > #include <lxc/log.h> > #include <lxc/start.h> > +#include <lxc/conf.h> > > #include "lxc.h" > #include "commands.h" > @@ -82,9 +83,12 @@ extern int lxc_stop_callback(int fd, struct lxc_request > *request, > { > struct lxc_answer answer; > int ret; > + int stopsignal = SIGKILL; > > + if (handler->conf->stopsignal) > + stopsignal = handler->conf->stopsignal; > memset(&answer, 0, sizeof(answer)); > - answer.ret = kill(handler->pid, SIGKILL); > + answer.ret = kill(handler->pid, stopsignal); > if (!answer.ret) { > ret = lxc_unfreeze_bypath(handler->cgroup); > if (!ret) > -- > 1.8.1.5 > > > ------------------------------------------------------------------------------ > Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester > Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the > endpoint security space. For insight on selecting the right partner to > tackle endpoint security challenges, access the full report. > http://p.sf.net/sfu/symantec-dev2dev > _______________________________________________ > Lxc-devel mailing list > Lxc-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/lxc-devel ------------------------------------------------------------------------------ Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the endpoint security space. For insight on selecting the right partner to tackle endpoint security challenges, access the full report. http://p.sf.net/sfu/symantec-dev2dev _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel