move inotify so watchdog can stop lxc in init state 0
[sysadmin-cookbook] / recepies / lxc / lxc-watchdog.sh
1 #!/bin/sh
2
3 # lxc-watchdog.sh
4 #
5 # Dobrica Pavlinusic <dpavlin@rot13.org> 2010-03-15
6 #
7 # this script can be used to start/stop Linux containers 
8 # using clever inotify hack to monitor halt/reboot from
9 # Tony Risinger posted to lxc-users mailing list
10 #
11 # http://www.mail-archive.com/lxc-users@lists.sourceforge.net/msg00074.html
12
13
14 which inotifywait >/dev/null || apt-get install inotify-tools
15
16 lxc_status() {
17         lxc-ls -1 | sort -u | xargs -i lxc-info -n {}
18 }
19
20 lxc_exists() {
21         name=$1
22
23         if [ ! -e /var/lib/lxc/$name/config ] ; then
24                 echo "Usage: $0 name"
25                 lxc_status
26                 exit 1
27         fi
28 }
29
30
31 lxc_rootfs() {
32         grep lxc.rootfs "/var/lib/lxc/$1/config" | cut -d= -f2 | sed 's/^ *//'
33 }
34
35
36 cleanup_init_scripts() {
37         rootfs=$(lxc_rootfs $1)
38
39         ls \
40                 $rootfs/etc/rc?.d/*umountfs \
41                 $rootfs/etc/rc?.d/*umountroot \
42                 $rootfs/etc/rc?.d/*hwclock* \
43         2>/dev/null | xargs -i rm -v {}
44 }
45
46
47 setup_inittab() {
48         rootfs=$(lxc_rootfs $1)
49
50         # let container respond to kill -SIGPWR
51         inittab=$rootfs/etc/inittab
52         powerfail="pw::powerfail:/sbin/init 0"
53         if ! grep "$powerfail" ${inittab} >/dev/null ; then
54                 grep -v ::power ${inittab} > ${inittab}.new
55                 echo $powerfail >> ${inittab}.new
56                 mv ${inittab}.new ${inittab}
57                 echo "$initab modified"
58         fi
59
60 }
61
62
63 lxc_stop() {
64         name=$1
65
66         init_pid=`lxc-ps -C init -o pid | grep "^$name" | cut -d" " -f2-`
67         if [ -z "$init_pid" ] ; then
68                 lxc-info -n $name
69                 exit 1
70         fi
71         echo "$name stop $init_pid"
72         /bin/kill -SIGPWR $init_pid
73         lxc-wait -n $name -s STOPPED
74
75 }
76
77
78 lxc_start() {
79         name=$1
80
81         if ! lxc-info -n $name | grep RUNNING ; then
82                 echo "$name start"
83                 lxc-start -n $name -o /tmp/${name}.log -d
84                 lxc-wait  -n $name -s RUNNING
85                 lxc-info  -n $name
86         fi
87 }
88
89 lxc_watchdog() {
90 name=$1
91 rootfs=$(lxc_rootfs $1)
92
93 while true; do
94         vps_utmp=${rootfs}/var/run/utmp
95         tasks=`wc -l < /cgroup/${name}/tasks`
96         test -z "$tasks" && exit 1
97         if [ "$tasks" -eq 1 ]; then
98
99                 runlevel="$(runlevel ${vps_utmp})"
100                 echo "# $name runlevel $runlevel"
101
102                 case $runlevel in
103                 N*)
104                         # nothing for new boot state
105                 ;;
106                 ??0)
107                         echo "$name halt"
108                         lxc-stop -n "${name}"
109                         lxc-wait -n ${name} -s STOPPED
110                         break
111                 ;;
112                 ??6)
113                         echo "$name reboot";
114                         lxc-stop -n ${name}
115                         lxc-wait -n ${name} -s STOPPED
116                         lxc-start -d -n ${name} -o /tmp/${name}.log
117                 ;;
118                 *)
119                         # make sure vps is still running
120                         state="$(lxc-info -n "${name}" | sed -e 's/.* is //')"
121                         [ "$state" = "RUNNING" ] || break
122                 ;;
123                 esac
124         else
125                 echo "# $name $tasks tasks"
126         fi
127
128         # time of 5 minutes on it JUST IN CASE...
129         inotifywait -qqt 300 ${vps_utmp}
130 done
131
132 echo "${name} exited"
133
134 }
135
136
137 case "$1" in
138
139 start)
140         lxc_exists $2
141         cleanup_init_scripts $2
142         setup_inittab $2
143         lxc_start $2
144         ( nohup $0 watchdog $2 >> /tmp/$2.log ) &
145         ;;
146 stop)
147         lxc_exists $2
148         lxc_stop $2
149         ;;
150 status)
151         lxc_status
152         ;;
153 reload|force-reload|restart)
154         lxc_stop $2
155         lxc_start $2
156         ;;
157 watchdog)
158         lxc_watchdog $2
159         ;;
160 *)
161         echo "Usage: $0 {start|stop|restart|status}" >&2
162         exit 3
163         ;;
164
165 esac
166