4 # This is a "library" of sorts for use by the other FRR shell scripts. It
5 # has most of the daemon start/stop logic, but expects the following shell
6 # functions/commands to be provided by the "calling" script:
12 # (coincidentally, these are LSB standard functions.)
14 # Sourcing this file in a shell script will load FRR config variables but
15 # not perform any action. Note there is an "exit 1" if the main config
16 # file does not exist.
18 # This script should be installed in /usr/sbin/frrcommon.sh
19 # FRR_PATHSPACE is passed in from watchfrr
20 suffix
="${FRR_PATHSPACE:+/${FRR_PATHSPACE}}"
21 nsopt
="${FRR_PATHSPACE:+-N ${FRR_PATHSPACE}}"
23 PATH
=/bin
:/usr
/bin
:/sbin
:/usr
/sbin
24 D_PATH
="/usr/sbin" # /usr/lib/frr
25 C_PATH
="/etc/frr" # /etc/frr
26 V_PATH
="/var/run/frr" # /var/run/frr
27 VTYSH
="/usr/bin/vtysh" # /usr/bin/vtysh
28 FRR_USER
="network" # frr
29 FRR_GROUP
="network" # frr
30 FRR_VTY_GROUP
="" # frrvty
31 FRR_CONFIG_MODE
="0600" # 0600
32 FRR_DEFAULT_PROFILE
="traditional" # traditional / datacenter
34 # ORDER MATTERS FOR $DAEMONS!
36 # - watchfrr does NOT belong in this list
38 DAEMONS
="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd sharpd pbrd staticd bfdd fabricd vrrpd"
39 RELOAD_SCRIPT
="$D_PATH/frr-reload.py"
46 [ -n "$watchfrr_debug" ] ||
return 0
48 printf '%s %s(%s):' "`date +%Y-%m-%dT%H:%M:%S.%N`" "$0" $$
>&2
49 # this is to show how arguments are split regarding whitespace & co.
50 # (e.g. for use with `debug "message" "$@"`)
51 while [ $# -gt 0 ]; do
52 printf ' "%s"' "$1" >&2
59 [ -n "$FRR_USER" ] && chown
"$FRR_USER" "$1"
60 [ -n "$FRR_GROUP" ] && chgrp
"$FRR_GROUP" "$1"
61 [ -n "$FRR_CONFIG_MODE" ] && chmod "$FRR_CONFIG_MODE" "$1"
68 [ "$1" = "watchfrr" ] && return 0
69 [ -r "$C_PATH/frr.conf" ] ||
return 0
71 "$VTYSH" `echo $nsopt` -b -d "$1"
73 "$VTYSH" `echo $nsopt` -b
78 # note this sets global variables ($dmninst, $daemon, $inst)
80 daemon
="${dmninst%-*}"
82 [ "$daemon" != "$dmninst" ] && inst
="${dmninst#*-}"
86 # note $1 and $2 specify names for global variables to be set
87 local enabled disabled evar dvar
93 for daemon
in $DAEMONS; do
95 eval inst
=\$
${daemon}_instances
96 [ "$daemon" = zebra
-o "$daemon" = staticd
] && cfg
=yes
97 if [ -n "$cfg" -a "$cfg" != "no" -a "$cfg" != "0" ]; then
98 if ! daemon_prep
"$daemon" "$inst"; then
101 debug
"$daemon enabled"
102 # enabled="$enabled $daemon"
104 if [ -n "$inst" ]; then
105 debug
"$daemon multi-instance $inst"
109 enabled
="$enabled $daemon-$i"
113 enabled
="$enabled $daemon"
116 debug
"$daemon disabled"
117 disabled
="$disabled $daemon"
121 enabled
="${enabled# }"
122 disabled
="${disabled# }"
123 [ -z "$evar" ] && echo "$enabled"
124 [ -n "$evar" ] && eval $evar="\"$enabled\""
125 [ -n "$dvar" ] && eval $dvar="\"$disabled\""
129 # note $1 specifies the name of a global variable to be set
130 local enabled evar daemon inst oldifs i
134 for daemon
in $DAEMONS; do
135 eval inst
=\$
${daemon}_instances
136 if [ -n "$inst" ]; then
140 enabled
="$enabled $daemon-$i"
144 enabled
="$enabled $daemon"
148 enabled
="${enabled# }"
149 [ -z "$evar" ] && echo "$enabled"
150 [ -n "$evar" ] && eval $evar="\"$enabled\""
158 [ "$item" = "$i" ] && return 0
164 # individual daemon management
168 local daemon inst cfg
171 [ "$daemon" = "watchfrr" ] && return 0
172 [ -x "$D_PATH/$daemon" ] ||
{
173 log_failure_msg
"cannot start $daemon${inst:+ (instance $inst)}: daemon binary not installed"
176 [ -r "$C_PATH/frr.conf" ] && return 0
178 cfg
="$C_PATH/$daemon${inst:+-$inst}.conf"
179 if [ ! -r "$cfg" ]; then
187 local dmninst daemon inst args instopt wrap bin
190 ulimit -n $MAX_FDS > /dev
/null
2> /dev
/null
191 daemon_prep
"$daemon" "$inst" ||
return 1
192 if test ! -d "$V_PATH"; then
194 chown
$FRR_USER "$V_PATH"
197 eval wrap
="\$${daemon}_wrap"
198 bin
="$D_PATH/$daemon"
199 instopt
="${inst:+-n $inst}"
200 eval args
="\$${daemon}_options"
202 if eval "$all_wrap $wrap $bin $nsopt -d $frr_global_options $instopt $args"; then
203 log_success_msg
"Started $dmninst"
206 log_failure_msg
"Failed to start $dmninst!"
211 local dmninst daemon inst pidfile vtyfile pid cnt fail
214 pidfile
="$V_PATH/$daemon${inst:+-$inst}.pid"
215 vtyfile
="$V_PATH/$daemon${inst:+-$inst}.vty"
217 [ -r "$pidfile" ] || fail
="pid file not found"
218 [ -z "$fail" ] && pid
="`cat \"$pidfile\"`"
219 [ -z "$fail" -a -z "$pid" ] && fail
="pid file is empty"
220 [ -n "$fail" ] ||
kill -0 "$pid" 2>/dev
/null || fail
="pid $pid not running"
222 if [ -n "$fail" ]; then
223 log_failure_msg
"Cannot stop $dmninst: $fail"
230 while kill -0 "$pid" 2>/dev
/null
; do
232 [ $
(( cnt
-= 1 )) -gt 0 ] ||
break
234 if kill -0 "$pid" 2>/dev
/null
; then
235 log_failure_msg
"Failed to stop $dmninst, pid $pid still running"
239 log_success_msg
"Stopped $dmninst"
246 local dmninst daemon inst pidfile pid fail
249 pidfile
="$V_PATH/$daemon${inst:+-$inst}.pid"
251 [ -r "$pidfile" ] ||
return 3
252 pid
="`cat \"$pidfile\"`"
253 [ -z "$pid" ] && return 1
254 kill -0 "$pid" 2>/dev
/null ||
return 1
261 if [ "$rv" -eq 0 ]; then
262 log_success_msg
"Status of $1: running"
264 log_failure_msg
"Status of $1: FAILED"
270 # all-daemon commands
275 for dmninst
in $daemons; do
276 daemon_start
"$dmninst"
283 daemon_list daemons disabled
284 [ "$1" = "--reallyall" ] && daemons
="$daemons $disabled"
287 for dmninst
in $daemons; do
288 reversed
="$dmninst $reversed"
291 for dmninst
in $reversed; do
292 daemon_stop
"$dmninst" &
305 for dmninst
in $daemons; do
306 print_status
"$dmninst" || fail
=1
317 [ -r "$oldcfg" ] ||
return 0
318 [ -s "$oldcfg" ] ||
return 0
319 grep -v '^[[:blank:]]*\(#\|$\)' "$oldcfg" > /dev
/null ||
return 0
321 log_warning_msg
"Reading deprecated $oldcfg. Please move its settings to $C_PATH/daemons and remove it."
323 # save off settings from daemons for the OR below
324 for dmn
in $DAEMONS; do eval "_new_$dmn=\${$dmn:-no}"; done
328 # OR together the daemon enabling options between config files
329 for dmn
in $DAEMONS; do eval "test \$_new_$dmn != no && $dmn=\$_new_$dmn; unset _new_$dmn"; done
332 [ -r "$C_PATH/daemons" ] ||
{
333 log_failure_msg
"cannot run $@: $C_PATH/daemons does not exist"
338 if [ -z "$FRR_PATHSPACE" ]; then
339 load_old_config
"$C_PATH/daemons.conf"
340 load_old_config
"/etc/default/frr"
341 load_old_config
"/etc/sysconfig/frr"
344 if { declare -p watchfrr_options
2>/dev
/null || true
; } |
grep -q '^declare \-a'; then
345 log_warning_msg
"watchfrr_options contains a bash array value." \
346 "The configured value is intentionally ignored since it is likely wrong." \
347 "Please remove or fix the setting."
348 unset watchfrr_options
351 if test -z "$frr_profile"; then
352 # try to autodetect config profile
353 if test -d /etc
/cumulus
; then
354 frr_profile
=datacenter
355 # elif test ...; then
356 # -- add your distro/system here
357 elif test -n "$FRR_DEFAULT_PROFILE"; then
358 frr_profile
="$FRR_DEFAULT_PROFILE"
361 test -n "$frr_profile" && frr_global_options
="$frr_global_options -F $frr_profile"
365 # other defaults and dispatch
371 debug
"frrcommon_main" "$@"
376 if [ "$1" = "all" -o -z "$1" ]; then
388 start
) daemon_start
"$@";;
389 stop
) daemon_stop
"$@";;