quagga.init 6.0 KB

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