quagga.init 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  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. exec sh $0 start
  101. ;;
  102. start|restart|watchrestart)
  103. START_DAEMONS=
  104. for d in ${DAEMONS_STARTSEQ}
  105. do
  106. [ -x "${BINDIR}/${d}" -a -f "${CONFDIR}/${d}.conf" ] \
  107. && START_DAEMONS="${START_DAEMONS}${d} "
  108. done
  109. WATCHQUAGGA_DAEMONS=${START_DAEMONS}
  110. if is_in watchquagga "${DAEMONS_STARTSEQ}"
  111. then
  112. START_DAEMONS="${START_DAEMONS} watchquagga"
  113. fi
  114. if [ -n "${ARG_DAEMONS}" ]
  115. then
  116. if select_subset "${ARG_DAEMONS}" "${DAEMONS}"
  117. then
  118. if select_subset "${ARG_DAEMONS}" "${START_DAEMONS}"
  119. then
  120. START_DAEMONS=${RESULT}
  121. else
  122. die "these daemons are not startable:${RESULT}."
  123. fi
  124. else
  125. die "unknown daemons:${RESULT}; choose from: ${DAEMONS}."
  126. fi
  127. fi
  128. ;;
  129. esac
  130. # select daemons to stop
  131. case ${COMMAND} in
  132. stop|restart|watchrestart)
  133. STOP_DAEMONS=${DAEMONS_STOPSEQ}
  134. if [ -n "${ARG_DAEMONS}" ]
  135. then
  136. if select_subset "${ARG_DAEMONS}" "${STOP_DAEMONS}"
  137. then
  138. STOP_DAEMONS=${RESULT}
  139. else
  140. die "unknown daemons:${RESULT}; choose from: ${DAEMONS}."
  141. fi
  142. fi
  143. stop_daemons=
  144. for d in ${STOP_DAEMONS}
  145. do
  146. pidfile=${STATEDIR}/${d}.pid
  147. if [ -f "${pidfile}" -o -n "$(pidof ${d})" ]
  148. then
  149. stop_daemons="${stop_daemons}${d} "
  150. elif [ -n "${ARG_DAEMONS}" ]
  151. then
  152. echo "${ME}: found no ${d} process running."
  153. fi
  154. done
  155. STOP_DAEMONS=${stop_daemons}
  156. ;;
  157. esac
  158. # stop daemons
  159. for d in $STOP_DAEMONS
  160. do
  161. echo -n "${ME}: Stopping ${d} ... "
  162. pidfile=${STATEDIR}/${d}.pid
  163. if [ -f "${pidfile}" ]
  164. then
  165. file_pid=$(cat ${pidfile})
  166. if [ -z "${file_pid}" ]
  167. then
  168. echo -n "no pid file entry found ... "
  169. fi
  170. else
  171. file_pid=
  172. echo -n "no pid file found ... "
  173. fi
  174. proc_pid=$(pidof ${d})
  175. if [ -z "${proc_pid}" ]
  176. then
  177. echo -n "found no ${d} process running ... "
  178. else
  179. count=0
  180. notinpidfile=
  181. for p in ${proc_pid}
  182. do
  183. count=$((${count}+1))
  184. if kill ${p}
  185. then
  186. echo -n "killed ${p} ... "
  187. else
  188. echo -n "failed to kill ${p} ... "
  189. fi
  190. [ "${p}" = "${file_pid}" ] \
  191. || notinpidfile="${notinpidfile} ${p}"
  192. done
  193. [ ${count} -le 1 ] \
  194. || echo -n "WARNING: ${count} ${d} processes were found running ... "
  195. for n in ${notinpidfile}
  196. do
  197. echo -n "WARNING: process ${n} was not in pid file ... "
  198. done
  199. fi
  200. count=0
  201. survivors=$(pidof ${d})
  202. while [ -n "${survivors}" ]
  203. do
  204. sleep 1
  205. count=$((${count}+1))
  206. survivors=$(pidof ${d})
  207. [ -z "${survivors}" -o ${count} -gt 5 ] && break
  208. for p in ${survivors}
  209. do
  210. sleep 1
  211. echo -n "${p} "
  212. kill ${p}
  213. done
  214. done
  215. survivors=$(pidof ${d})
  216. [ -n "${survivors}" ] && \
  217. if kill -KILL ${survivors}
  218. then
  219. echo -n "KILLed ${survivors} ... "
  220. else
  221. echo -n "failed to KILL ${survivors} ... "
  222. fi
  223. sleep 1
  224. survivors=$(pidof ${d})
  225. if [ -z "${survivors}" ]
  226. then
  227. echo -n "done."
  228. if [ -f "${pidfile}" ]
  229. then
  230. rm -f ${pidfile} \
  231. || echo -n " Failed to remove pidfile."
  232. fi
  233. else
  234. echo -n "failed to stop ${survivors} - giving up."
  235. if [ "${survivors}" != "${file_pid}" ]
  236. then
  237. if echo "${survivors}" > ${pidfile}
  238. then
  239. chown quagga:quagga ${pidfile}
  240. echo -n " Wrote ${survivors} to pidfile."
  241. else
  242. echo -n " Failed to write ${survivors} to pidfile."
  243. fi
  244. fi
  245. fi
  246. echo
  247. done
  248. # start daemons
  249. if [ -n "$START_DAEMONS" ]
  250. then
  251. [ -d ${CONFDIR} ] \
  252. || quit "${ME}: no config directory ${CONFDIR} - exiting."
  253. chown -R quagga:quagga ${CONFDIR}
  254. [ -d ${STATEDIR} ] || mkdir -p ${STATEDIR} \
  255. || die "${ME}: could not create state directory ${STATEDIR} - exiting."
  256. chown -R quagga:quagga ${STATEDIR}
  257. for d in $START_DAEMONS
  258. do
  259. echo -n "${ME}: Starting ${d} ... "
  260. proc_pid=$(pidof ${d})
  261. pidfile=${STATEDIR}/${d}.pid
  262. file_pid=
  263. if [ -f "${pidfile}" ]
  264. then
  265. file_pid=$(cat ${pidfile})
  266. if [ -n "${file_pid}" ]
  267. then
  268. echo -n "found old pid file entry ${file_pid} ... "
  269. fi
  270. fi
  271. if [ -n "${proc_pid}" ]
  272. then
  273. echo -n "found ${d} running (${proc_pid}) - skipping ${d}."
  274. if [ "${proc_pid}" != "${file_pid}" ]
  275. then
  276. if echo "${proc_pid}" > ${pidfile}
  277. then
  278. chown quagga:quagga ${pidfile}
  279. echo -n " Wrote ${proc_pid} to pidfile."
  280. else
  281. echo -n " Failed to write ${proc_pid} to pidfile."
  282. fi
  283. fi
  284. elif rm -f "${pidfile}"
  285. then
  286. if [ "${d}" = "watchquagga" ]
  287. then
  288. $("${BINDIR}/${d}" \
  289. ${WATCHQUAGGA_FLAGS} \
  290. "${WATCHQUAGGA_CMD}" \
  291. ${WATCHQUAGGA_DAEMONS})
  292. status=$?
  293. else
  294. $("${BINDIR}/${d}" ${DAEMON_FLAGS})
  295. status=$?
  296. fi
  297. if [ $status -eq 0 ]
  298. then
  299. echo -n "done."
  300. else
  301. echo -n "failed."
  302. fi
  303. else
  304. echo -n " failed to remove pidfile."
  305. fi
  306. echo
  307. done
  308. fi