-#!/bin/bash
-
-# based on Tony Risinger code from lxc-users
+#!/bin/sh
+
+# lxc-watchdog.sh
+#
+# Dobrica Pavlinusic <dpavlin@rot13.org> 2010-03-15
+#
+# this script can be used to start/stop Linux containers
+# using clever inotify hack to monitor halt/reboot from
+# Tony Risinger posted to lxc-users mailing list
+#
# http://www.mail-archive.com/lxc-users@lists.sourceforge.net/msg00074.html
+
which inotifywait >/dev/null || apt-get install inotify-tools
-name=$1
+lxc_status() {
+ lxc-ls -1 | sort -u | xargs -i lxc-info -n {}
+}
+
+lxc_exists() {
+ name=$1
+
+ if [ ! -e /var/lib/lxc/$name/config ] ; then
+ echo "Usage: $0 name"
+ lxc_status
+ exit 1
+ fi
+}
+
+
+lxc_rootfs() {
+ grep lxc.rootfs "/var/lib/lxc/$1/config" | cut -d= -f2 | sed 's/^ *//'
+}
-if [ ! -e /var/lib/lxc/$name/config ] ; then
- echo "Usage: $0 name"
- ls /var/lib/lxc/*/config | cut -d/ -f5
- exit 1
-fi
-rootfs=`grep lxc.rootfs /var/lib/lxc/$name/config | cut -d= -f2`
-echo "$name rootfs $rootfs"
+cleanup_init_scripts() {
+ rootfs=$(lxc_rootfs $1)
+ ls \
+ $rootfs/etc/rc?.d/*umountfs \
+ $rootfs/etc/rc?.d/*umountroot \
+ $rootfs/etc/rc?.d/*hwclock* \
+ 2>/dev/null | xargs -i rm -v {}
+}
-# cleanup init scripts which don't work in containers
-ls \
- $rootfs/etc/rc?.d/*umountfs \
- $rootfs/etc/rc?.d/*umountroot \
- $rootfs/etc/rc?.d/*hwclock* \
-2>/dev/null | xargs -i rm -v {}
+setup_inittab() {
+ rootfs=$(lxc_rootfs $1)
+
+ # let container respond to kill -SIGPWR
+ inittab=$rootfs/etc/inittab
+ powerfail="pw::powerfail:/sbin/init 0"
+ if ! grep "$powerfail" ${inittab} >/dev/null ; then
+ grep -v ::power ${inittab} > ${inittab}.new
+ echo $powerfail >> ${inittab}.new
+ mv ${inittab}.new ${inittab}
+ echo "$initab modified"
+ fi
-# let container respond to kill -SIGPWR
-inittab=$rootfs/etc/inittab
-powerfail="pw::powerfail:/sbin/init 0"
-if ! grep "$powerfail" ${inittab} >/dev/null ; then
- grep -v ::power ${inittab} > ${inittab}.new
- echo $powerfail >> ${inittab}.new
- mv ${inittab}.new ${inittab}
- echo "$initab modified"
-fi
+}
-if [ "$2" == "stop" ] ; then
- echo "$name stop"
- kill -SIGPWR `lxc-ps -C init -o pid | grep "^$name" | cut -d" " -f2-`
+lxc_stop() {
+ name=$1
+
+ init_pid=`lxc-ps -C init -o pid | grep "^$name" | cut -d" " -f2-`
+ if [ -z "$init_pid" ] ; then
+ lxc-info -n $name
+ exit 1
+ fi
+ echo "$name stop $init_pid"
+ /bin/kill -SIGPWR $init_pid
lxc-wait -n $name -s STOPPED
- exit
-fi
+
+}
-if ! lxc-info -n $name | grep RUNNING ; then
- echo "$name start"
- lxc-start -n $name -o /tmp/${name}.log -d
- lxc-wait -n $name -s RUNNING
- lxc-info -n $name
-fi
+lxc_start() {
+ name=$1
+
+ if ! lxc-info -n $name | grep RUNNING ; then
+ echo "$name start"
+ lxc-start -n $name -o /tmp/${name}.log -d
+ lxc-wait -n $name -s RUNNING
+ lxc-info -n $name
+ fi
+}
+
+lxc_watchdog() {
+name=$1
+rootfs=$(lxc_rootfs $1)
while true; do
# time of 5 minutes on it JUST IN CASE...
vps_utmp=${rootfs}/var/run/utmp
inotifywait -qqt 300 ${vps_utmp}
- if [ $(wc -l < /cgroup/${name}/tasks) -eq 1 ]; then
+ tasks=`wc -l < /cgroup/${name}/tasks`
+ test -z "$tasks" && exit 1
+ if [ "$tasks" -eq 1 ]; then
runlevel="$(runlevel ${vps_utmp})"
echo "# $name runlevel $runlevel"
??0)
echo "$name halt"
lxc-stop -n "${name}"
+ lxc-wait -n ${name} -s STOPPED
break
;;
??6)
echo "$name reboot";
lxc-stop -n ${name}
lxc-wait -n ${name} -s STOPPED
- mount /mnt/llin -o remount,rw
lxc-start -d -n ${name} -o /tmp/${name}.log
;;
*)
[ "$state" = "RUNNING" ] || break
;;
esac
+ else
+ echo "# $name $tasks tasks"
fi
done
+echo "${name} exited"
+
+}
+
+
+case "$1" in
+
+start)
+ lxc_exists $2
+ cleanup_init_scripts $2
+ setup_inittab $2
+ lxc_start $2
+ ( nohup $0 watchdog $2 >> /tmp/$2.log ) &
+ ;;
+stop)
+ lxc_exists $2
+ lxc_stop $2
+ ;;
+status)
+ lxc_status
+ ;;
+reload|force-reload|restart)
+ lxc_stop $2
+ lxc_start $2
+ ;;
+watchdog)
+ lxc_watchdog $2
+ ;;
+*)
+ echo "Usage: $0 {start|stop|restart|status}" >&2
+ exit 3
+ ;;
+
+esac
+