On 05/17/2013 03:15 PM, Serge Hallyn wrote: > implement c->reboot(c) in the api. Remove lxc-shutdown.in, the > bash script. Replace it with lxc_shutdown.c which uses the > API.
Thanks for those changes. As we briefly discussed on IRC, I think we should rework a bit the set of binaries we have to stop containers, move to a single one that tries to "do the right thing" by default. So my suggestion is basically to: - Kill lxc-shutdown - Change lxc-stop so that: * Default behaviour is to call shutdown(), wait 15s for STOPPED, if not STOPPED, print a message to the user and call stop() * We have a -r option to reboot the container (with proper check that the container indeed rebooted within the next 15s) * We have a -s option to shutdown the container without the automatic fallback to stop() * Add a -k option allowing a user to just kill a container (equivalent to old lxc-stop, no shutdown() call and no delay). We'd therefore end up with a single binary which does shutdown, stop and reboot, properly checks that the actions are carried out and supports timing out and fallback to kill. The 15s timeout would be over-ridable through -t, 15s is a guess as to how long users would be ready to wait for a container to die assuming some complex processes (database and similar) need enough time to sync their data and exit. Does that sound reasonable to everyone? > Signed-off-by: Serge Hallyn <serge.hal...@ubuntu.com> > --- > configure.ac | 1 - > src/lxc/Makefile.am | 3 +- > src/lxc/arguments.h | 4 +- > src/lxc/lxc-shutdown.in | 165 > ------------------------------------------------ > src/lxc/lxc_shutdown.c | 117 ++++++++++++++++++++++++++++++++++ > src/lxc/lxccontainer.c | 18 ++++++ > src/lxc/lxccontainer.h | 2 + > 7 files changed, 142 insertions(+), 168 deletions(-) > delete mode 100644 src/lxc/lxc-shutdown.in > create mode 100644 src/lxc/lxc_shutdown.c > > diff --git a/configure.ac b/configure.ac > index 414d71b..83d997b 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -383,7 +383,6 @@ AC_CONFIG_FILES([ > src/lxc/lxc-checkconfig > src/lxc/lxc-version > src/lxc/lxc-create > - src/lxc/lxc-shutdown > src/lxc/lxc-start-ephemeral > src/lxc/lxc-destroy > src/lxc/legacy/lxc-ls > diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am > index 4a19061..ce79904 100644 > --- a/src/lxc/Makefile.am > +++ b/src/lxc/Makefile.am > @@ -124,7 +124,6 @@ bin_SCRIPTS = \ > lxc-checkconfig \ > lxc-version \ > lxc-create \ > - lxc-shutdown \ > lxc-destroy > > EXTRA_DIST = \ > @@ -147,6 +146,7 @@ endif > bin_PROGRAMS = \ > lxc-attach \ > lxc-unshare \ > + lxc-shutdown \ > lxc-stop \ > lxc-start \ > lxc-clone \ > @@ -191,6 +191,7 @@ lxc_restart_SOURCES = lxc_restart.c > lxc_clone_SOURCES = lxc_clone.c > lxc_start_SOURCES = lxc_start.c > lxc_stop_SOURCES = lxc_stop.c > +lxc_shutdown_SOURCES = lxc_shutdown.c > lxc_unfreeze_SOURCES = lxc_unfreeze.c > lxc_unshare_SOURCES = lxc_unshare.c > lxc_wait_SOURCES = lxc_wait.c > diff --git a/src/lxc/arguments.h b/src/lxc/arguments.h > index 002a919..a0f0fc9 100644 > --- a/src/lxc/arguments.h > +++ b/src/lxc/arguments.h > @@ -61,9 +61,11 @@ struct lxc_arguments { > int ttynum; > char escape; > > - /* for lxc-wait */ > + /* for lxc-wait and lxc-shutdown */ > char *states; > long timeout; > + int wait; > + int reboot; > > /* close fds from parent? */ > int close_all_fds; > diff --git a/src/lxc/lxc-shutdown.in b/src/lxc/lxc-shutdown.in > deleted file mode 100644 > index c81e736..0000000 > --- a/src/lxc/lxc-shutdown.in > +++ /dev/null > @@ -1,165 +0,0 @@ > -#!/bin/sh > - > -# (C) Copyright Canonical 2011,2012 > - > -# 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 > - > -set -e > - > -. @DATADIR@/lxc/lxc.functions > - > -usage() { > - echo "usage: lxc-shutdown -n name [-w] [-r] [-P lxcpath]" > - echo " Cleanly shut down a container." > - echo " -w: wait for shutdown to complete." > - echo " -r: reboot (ignore -w)." > - echo " -t timeout: wait at most timeout seconds (implies -w), then kill" > - echo " the container." > - echo " -P lxcpath: path to the lxc container directories." > -} > - > -alarm() { > - trap 'exit 0' TERM > - pid=$1 > - timeout=$2 > - sleep $timeout > - kill $pid > -} > - > -dolxcstop() > -{ > - echo "Calling lxc-stop on $lxc_name" > - lxc-stop -n $lxc_name -P "$lxc_path" > - exit 0 > -} > - > -usage_err() { > - [ -n "$1" ] && echo "$1" >&2 > - usage > - exit 1 > -} > - > -optarg_check() { > - [ -n "$2" ] || usage_err "option '$1' requires an argument" > -} > - > -timeout="-1" > - > -reboot=0 > -dowait=0 > - > -while [ $# -gt 0 ]; do > - opt="$1" > - shift > - case "$opt" in > - -h|--help) > - usage > - exit 0 > - ;; > - -n|--name) > - optarg_check $opt "$1" > - lxc_name=$1 > - shift > - ;; > - -w|--wait) > - dowait=1 > - ;; > - -r|--reboot) > - reboot=1 > - ;; > - -t|--timeout) > - optarg_check $opt "$1" > - timeout=$1 > - dowait=1 > - shift > - ;; > - -P|--lxcpath) > - optarg_check $opt "$1" > - lxc_path=$1 > - dowait=1 > - shift > - ;; > - --) > - break;; > - -?) > - usage_err "unknown option '$opt'" > - ;; > - -*) > - # split opts -abc into -a -b -c > - set -- $(echo "${opt#-}" | sed 's/\(.\)/ -\1/g') "$@" > - ;; > - *) > - usage_err "unknown option '$opt'" > - exit 1 > - ;; > - esac > -done > - > -if [ -z "$lxc_name" ]; then > - echo "no container name specified" > - usage > - exit 1 > -fi > - > -if [ ! -d "$lxc_path" ]; then > - echo "$lxc_path: no such directory" > - exit 1 > -fi > - > -if [ "$(id -u)" != "0" ]; then > - echo "This command has to be run as root" > - exit 1 > -fi > - > -which lxc-info > /dev/null 2>&1 || { echo "lxc-info not found."; exit 1; } > -which lxc-wait > /dev/null 2>&1 || { echo "lxc-wait not found."; exit 1; } > - > -pid=`lxc-info -n $lxc_name -P "$lxc_path" -p 2>/dev/null | awk '{ print $2 > }'` > -if [ "$pid" = "-1" ]; then > - echo "$lxc_name is not running" > - exit 1 > -fi > - > -if [ $reboot -eq 1 ]; then > - kill -s INT $pid > - exit 0 > -else > - kill -s PWR $pid > -fi > - > -if [ $dowait -eq 0 ]; then > - exit 0 > -fi > - > -if [ $timeout != "-1" ]; then > - trap dolxcstop EXIT > - alarm $$ $timeout 2>/dev/null & > - alarmpid=$! > -fi > - > -while ! lxc-info -n $lxc_name -P "$lxc_path" --state-is STOPPED; do > - sleep 1 > -done > - > -if [ $timeout != "-1" ]; then > - trap - EXIT > - # include subprocesses; otherwise, we may have to wait until sleep > completes > - # if called from a non-interactive context > - kill $alarmpid $(ps --no-headers --ppid $alarmpid -o pid) 2>/dev/null || > : > -fi > - > -echo "Container $lxc_name has shut down" > - > -exit 0 > diff --git a/src/lxc/lxc_shutdown.c b/src/lxc/lxc_shutdown.c > new file mode 100644 > index 0000000..c9b5083 > --- /dev/null > +++ b/src/lxc/lxc_shutdown.c > @@ -0,0 +1,117 @@ > +/* > + * > + * Copyright © 2013 Serge Hallyn <serge.hal...@ubuntu.com>. > + * Copyright © 2013 Canonical Ltd. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2, as > + * published by the Free Software Foundation. > + * > + * This program 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 General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License along > + * with this program; if not, write to the Free Software Foundation, Inc., > + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > + */ > + > +#include "../lxc/lxccontainer.h" > + > +/* > + * usage: > + lxc-shutdown -h > + usage: lxc-shutdown -n name [-w] [-r] [-P lxcpath] > + Cleanly shut down a container. > + -w: wait for shutdown to complete. > + -r: reboot (ignore -w). > + -t timeout: wait at most timeout seconds (implies -w), then kill > + the container. > + -P lxcpath: path to the lxc container directories. > +*/ > + > +#include <stdio.h> > +#include <libgen.h> > +#include <unistd.h> > +#include <sys/types.h> > + > +#include <lxc/lxc.h> > +#include <lxc/log.h> > + > +#include "arguments.h" > +#include "utils.h" > + > +lxc_log_define(lxc_shutdown, lxc); > + > +static int my_parser(struct lxc_arguments* args, int c, char* arg) > +{ > + switch (c) { > + case 'r': args->reboot = 1; break; > + case 'w': args->wait = 1; break; > + case 't': args->timeout = atoi(arg); break; > + } > + return 0; > +} > + > +static const struct option my_longopts[] = { > + {"reboot", no_argument, 0, 'r'}, > + {"wait", no_argument, 0, 'w'}, > + {"timeout", required_argument, 0, 't'}, > + LXC_COMMON_OPTIONS > +}; > + > +static struct lxc_arguments my_args = { > + .progname = "lxc-shutdown", > + .help = "\ > +--name=NAME [-w] [-r] [-t timeout] [-P lxcpath]\n\ > +\n\ > +lxc-stop stops a container with the identifier NAME\n\ > +\n\ > +Options :\n\ > + -n, --name=NAME NAME for name of the container\n\ > + -t, --timeout=T wait T seconds before hardkilling\n\ > + -w, --wait wait for the container to shut down\n\ > + -r, --reboot reboot the container (ignore wait)\n", > + .options = my_longopts, > + .parser = my_parser, > + .checker = NULL, > +}; > + > +int main(int argc, char *argv[]) > +{ > + struct lxc_container *c; > + > + /* this is a short term test. We'll probably want to check for > + * write access to lxcpath instead */ > + if (geteuid()) { > + fprintf(stderr, "%s must be run as root\n", argv[0]); > + exit(1); > + } > + > + if (lxc_arguments_parse(&my_args, argc, argv)) > + exit(1); > + > + if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, > + my_args.progname, my_args.quiet, my_args.lxcpath[0])) > + exit(1); > + > + c = lxc_container_new(my_args.name, my_args.lxcpath[0]); > + if (!c) { > + fprintf(stderr, "System error loading container\n"); > + exit(1); > + } > + > + if (!c->is_running(c)) { > + fprintf(stderr, "%s is not running\n", my_args.name); > + exit(1); > + } > + > + if (my_args.reboot) > + exit(c->reboot(c) ? 0 : 1); > + > + if (!c->shutdown(c, my_args.timeout)) > + exit(c->wait(c, "STOPPED", -1) ? 0 : 1); > + > + exit(0); > +} > diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c > index 23db6f2..2126c89 100644 > --- a/src/lxc/lxccontainer.c > +++ b/src/lxc/lxccontainer.c > @@ -689,6 +689,23 @@ out: > return bret; > } > > +static bool lxcapi_reboot(struct lxc_container *c) > +{ > + pid_t pid; > + > + if (!c) > + return false; > + if (!c->is_running(c)) > + return false; > + pid = c->init_pid(c); > + if (pid <= 0) > + return false; > + if (kill(pid, SIGINT) < 0) > + return false; > + return true; > + > +} > + > static bool lxcapi_shutdown(struct lxc_container *c, int timeout) > { > bool retv; > @@ -1635,6 +1652,7 @@ struct lxc_container *lxc_container_new(const char > *name, const char *configpath > c->create = lxcapi_create; > c->createl = lxcapi_createl; > c->shutdown = lxcapi_shutdown; > + c->reboot = lxcapi_reboot; > c->clear_config_item = lxcapi_clear_config_item; > c->get_config_item = lxcapi_get_config_item; > c->get_cgroup_item = lxcapi_get_cgroup_item; > diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h > index 67fbed4..c718d14 100644 > --- a/src/lxc/lxccontainer.h > +++ b/src/lxc/lxccontainer.h > @@ -50,6 +50,8 @@ struct lxc_container { > bool (*save_config)(struct lxc_container *c, const char *alt_file); > bool (*create)(struct lxc_container *c, char *t, char *const argv[]); > bool (*createl)(struct lxc_container *c, char *t, ...); > + /* send SIGINT to ask container to reboot */ > + bool (*reboot)(struct lxc_container *c); > /* send SIGPWR. if timeout is not 0 or -1, do a hard stop after > timeout seconds */ > bool (*shutdown)(struct lxc_container *c, int timeout); > /* clear all network or capability items in the in-memory configuration > */ > -- Stéphane Graber Ubuntu developer http://www.ubuntu.com
signature.asc
Description: OpenPGP digital signature
------------------------------------------------------------------------------ AlienVault Unified Security Management (USM) platform delivers complete security visibility with the essential security capabilities. Easily and efficiently configure, manage, and operate all of your security controls from a single console and one unified framework. Download a free trial. http://p.sf.net/sfu/alienvault_d2d
_______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel