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

Stéphane Graber stgraber at ubuntu.com
Wed Mar 13 21:04:53 UTC 2013


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

-------------- 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/23aa3277/attachment.pgp>


More information about the lxc-devel mailing list