01f8d7137d13b11a107bbd876539d8f5a98a8279
[openwrt/svn-archive/archive.git] / net / quagga / files / quagga
1 #!/bin/sh
2 #
3 # quagga Starts/stops quagga daemons and watchquagga.
4 # Create a daemon.conf file to have that routing daemon
5 # started/stopped automagically when using this script
6 # without any daemon names as args.
7 # If watchquagga is available, it will also be
8 # started/stopped if the script is called without
9 # any daemon names.
10 #
11
12 ME=$(basename $0)
13
14 usage() {
15 echo "Usage: ${ME} {start|stop|restart} [daemon ...]"
16 exit 2
17 }
18
19 if [ -z "$1" ]
20 then
21 usage
22 else
23 COMMAND=$1
24 fi
25 shift
26 ARG_DAEMONS=$*
27 BINDIR=/usr/sbin
28 CONFDIR=/etc/quagga
29 STATEDIR=/var/run/quagga
30 DAEMONS="zebra ripd ripngd ospfd ospf6d bgpd"
31 DAEMON_FLAGS=-d
32 WATCHQUAGGA_FLAGS="-d -z -T 60 -R"
33 WATCHQUAGGA_CMD="$0 watchrestart"
34 if [ ${COMMAND} != "watchrestart" ]
35 then
36 DAEMONS="${DAEMONS} watchquagga"
37 fi
38 DAEMONS_STARTSEQ=${DAEMONS}
39
40 reverse()
41 {
42 local revlist r
43 revlist=
44 for r
45 do
46 revlist="$r $revlist"
47 done
48 echo $revlist
49 }
50
51 DAEMONS_STOPSEQ=$(reverse ${DAEMONS_STARTSEQ})
52
53 #pidof() {
54 # ps ax | awk 'match($5, "(^|/)'"$1"'$") > 0 { printf " %s", $1 }'
55 #}
56
57 quit() {
58 echo "${ME}: $1"
59 exit 0
60 }
61
62 die() {
63 echo "${ME}: $1"
64 exit 1
65 }
66
67 is_in() {
68 local i
69 for i in $2
70 do
71 [ "$1" = "$i" ] && return 0
72 done
73 return 1
74 }
75
76 select_subset() {
77 local unknown i j
78 unknown=
79 RESULT=
80 for i in $1
81 do
82 is_in $i "$2" || unknown="$unknown $i"
83 done
84 if [ -n "$unknown" ]
85 then
86 RESULT=$unknown
87 return 1
88 else
89 for j in $2
90 do
91 is_in $j "$1" && RESULT="$RESULT $j"
92 done
93 return 0
94 fi
95 }
96
97 # check command
98
99 case ${COMMAND}
100 in
101 start|stop|restart)
102 ;;
103 watchrestart)
104 if [ -n "$ARG_DAEMONS" ]
105 then
106 echo "${ME}: watchrestart mode is only for use by watchquagga"
107 exit 2
108 fi
109 ;;
110 *)
111 usage
112 ;;
113 esac
114
115 # select daemons to start
116
117 case ${COMMAND}
118 in
119 start|restart|watchrestart)
120 START_DAEMONS=
121 for d in ${DAEMONS_STARTSEQ}
122 do
123 [ -x "${BINDIR}/${d}" -a -f "${CONFDIR}/${d}.conf" ] \
124 && START_DAEMONS="${START_DAEMONS}${d} "
125 done
126 WATCHQUAGGA_DAEMONS=${START_DAEMONS}
127 if is_in watchquagga "${DAEMONS_STARTSEQ}"
128 then
129 START_DAEMONS="${START_DAEMONS} watchquagga"
130 fi
131 if [ -n "${ARG_DAEMONS}" ]
132 then
133 if select_subset "${ARG_DAEMONS}" "${DAEMONS}"
134 then
135 if select_subset "${ARG_DAEMONS}" "${START_DAEMONS}"
136 then
137 START_DAEMONS=${RESULT}
138 else
139 die "these daemons are not startable:${RESULT}."
140 fi
141 else
142 die "unknown daemons:${RESULT}; choose from: ${DAEMONS}."
143 fi
144 fi
145 ;;
146 esac
147
148 # select daemons to stop
149
150 case ${COMMAND}
151 in
152 stop|restart|watchrestart)
153 STOP_DAEMONS=${DAEMONS_STOPSEQ}
154 if [ -n "${ARG_DAEMONS}" ]
155 then
156 if select_subset "${ARG_DAEMONS}" "${STOP_DAEMONS}"
157 then
158 STOP_DAEMONS=${RESULT}
159 else
160 die "unknown daemons:${RESULT}; choose from: ${DAEMONS}."
161 fi
162 fi
163 stop_daemons=
164 for d in ${STOP_DAEMONS}
165 do
166 pidfile=${STATEDIR}/${d}.pid
167 if [ -f "${pidfile}" -o -n "$(pidof ${d})" ]
168 then
169 stop_daemons="${stop_daemons}${d} "
170 elif [ -n "${ARG_DAEMONS}" ]
171 then
172 echo "${ME}: found no ${d} process running."
173 fi
174 done
175 STOP_DAEMONS=${stop_daemons}
176 ;;
177 esac
178
179 # stop daemons
180
181 for d in $STOP_DAEMONS
182 do
183 echo -n "${ME}: Stopping ${d} ... "
184 pidfile=${STATEDIR}/${d}.pid
185 if [ -f "${pidfile}" ]
186 then
187 file_pid=$(cat ${pidfile})
188 if [ -z "${file_pid}" ]
189 then
190 echo -n "no pid file entry found ... "
191 fi
192 else
193 file_pid=
194 echo -n "no pid file found ... "
195 fi
196 proc_pid=$(pidof ${d})
197 if [ -z "${proc_pid}" ]
198 then
199 echo -n "found no ${d} process running ... "
200 else
201 count=0
202 notinpidfile=
203 for p in ${proc_pid}
204 do
205 count=$((${count}+1))
206 if kill ${p}
207 then
208 echo -n "killed ${p} ... "
209 else
210 echo -n "failed to kill ${p} ... "
211 fi
212 [ "${p}" = "${file_pid}" ] \
213 || notinpidfile="${notinpidfile} ${p}"
214 done
215 [ ${count} -le 1 ] \
216 || echo -n "WARNING: ${count} ${d} processes were found running ... "
217 for n in ${notinpidfile}
218 do
219 echo -n "WARNING: process ${n} was not in pid file ... "
220 done
221 fi
222 count=0
223 survivors=$(pidof ${d})
224 while [ -n "${survivors}" ]
225 do
226 sleep 1
227 count=$((${count}+1))
228 survivors=$(pidof ${d})
229 [ -z "${survivors}" -o ${count} -gt 5 ] && break
230 for p in ${survivors}
231 do
232 sleep 1
233 echo -n "${p} "
234 kill ${p}
235 done
236 done
237 survivors=$(pidof ${d})
238 [ -n "${survivors}" ] && \
239 if kill -KILL ${survivors}
240 then
241 echo -n "KILLed ${survivors} ... "
242 else
243 echo -n "failed to KILL ${survivors} ... "
244 fi
245 sleep 1
246 survivors=$(pidof ${d})
247 if [ -z "${survivors}" ]
248 then
249 echo -n "done."
250 if [ -f "${pidfile}" ]
251 then
252 rm -f ${pidfile} \
253 || echo -n " Failed to remove pidfile."
254 fi
255 else
256 echo -n "failed to stop ${survivors} - giving up."
257 if [ "${survivors}" != "${file_pid}" ]
258 then
259 if echo "${survivors}" > ${pidfile}
260 then
261 chown quagga:quagga ${pidfile}
262 echo -n " Wrote ${survivors} to pidfile."
263 else
264 echo -n " Failed to write ${survivors} to pidfile."
265 fi
266 fi
267 fi
268 echo
269 done
270
271 # start daemons
272
273 if [ -n "$START_DAEMONS" ]
274 then
275 [ -d ${CONFDIR} ] \
276 || quit "${ME}: no config directory ${CONFDIR} - exiting."
277 chown -R quagga:quagga ${CONFDIR}
278 [ -d ${STATEDIR} ] || mkdir -p ${STATEDIR} \
279 || die "${ME}: could not create state directory ${STATEDIR} - exiting."
280 chown -R quagga:quagga ${STATEDIR}
281
282 for d in $START_DAEMONS
283 do
284 echo -n "${ME}: Starting ${d} ... "
285 proc_pid=$(pidof ${d})
286 pidfile=${STATEDIR}/${d}.pid
287 file_pid=
288 if [ -f "${pidfile}" ]
289 then
290 file_pid=$(cat ${pidfile})
291 if [ -n "${file_pid}" ]
292 then
293 echo -n "found old pid file entry ${file_pid} ... "
294 fi
295 fi
296 if [ -n "${proc_pid}" ]
297 then
298 echo -n "found ${d} running (${proc_pid}) - skipping ${d}."
299 if [ "${proc_pid}" != "${file_pid}" ]
300 then
301 if echo "${proc_pid}" > ${pidfile}
302 then
303 chown quagga:quagga ${pidfile}
304 echo -n " Wrote ${proc_pid} to pidfile."
305 else
306 echo -n " Failed to write ${proc_pid} to pidfile."
307 fi
308 fi
309 elif rm -f "${pidfile}"
310 then
311 if [ "${d}" = "watchquagga" ]
312 then
313 $("${BINDIR}/${d}" \
314 ${WATCHQUAGGA_FLAGS} \
315 "${WATCHQUAGGA_CMD}" \
316 ${WATCHQUAGGA_DAEMONS})
317 status=$?
318 else
319 $("${BINDIR}/${d}" ${DAEMON_FLAGS})
320 status=$?
321 fi
322 if [ $status -eq 0 ]
323 then
324 echo -n "done."
325 else
326 echo -n "failed."
327 fi
328 else
329 echo -n " failed to remove pidfile."
330 fi
331 echo
332 done
333 fi