From: gkurz@linux.vnet.ibm.com Date: Thu, 29 Apr 2010 08:03:59 +0000 (+0200) Subject: lxc: introduce lxc-kill command (v4) X-Git-Tag: lxc-0.7.0~93 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e4b3fe5833cf5e8cb85389ceed8a00254c87b01f;p=thirdparty%2Flxc.git lxc: introduce lxc-kill command (v4) lxc-kill send a signal to the process 1 of the container. If this command is used on an application container ran by lxc-execute, the lxc-init will receive the signal and will forward it to the process 2 which is the command specified in the command line. Signed-off-by: Greg Kurz Signed-off-by: Michel Normand Signed-off-by: Daniel Lezcano --- diff --git a/configure.ac b/configure.ac index f82e7df75..4c8c50f4b 100644 --- a/configure.ac +++ b/configure.ac @@ -95,6 +95,7 @@ AC_CONFIG_FILES([ doc/lxc-ls.sgml doc/lxc-ps.sgml doc/lxc-cgroup.sgml + doc/lxc-kill.sgml doc/lxc.conf.sgml doc/lxc.sgml doc/common_options.sgml diff --git a/doc/Makefile.am b/doc/Makefile.am index bd96c9933..54e5f2217 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -20,6 +20,7 @@ man_MANS = \ lxc-ls.1 \ lxc-ps.1 \ lxc-cgroup.1 \ + lxc-kill.1 \ \ lxc.conf.5 \ \ diff --git a/doc/lxc-execute.sgml.in b/doc/lxc-execute.sgml.in index fe51b9bf3..7bd009807 100644 --- a/doc/lxc-execute.sgml.in +++ b/doc/lxc-execute.sgml.in @@ -86,6 +86,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA container, lxc-init has the pid 1 and the first process of the application has the pid 2. + + The above lxc-init is designed to forward received + signals to the started command. + So lxc-kill (1) sent signal is received + by the user specified command (pid 2 in the container). + diff --git a/doc/lxc-kill.sgml.in b/doc/lxc-kill.sgml.in new file mode 100644 index 000000000..c3373c6fa --- /dev/null +++ b/doc/lxc-kill.sgml.in @@ -0,0 +1,91 @@ + + + + + +mcr +"> + +]> + + + + @LXC_GENERATE_DATE@ + + + lxc-kill + 1 + IBM + + + + lxc-kill + + + Send a signal to the process 1 of the container. + + + + + + lxc-kill --name=NAME SIGNUM + + + + + Description + + + lxc-kill send + the SIGNUM signal to the first process of the container. + + + + If this command is used on an application container ran by + lxc-execute, the lxc-init will receive the signal and will forward it to + the process 2 which is the command specified in the command line. See + lxc-execute (1). + + + + &commonoptions; + + + Examples + + + To send the signal 26 to the process pi1 running in container + 123 : + + + + lxc-execute -n 123 -- pi1 -d 500000 + lxc-kill --name=123 26 + + + + + ©rights; + + &seealso; + + + + diff --git a/doc/see_also.sgml.in b/doc/see_also.sgml.in index 93b9344b9..78b99b46b 100644 --- a/doc/see_also.sgml.in +++ b/doc/see_also.sgml.in @@ -57,6 +57,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1 , + + lxc-kill + 1 + , + lxc-console 1 diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am index 4c4783df1..510bc9dca 100644 --- a/src/lxc/Makefile.am +++ b/src/lxc/Makefile.am @@ -82,7 +82,8 @@ bin_PROGRAMS = \ lxc-cgroup \ lxc-unfreeze \ lxc-checkpoint \ - lxc-restart + lxc-restart \ + lxc-kill libexec_PROGRAMS = \ lxc-init @@ -105,6 +106,7 @@ lxc_stop_SOURCES = lxc_stop.c lxc_unfreeze_SOURCES = lxc_unfreeze.c lxc_unshare_SOURCES = lxc_unshare.c lxc_wait_SOURCES = lxc_wait.c +lxc_kill_SOURCES = lxc_kill.c install-exec-local: install-soPROGRAMS mv $(DESTDIR)$(libdir)/liblxc.so $(DESTDIR)$(libdir)/liblxc.so.$(VERSION) diff --git a/src/lxc/lxc_init.c b/src/lxc/lxc_init.c index b0b7ac7c9..a34818e5f 100644 --- a/src/lxc/lxc_init.c +++ b/src/lxc/lxc_init.c @@ -46,12 +46,23 @@ static struct option options[] = { { 0, 0, 0, 0 }, }; +static int was_interrupted = 0; + int main(int argc, char *argv[]) { + + void interrupt_handler(int sig) + { + if (!was_interrupted) + was_interrupted = sig; + } + pid_t pid; int nbargs = 0; int err = -1; char **aargv; + sigset_t mask, omask; + int i; while (1) { int ret = getopt_long_only(argc, argv, "", options, NULL); @@ -75,6 +86,18 @@ int main(int argc, char *argv[]) aargv = &argv[optind]; argc -= nbargs; + sigfillset(&mask); + sigprocmask(SIG_SETMASK, &mask, &omask); + + for (i = 1; i < NSIG; i++) { + struct sigaction act; + + sigfillset(&act.sa_mask); + act.sa_flags = 0; + act.sa_handler = interrupt_handler; + sigaction(i, &act, NULL); + } + pid = fork(); if (pid < 0) @@ -82,6 +105,10 @@ int main(int argc, char *argv[]) if (!pid) { + for (i = 1; i < NSIG; i++) + signal(i, SIG_DFL); + sigprocmask(SIG_SETMASK, &omask, NULL); + if (lxc_setup_fs()) exit(err); @@ -92,6 +119,8 @@ int main(int argc, char *argv[]) exit(err); } + sigprocmask(SIG_SETMASK, &omask, NULL); + /* no need of other inherited fds but stderr */ close(fileno(stdin)); close(fileno(stdout)); @@ -102,6 +131,11 @@ int main(int argc, char *argv[]) int orphan = 0; pid_t waited_pid; + if (was_interrupted) { + kill(pid, was_interrupted); + was_interrupted = 0; + } + waited_pid = wait(&status); if (waited_pid < 0) { if (errno == ECHILD) diff --git a/src/lxc/lxc_kill.c b/src/lxc/lxc_kill.c new file mode 100644 index 000000000..3d996a5c7 --- /dev/null +++ b/src/lxc/lxc_kill.c @@ -0,0 +1,92 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2010 + * + * Authors: + * Daniel Lezcano + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include "commands.h" +#include "arguments.h" +#include "namespace.h" +#include "log.h" + +lxc_log_define(lxc_kill_ui, lxc); + +static const struct option my_longopts[] = { + LXC_COMMON_OPTIONS +}; + +static struct lxc_arguments my_args = { + .progname = "lxc-kill", + .help = "\ +--name=NAME SIGNUM\n\ +\n\ +Sends signal number SIGNUM to the first user process in container NAME\n\ +\n\ +Options :\n\ + -n, --name=NAME NAME for name of the container\n", + .options = my_longopts, + .parser = NULL, + .checker = NULL, +}; + +int main(int argc, char *argv[], char *envp[]) +{ + int ret; + pid_t pid; + int sig; + + ret = lxc_arguments_parse(&my_args, argc, argv); + if (ret) + return ret; + + ret = lxc_log_init(my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet); + if (ret) + return ret; + + if (my_args.argc) { + sig = atoi(my_args.argv[0]); + if (!sig || sig >= NSIG) { + ERROR("'%s' isn't a valid signal number", + my_args.argv[0]); + return -1; + } + } else + sig=SIGKILL; + + pid = get_init_pid(my_args.name); + if (pid < 0) { + ERROR("failed to get the init pid"); + return -1; + } + + ret = kill(pid, sig); + if (ret < 0) { + ERROR("failed to kill the init pid"); + return -1; + } + + return 0; +}