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