Skip hosts that aren't enabled.
[myplc.git] / host.init
1 #!/bin/bash
2 #
3 # plc   Manages all PLC services on this machine
4 #
5 # chkconfig: 2345 99 5
6 #
7 # description:  Manages all PLC services on this machine
8 #
9 # $Id$
10 #
11
12 PATH=/sbin:/bin:/usr/bin:/usr/sbin
13
14 # Source function library.
15 if [ -f /etc/init.d/functions ] ; then
16     . /etc/init.d/functions
17 fi
18
19 # If success() or failure() are not defined
20 if ! type -type success >/dev/null || ! type -type failure >/dev/null ; then
21     success() {
22         echo -ne "[  OK  ]\r"
23         return 0
24     }
25     failure() {
26         echo -ne "[FAILED]\r"
27         return 1
28     }
29 fi
30
31 # Source configuration
32 SERVICE=$(basename $0)
33 if [ ! -f /etc/sysconfig/$SERVICE ] ; then
34     SERVICE=plc
35 fi
36 if [ -f /etc/sysconfig/$SERVICE -a -z "${PLC_ROOT}${PLC_DATA}" ] ; then
37     . /etc/sysconfig/$SERVICE
38 fi
39
40 # Total number of errors
41 ERRORS=0
42
43 # Count the exit status of the last command
44 check ()
45 {
46     ERRORS=$(($ERRORS+$?))
47 }
48
49 mounted ()
50 {
51     if cut -d' ' -f2 /proc/mounts | grep -q "$1" ; then
52         return 0
53     else
54         return 1
55     fi
56 }
57
58 mount_plc ()
59 {
60     echo -n $"Mounting PLC: "
61
62     if ! mounted $PLC_ROOT ; then
63         if ! e2fsck -a $PLC_ROOT.img | logger -t "PLC" ; then
64             e2fsck $PLC_ROOT.img
65         fi
66         mount -o loop $PLC_ROOT.img $PLC_ROOT
67         check
68     fi
69     if ! mounted $PLC_ROOT/data ; then
70         mount -t none -o bind,rw $PLC_DATA $PLC_ROOT/data
71         check
72     fi
73     if ! mounted $PLC_ROOT/proc ; then
74         mount -t proc none $PLC_ROOT/proc
75         check
76     fi
77
78     [ $ERRORS -eq 0 ] && success $"PLC unmount" || failure $"PLC unmount"       
79     echo
80
81 }
82
83 start ()
84 {
85     # Starting everything
86     if [ -z "$1" ] ; then
87         mount_plc 
88     fi
89
90     chroot $PLC_ROOT /sbin/service plc $PLC_OPTIONS start $*
91     check
92 }
93
94 umount_plc ()
95 {
96     echo -n $"Unmounting PLC: "
97
98     for dir in $PLC_ROOT/proc $PLC_ROOT/data $PLC_ROOT ; do
99         if mounted $dir ; then
100             umount $dir
101             check
102         fi
103     done
104
105     [ $ERRORS -eq 0 ] && success $"PLC unmount" || failure $"PLC unmount"       
106     echo
107 }
108
109 stop ()
110 {
111     if mounted $PLC_ROOT ; then
112         chroot $PLC_ROOT /sbin/service plc $PLC_OPTIONS stop $*
113         check
114     fi
115
116     # Stopped everything
117     if [ -z "$1" ] ; then
118         umount_plc
119     fi
120 }
121
122 mountstatus_plc ()
123 {
124     for dir in $PLC_ROOT/proc $PLC_ROOT/data $PLC_ROOT ; do
125         if mounted $dir ; then
126             echo $dir
127         fi
128     done
129 }
130
131 # safestop : tries to stop normally; if that fails, kills processes that are still using /plc 
132 # needs the lsof rpm in the root context (should be a dependency of the myplc spec)
133 function check_command ()
134 {
135     command=$1; shift
136     found=$(type -p $command)
137     if [ -z "$found" ] ; then
138         echo "$COMMAND : requires command $command, was not found - exiting"
139         exit 1
140     fi
141 }
142
143
144 ### when process stil use /plc/root, we cannot umount it
145 function kill_all ()
146 {
147     [ -n "$DEBUG" ] && set -x
148     check_command lsof
149     
150     echo -n "Killing processes using $PLC_ROOT and $PLC_DATA: "
151     # initialize process list
152     former_process_list="unlikely"
153       
154     # we ignore unknown uids for now, since we run in the chroot jail anyway
155     # not too sure about that though, 
156     while true; do
157         # get the list of processes - collapse and remove empty lines
158         process_list=$(lsof -t +D $PLC_ROOT +D $PLC_DATA)
159         if [ -z "$process_list" ] ; then
160             # we are done, let's bail out
161             success "$PLC_ROOT clear" ; echo ; return
162         fi
163         if [ "$process_list" = "$former_process_list" ] ; then
164             # we are stuck, no progress since last time : exit on error
165             failure "$PLC_ROOT locked" ; echo ; return
166         fi
167         # record for next loop
168         former_process_list="$process_list"
169         # kill them
170         kill $process_list
171         sleep 2
172         # check there are dead
173         for pid in $process_list ; do
174             ps -o pid $pid &> /dev/null 
175             if [ "$?" = 0 ] ; then
176                 [ -n "$DEBUG" ] && echo "$pid survived kill - forcing kill -9"
177                 kill -9 $pid
178             fi
179         done
180     done
181 }
182
183 # Get command
184 shift $(($OPTIND - 1))
185 command=$1
186
187 # Get step(s)
188 shift 1
189
190 case "$command" in
191     start|stop)
192         $command $*
193         ;;
194
195     restart)
196         stop $*
197         ERRORS=0
198         start $*
199         ;;
200
201     reload)
202         chroot $PLC_ROOT /sbin/service plc $PLC_OPTIONS reload $*
203         ;;      
204
205     mount|umount|mountstatus)
206         ${command}_plc
207         ;;
208
209    kill)
210         kill_all
211         ;;
212
213    safestop)
214         stop
215         ### Checking : we might need to run kill
216         mounted=$(mountstatus_plc)
217         if [ -n "$mounted" ] ; then
218             echo "Umount failed : killing remaining processes and trying again"
219             ERRORS=0
220             kill_all
221             ERRORS=0
222             stop
223         fi
224         ;;
225   
226     *)
227         echo "Usage: $0 {start|stop|restart|reload|mount|umount|mountstatus|kill|safestop}"
228         RETVAL=1
229         ;;
230 esac
231
232 exit $ERRORS