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

Reply via email to