Hi,

it bugged me that there is no "clean" way to shut down a full system
container from the outside, so I wrote the attached helper script.

It finds the "init" process for the container and sends the INT signal
to that process, which most init systems (all?) interpret as a request
to reboot the system. Changing the inittab (or whatever is cool with
current init systems) to make the system halt instead gives us a nice
way to shut down a container in a clean fashion.

Since this script may be usable for system shutdown scripts, I also
implemented a timeout, but maybe lxc-wait should be extended to provide
that functionality...

Thoughts, comments?

Greetings, Tobi

-- 
My blog: http://blog.23.gs/
GPG-Key 0xE2BEA341 - signed/encrypted mail preferred
http://www.fli4l.de/ - ISDN- & DSL-Router on one disk!
Registered FLI4L-User #00000003
#!/bin/sh
# set -ex

usage() {
        echo "Usage: $(basename $0) {--name|-n} <name> [{--wait|-w} <timeout>]"
}

help() {
        usage
        echo
        echo "send the INT signal to a specified container"
        echo "to simulate Ctrl+Alt+Del for a clean shutdown"
        echo
        echo "Options:"
        echo "name  : name of the container"
        echo "help  : this current help."
        echo "wait  : wait <timeout> seconds for the container to stop."
        echo
        echo "For proper operation the ctrlaltdel action of the"
        echo "container should halt the system."
}

name=
waittime=
for i in "$@"; do
        case $i in
                -h|--help)
                        help; exit 1;;
                -n|--name)
                        name="$2"; shift 2;;
                -w|--wait)
                        waittime="$2"; shift 2;;
        esac
done

if [ -z "$name" ]; then
        usage
        exit 1
fi

cgroups=$(mount -l -t cgroup)
cgroup_path=""

for i in "$cgroups"; do
    set -- $i
    cgroup_name=$1
    cgroup_path=$3

    if [ "$cgroup_name" = "lxc" ]; then
        break;
    fi

done

if [ -z "$cgroup_path" ]; then
    echo "no cgroup mount point found"
    exit 1
fi

init_pid=
while read pid
do
    set -- $(cat /proc/$pid/stat)
    ppid=$4
    if ! grep -q $ppid "$cgroup_path/$name/tasks"
    then
        init_pid=$pid
        break
    fi
done < "$cgroup_path/$name/tasks"

if [ -z "$init_pid" ]; then
    echo "no process found for '$name'"
    exit 1
fi

kill -s INT $init_pid

if [ "$waittime" ]; then
        while [ "$waittime" -gt 0 ]; do
                if lxc-info -n "$name" | grep -q 'is STOPPED'
                then
                        exit 0
                fi
                sleep 1
                waittime=$((waittime - 1))
        done
        exit 1
fi

Attachment: signature.asc
Description: Digital signature

------------------------------------------------------------------------------
Achieve unprecedented app performance and reliability
What every C/C++ and Fortran developer should know.
Learn how Intel has extended the reach of its next-generation tools
to help boost performance applications - inlcuding clusters.
http://p.sf.net/sfu/intel-dev2devmay
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to