[lxc-devel] [PATCH/RFC] Add lxc.stopsignal config option

Stéphane Graber stgraber at ubuntu.com
Thu Mar 14 03:26:47 UTC 2013


On 03/13/2013 08:19 PM, Stéphane Graber wrote:
> On 03/13/2013 08:14 PM, Alexander Vladimirov wrote:
>> I am unable to reproduce it with my containers, can you show config
>> used to test?
> 
> http://paste.ubuntu.com/5612341/
> 
> As far as we can tell so far, the code looks fine but something is
> somehow setting the value in the struct to -1. It's not any of the
> functions you introduced, so our guess is that something else is messing
> with lxc_conf in a way it shouldn't.

Alright, we figured it out. Serge noticed that the struct wasn't the
same size in start.c than it was in commands.c. The reason was tracked
down to config.h being included late in commands.c (and a few other
places) making some members disappear in some cases.

Adding an explicit include of config.h in conf.h and start.h fixed it here.

My machine will now run through all the usual tests and I hope to send
the pull request for rc1 tomorrow morning instead.

>> 2013/3/14 Stéphane Graber <stgraber at ubuntu.com>:
>>> On 03/12/2013 09:37 AM, Serge Hallyn wrote:
>>>> Quoting Alexander Vladimirov (alexander.idkfa.vladimirov at 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.vladimirov at gmail.com>
>>>>
>>>> Looks good to me.
>>>>
>>>> Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.com>
>>>
>>> This change is causing a regression, breaking lxc-stop by default:
>>>
>>> root at castiana:~/data/code/lxc# lxc-stop -n test-lucid
>>> lxc-stop: failed to stop 'test-lucid': Operation not permitted
>>>
>>> kill(32498, -1)                         = -1 EINVAL (Invalid argument)
>>>
>>> We're looking at fixing this now before I can continue with preparing
>>> rc1 for release.
>>>
>>>>> ---
>>>>>  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 at 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 at lists.sourceforge.net
>>>> https://lists.sourceforge.net/lists/listinfo/lxc-devel
>>>>
>>>
>>>
>>> --
>>> Stéphane Graber
>>> Ubuntu developer
>>> http://www.ubuntu.com
>>>
>>>
>>> ------------------------------------------------------------------------------
>>> Everyone hates slow websites. So do we.
>>> Make your web apps faster with AppDynamics
>>> Download AppDynamics Lite for free today:
>>> http://p.sf.net/sfu/appdyn_d2d_mar
>>> _______________________________________________
>>> Lxc-devel mailing list
>>> Lxc-devel at lists.sourceforge.net
>>> https://lists.sourceforge.net/lists/listinfo/lxc-devel
>>>
> 
> 
> 
> 
> ------------------------------------------------------------------------------
> Everyone hates slow websites. So do we.
> Make your web apps faster with AppDynamics
> Download AppDynamics Lite for free today:
> http://p.sf.net/sfu/appdyn_d2d_mar
> 
> 
> 
> _______________________________________________
> Lxc-devel mailing list
> Lxc-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel
> 


-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20130313/f5c64d4e/attachment.pgp>


More information about the lxc-devel mailing list