Commit f0f1d8c0 by Dwight Engen Committed by Stéphane Graber

add lxc.haltsignal for soft shutdown

- use this in the busybox template since busybox's init expects to receive SIGUSR1 to halt - fix lxc.stopsignal to be output by write_config so lxcapi_clone() and lxcapi_save_config() will output it Signed-off-by: 's avatarDwight Engen <dwight.engen@oracle.com> Acked-by: 's avatarStéphane Graber <stgraber@ubuntu.com>
parent 19a85f1f
...@@ -65,13 +65,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ...@@ -65,13 +65,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<para> <para>
<command>lxc-stop</command> reboots, cleanly shuts down, or kills <command>lxc-stop</command> reboots, cleanly shuts down, or kills
all the processes inside the container. By default, it will all the processes inside the container. By default, it will
request a clean shutdown of the container (by sending SIGPWR to request a clean shutdown of the container by sending
the container), wait 60 seconds for the container to exit, and <command>lxc.haltsignal</command> (defaults to SIGPWR) to
returns. If the container fails to cleanly exit, then after 60 the container's init process, waiting up to 60 seconds for the container
seconds the container will be sent the to exit, and then returning. If the container fails to cleanly exit in
<command>lxc.stopsignal</command> to force it to shut down. If 60 seconds, it will be sent the <command>lxc.stopsignal</command>
<command>lxc.stopsignal</command> is not specified, the signal sent is (defaults to SIGKILL) to force it to shut down.
SIGKILL.
</para> </para>
<para> <para>
The <optional>-W</optional>, <optional>-r</optional>, The <optional>-W</optional>, <optional>-r</optional>,
......
...@@ -156,13 +156,36 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ...@@ -156,13 +156,36 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
</refsect2> </refsect2>
<refsect2> <refsect2>
<title>Halt signal</title>
<para>
Allows one to specify signal name or number, sent by lxc-stop to the
container's init process to cleanly shutdown the container. Different
init systems could use different signals to perform clean shutdown
sequence. This option allows the signal to be specified in kill(1)
fashion, e.g. SIGPWR, SIGRTMIN+14, SIGRTMAX-10 or plain number. The
default signal is SIGPWR.
</para>
<variablelist>
<varlistentry>
<term>
<option>lxc.haltsignal</option>
</term>
<listitem>
<para>
specify the signal used to halt the container
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect2>
<title>Stop signal</title> <title>Stop signal</title>
<para> <para>
Allows one to specify signal name or number, sent by lxc-stop to Allows one to specify signal name or number, sent by lxc-stop to forcibly
shutdown the container. Different init systems could use shutdown the container. This option allows signal to be specified in
different signals to perform clean shutdown sequence. Option kill(1) fashion, e.g. SIGKILL, SIGRTMIN+14, SIGRTMAX-10 or plain number.
allows signal to be specified in kill(1) fashion, e.g. The default signal is SIGKILL.
SIGKILL, SIGRTMIN+14, SIGRTMAX-10 or plain number.
</para> </para>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
......
...@@ -307,7 +307,8 @@ struct lxc_conf { ...@@ -307,7 +307,8 @@ struct lxc_conf {
#endif #endif
int maincmd_fd; int maincmd_fd;
int autodev; // if 1, mount and fill a /dev at start int autodev; // if 1, mount and fill a /dev at start
int stopsignal; // signal used to stop container int haltsignal; // signal used to halt container
int stopsignal; // signal used to hard stop container
int kmsg; // if 1, create /dev/kmsg symlink int kmsg; // if 1, create /dev/kmsg symlink
char *rcfile; // Copy of the top level rcfile we read char *rcfile; // Copy of the top level rcfile we read
......
...@@ -90,6 +90,7 @@ static int config_seccomp(const char *, const char *, struct lxc_conf *); ...@@ -90,6 +90,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_includefile(const char *, const char *, struct lxc_conf *);
static int config_network_nic(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_autodev(const char *, const char *, struct lxc_conf *);
static int config_haltsignal(const char *, const char *, struct lxc_conf *);
static int config_stopsignal(const char *, const char *, struct lxc_conf *); static int config_stopsignal(const char *, const char *, struct lxc_conf *);
static int config_start(const char *, const char *, struct lxc_conf *); static int config_start(const char *, const char *, struct lxc_conf *);
static int config_group(const char *, const char *, struct lxc_conf *); static int config_group(const char *, const char *, struct lxc_conf *);
...@@ -142,6 +143,7 @@ static struct lxc_config_t config[] = { ...@@ -142,6 +143,7 @@ static struct lxc_config_t config[] = {
{ "lxc.seccomp", config_seccomp }, { "lxc.seccomp", config_seccomp },
{ "lxc.include", config_includefile }, { "lxc.include", config_includefile },
{ "lxc.autodev", config_autodev }, { "lxc.autodev", config_autodev },
{ "lxc.haltsignal", config_haltsignal },
{ "lxc.stopsignal", config_stopsignal }, { "lxc.stopsignal", config_stopsignal },
{ "lxc.start.auto", config_start }, { "lxc.start.auto", config_start },
{ "lxc.start.delay", config_start }, { "lxc.start.delay", config_start },
...@@ -1108,6 +1110,16 @@ static int rt_sig_num(const char *signame) ...@@ -1108,6 +1110,16 @@ static int rt_sig_num(const char *signame)
return sig_n; return sig_n;
} }
static const char *sig_name(int signum) {
int n;
for (n = 0; n < sizeof(signames) / sizeof((signames)[0]); n++) {
if (n == signames[n].num)
return signames[n].name;
}
return "";
}
static int sig_parse(const char *signame) { static int sig_parse(const char *signame) {
int n; int n;
...@@ -1125,6 +1137,18 @@ static int sig_parse(const char *signame) { ...@@ -1125,6 +1137,18 @@ static int sig_parse(const char *signame) {
return -1; return -1;
} }
static int config_haltsignal(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->haltsignal = sig_n;
return 0;
}
static int config_stopsignal(const char *key, const char *value, static int config_stopsignal(const char *key, const char *value,
struct lxc_conf *lxc_conf) struct lxc_conf *lxc_conf)
{ {
...@@ -2119,6 +2143,10 @@ void write_config(FILE *fout, struct lxc_conf *c) ...@@ -2119,6 +2143,10 @@ void write_config(FILE *fout, struct lxc_conf *c)
fprintf(fout, "lxc.pts = %d\n", c->pts); fprintf(fout, "lxc.pts = %d\n", c->pts);
if (c->ttydir) if (c->ttydir)
fprintf(fout, "lxc.devttydir = %s\n", c->ttydir); fprintf(fout, "lxc.devttydir = %s\n", c->ttydir);
if (c->haltsignal)
fprintf(fout, "lxc.haltsignal = SIG%s\n", sig_name(c->haltsignal));
if (c->stopsignal)
fprintf(fout, "lxc.stopsignal = SIG%s\n", sig_name(c->stopsignal));
#if HAVE_SYS_PERSONALITY_H #if HAVE_SYS_PERSONALITY_H
switch(c->personality) { switch(c->personality) {
case PER_LINUX32: fprintf(fout, "lxc.arch = x86\n"); break; case PER_LINUX32: fprintf(fout, "lxc.arch = x86\n"); break;
......
...@@ -1307,6 +1307,7 @@ static bool lxcapi_shutdown(struct lxc_container *c, int timeout) ...@@ -1307,6 +1307,7 @@ static bool lxcapi_shutdown(struct lxc_container *c, int timeout)
{ {
bool retv; bool retv;
pid_t pid; pid_t pid;
int haltsignal = SIGPWR;
if (!c) if (!c)
return false; return false;
...@@ -1318,7 +1319,9 @@ static bool lxcapi_shutdown(struct lxc_container *c, int timeout) ...@@ -1318,7 +1319,9 @@ static bool lxcapi_shutdown(struct lxc_container *c, int timeout)
pid = c->init_pid(c); pid = c->init_pid(c);
if (pid <= 0) if (pid <= 0)
return true; return true;
kill(pid, SIGPWR); if (c->lxc_conf->haltsignal)
haltsignal = c->lxc_conf->haltsignal;
kill(pid, haltsignal);
retv = c->wait(c, "STOPPED", timeout); retv = c->wait(c, "STOPPED", timeout);
if (!retv && timeout > 0) { if (!retv && timeout > 0) {
c->stop(c); c->stop(c);
......
...@@ -272,6 +272,7 @@ copy_configuration() ...@@ -272,6 +272,7 @@ copy_configuration()
grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
cat <<EOF >> $path/config cat <<EOF >> $path/config
lxc.haltsignal = SIGUSR1
lxc.utsname = $name lxc.utsname = $name
lxc.tty = 1 lxc.tty = 1
lxc.pts = 1 lxc.pts = 1
......
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