From 032652bf5bb17ae2457196cfc7bd6433934ec9e6 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 30 Nov 2018 21:40:39 +0100 Subject: [PATCH] debian/tools: new init script This separates the init script used for the system (and called in the systemd unit file) from the script that watchfrr uses to control daemons. Mixing these two caused the entire thing to become a rather huge spaghetti mess. Note that there is a behaviour change in that the new script always starts zebra regardless of zebra_enable. Side changes: - Ubuntu 12.04 removed from backports since it doesn't work anyway - zebra is always started regardless of zebra_enable. To disable FRR, the entire init script should be disabled through policy. - no-watchfrr operation is no longer supported by the scripts in the Debian packages. (This is intentional.) Signed-off-by: David Lamparter --- configure.ac | 3 + .../backports/ubuntu12.04/debian/control | 56 ---- .../backports/ubuntu12.04/debian/frr.install | 1 - .../backports/ubuntu12.04/debian/frr.postinst | 1 - .../backports/ubuntu12.04/debian/frr.postrm | 1 - debianpkg/backports/ubuntu12.04/debian/rules | 162 --------- .../ubuntu12.04/debian/source/format | 1 - debianpkg/backports/ubuntu12.04/exclude | 0 debianpkg/backports/ubuntu12.04/versionext | 1 - .../backports/ubuntu14.04/debian/frr.install | 1 - .../backports/ubuntu14.04/debian/frr.postinst | 38 --- .../backports/ubuntu14.04/debian/frr.postrm | 14 - debianpkg/backports/ubuntu14.04/debian/rules | 2 + debianpkg/rules | 2 +- debianpkg/subdir.am | 10 - redhat/frr.spec.in | 3 + tools/.gitignore | 3 + tools/etc/frr/daemons | 10 +- tools/etc/frr/daemons.conf | 45 +-- tools/frr.service | 7 +- tools/frrcommon.sh.in | 317 ++++++++++++++++++ tools/frrinit.sh.in | 90 +++++ tools/subdir.am | 4 + tools/watchfrr.sh.in | 33 ++ 24 files changed, 483 insertions(+), 322 deletions(-) delete mode 100644 debianpkg/backports/ubuntu12.04/debian/control delete mode 120000 debianpkg/backports/ubuntu12.04/debian/frr.install delete mode 120000 debianpkg/backports/ubuntu12.04/debian/frr.postinst delete mode 120000 debianpkg/backports/ubuntu12.04/debian/frr.postrm delete mode 100755 debianpkg/backports/ubuntu12.04/debian/rules delete mode 100644 debianpkg/backports/ubuntu12.04/debian/source/format delete mode 100644 debianpkg/backports/ubuntu12.04/exclude delete mode 100644 debianpkg/backports/ubuntu12.04/versionext delete mode 100644 debianpkg/backports/ubuntu14.04/debian/frr.postinst delete mode 100644 debianpkg/backports/ubuntu14.04/debian/frr.postrm create mode 100644 tools/frrcommon.sh.in create mode 100644 tools/frrinit.sh.in create mode 100644 tools/watchfrr.sh.in diff --git a/configure.ac b/configure.ac index 559b8088ae..cb517a1a94 100755 --- a/configure.ac +++ b/configure.ac @@ -2026,6 +2026,9 @@ AC_CONFIG_FILES([ AC_CONFIG_FILES([vtysh/extract.pl],[chmod +x vtysh/extract.pl]) AC_CONFIG_FILES([tools/frr],[chmod +x tools/frr]) +AC_CONFIG_FILES([tools/watchfrr.sh],[chmod +x tools/watchfrr.sh]) +AC_CONFIG_FILES([tools/frrinit.sh],[chmod +x tools/frrinit.sh]) +AC_CONFIG_FILES([tools/frrcommon.sh]) AC_CONFIG_COMMANDS([lib/route_types.h], [ dst="${ac_abs_top_builddir}/lib/route_types.h" diff --git a/debianpkg/backports/ubuntu12.04/debian/control b/debianpkg/backports/ubuntu12.04/debian/control deleted file mode 100644 index 9bae348840..0000000000 --- a/debianpkg/backports/ubuntu12.04/debian/control +++ /dev/null @@ -1,56 +0,0 @@ -Source: frr -Section: net -Priority: optional -Maintainer: Nobody -Uploaders: Nobody -XSBC-Original-Maintainer: -Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson0, libjson0-dev, pkg-config, python (>= 2.7), python-ipaddr -Standards-Version: 3.9.6 -Homepage: http://www.frrouting.org/ -XS-Testsuite: autopkgtest - -Package: frr -Architecture: any -Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), ${misc:Depends} -Pre-Depends: adduser -Conflicts: zebra, zebra-pj, quagga -Replaces: zebra, zebra-pj -Suggests: snmpd -Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon forked from Quagga - FRR is free software which manages TCP/IP based routing protocols. - It supports BGP4, BGP4+, OSPFv2, OSPFv3, IS-IS, RIPv1, RIPv2, RIPng, - PIM and LDP as well as the IPv6 versions of these. - . - FRR is a fork of Quagga with an open community model. The main git - lives on https://github.com/frrouting/frr.git - -Package: frr-dbg -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, frr (= ${binary:Version}) -Priority: extra -Section: debug -Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (debug symbols) - This package provides debugging symbols for all binary packages built - from frr source package. It's highly recommended to have this package - installed before reporting any FRR crashes to either FRR developers or - Debian package maintainers. - -Package: frr-doc -Section: net -Architecture: all -Depends: ${misc:Depends} -Suggests: frr -Description: documentation files for FRR - This package includes info files for frr, a free software which manages - TCP/IP based routing protocols. It supports BGP4, BGP4+, OSPFv2, OSPFv3, - IS-IS, RIPv1, RIPv2, RIPng, PIM and LDP as well as the IPv6 versions of these. - -Package: frr-pythontools -Section: net -Architecture: all -Depends: ${misc:Depends}, frr (= ${binary:Version}), python (>= 2.7), python-ipaddr -Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (Python Tools) - This package includes info files for frr, a free software which manages - TCP/IP based routing protocols. It supports BGP4, BGP4+, OSPFv2, OSPFv3, - IS-IS, RIPv1, RIPv2, RIPng, PIM and LDP as well as the IPv6 versions of these. - diff --git a/debianpkg/backports/ubuntu12.04/debian/frr.install b/debianpkg/backports/ubuntu12.04/debian/frr.install deleted file mode 120000 index 83ecca5958..0000000000 --- a/debianpkg/backports/ubuntu12.04/debian/frr.install +++ /dev/null @@ -1 +0,0 @@ -../../ubuntu14.04/debian/frr.install \ No newline at end of file diff --git a/debianpkg/backports/ubuntu12.04/debian/frr.postinst b/debianpkg/backports/ubuntu12.04/debian/frr.postinst deleted file mode 120000 index eb98053c7b..0000000000 --- a/debianpkg/backports/ubuntu12.04/debian/frr.postinst +++ /dev/null @@ -1 +0,0 @@ -../../ubuntu14.04/debian/frr.postinst \ No newline at end of file diff --git a/debianpkg/backports/ubuntu12.04/debian/frr.postrm b/debianpkg/backports/ubuntu12.04/debian/frr.postrm deleted file mode 120000 index 4f4380872f..0000000000 --- a/debianpkg/backports/ubuntu12.04/debian/frr.postrm +++ /dev/null @@ -1 +0,0 @@ -../../ubuntu14.04/debian/frr.postrm \ No newline at end of file diff --git a/debianpkg/backports/ubuntu12.04/debian/rules b/debianpkg/backports/ubuntu12.04/debian/rules deleted file mode 100755 index 7495db89cb..0000000000 --- a/debianpkg/backports/ubuntu12.04/debian/rules +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/make -f - -# FRRouting Configuration options -###################################### -# -# WANT_xxxx --> Set to 1 for enable, 0 for disable -# The following are the defaults. They can be overridden by setting a -# env variable to a different value - -WANT_LDP ?= 1 -WANT_PIM ?= 1 -WANT_OSPFAPI ?= 1 -WANT_BGP_VNC ?= 1 -WANT_CUMULUS_MODE ?= 0 -WANT_MULTIPATH ?= 1 -WANT_SNMP ?= 0 - -# NOTES: -# -# If multipath is enabled (WANT_MULTIPATH=1), then set number of multipaths here -# Please be aware that 0 is NOT disabled, but treated as unlimited - -MULTIPATH ?= 256 - -# Set the following to the value required (or leave alone for the default below) -# WANT_FRR_USER is used for the username and groupname of the FRR user account - -WANT_FRR_USER ?= frr -WANT_FRR_VTY_GROUP ?= frrvty - -# Don't build PDF docs by default -GENERATE_PDF ?= 0 - -# -#################################### - -export DH_VERBOSE=1 -export DEB_BUILD_MAINT_OPTIONS = hardening=+all -export DH_OPTIONS=-v - -ifeq ($(WANT_SNMP), 1) - USE_SNMP=--enable-snmp - $(warning "DEBIAN: SNMP enabled, sorry for your inconvenience") -else - USE_SNMP=--disable-snmp - $(warning "DEBIAN: SNMP disabled, see README.Debian") -endif - -ifeq ($(WANT_LDP), 1) - USE_LDP=--enable-ldpd -else - USE_LDP=--disable-ldpd -endif - -ifeq ($(WANT_PIM), 1) - USE_PIM=--enable-pimd -else - USE_PIM=--disable-pimd -endif - -ifeq ($(WANT_OSPFAPI), 1) - USE_OSPFAPI=--enable-ospfapi=yes -else - USE_OSPFAPI=--enable-ospfapi=no -endif - -ifeq ($(WANT_BGP_VNC), 1) - USE_BGP_VNC=--enable-bgp-vnc=yes -else - USE_BGP_VNC=--enable-bgp-vnc=no -endif - -USE_FRR_USER=--enable-user=$(WANT_FRR_USER) -USE_FRR_GROUP=--enable-group=$(WANT_FRR_USER) -USE_FRR_VTY_GROUP=--enable-vty-group=$(WANT_FRR_VTY_GROUP) - -ifeq ($(WANT_MULTIPATH), 1) - USE_MULTIPATH=--enable-multipath=$(MULTIPATH) -else - USE_MULTIPATH=--disable-multipath -endif - -ifeq ($(WANT_CUMULUS_MODE), 1) - USE_CUMULUS=--enable-cumulus=yes -else - USE_CUMULUS=--enable-cumulus=no -endif - -ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) - DEBIAN_JOBS := $(subst parallel=,,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) -endif - -ifdef DEBIAN_JOBS -MAKEFLAGS += -j$(DEBIAN_JOBS) -endif - -%: - dh $@ --with=autoreconf --parallel --dbg-package=frr-dbg --list-missing - -override_dh_auto_configure: - # Frr needs /proc to check some BSD vs Linux specific stuff. - # Else it fails with an obscure error message pointing out that - # IPCTL_FORWARDING is an undefined symbol which is not very helpful. - @if ! [ -d /proc/1 ]; then \ - echo "./configure needs a mounted /proc"; \ - exit 1; \ - fi - - if ! [ -e config.status ]; then \ - dh_auto_configure -- \ - --enable-exampledir=/usr/share/doc/frr/examples/ \ - --localstatedir=/var/run/frr \ - --sbindir=/usr/lib/frr \ - --sysconfdir=/etc/frr \ - $(USE_SNMP) \ - $(USE_OSPFAPI) \ - $(USE_MULTIPATH) \ - $(USE_LDP) \ - --enable-fpm \ - $(USE_FRR_USER) $(USE_FRR_GROUP) \ - $(USE_FRR_VTY_GROUP) \ - --enable-configfile-mask=0640 \ - --enable-logfile-mask=0640 \ - --with-libpam \ - --enable-systemd=no \ - --enable-poll=yes \ - $(USE_CUMULUS) \ - $(USE_PIM) \ - --disable-bfdd \ - --enable-dependency-tracking \ - $(USE_BGP_VNC) \ - $(shell dpkg-buildflags --export=configure); \ - fi - -override_dh_auto_build: -ifeq ($(GENERATE_PDF), 1) - dh_auto_build -- -C doc pdf -endif - rm -vf doc/user/_build/texinfo/frr.info - dh_auto_build -- -C doc info - -override_dh_auto_test: - -override_dh_auto_install: - dh_auto_install - - # installed in frr-pythontools - rm debian/tmp/usr/lib/frr/frr-reload.py - - # cleaning up the info dir - rm -f debian/tmp/usr/share/info/dir* - - # install config files - mkdir -p debian/tmp/etc/frr/ - perl -pi -e 's#^!log file #!log file /var/log/frr/#' debian/tmp/usr/share/doc/frr/examples/*sample* - - # leftover from previously shipping SMUX client OID MIB - mkdir -p debian/tmp/usr/share/snmp/mibs - - # cleaning .la files - sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/*.la - sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/frr/modules/*.la diff --git a/debianpkg/backports/ubuntu12.04/debian/source/format b/debianpkg/backports/ubuntu12.04/debian/source/format deleted file mode 100644 index 163aaf8d82..0000000000 --- a/debianpkg/backports/ubuntu12.04/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/debianpkg/backports/ubuntu12.04/exclude b/debianpkg/backports/ubuntu12.04/exclude deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/debianpkg/backports/ubuntu12.04/versionext b/debianpkg/backports/ubuntu12.04/versionext deleted file mode 100644 index 159e2e4160..0000000000 --- a/debianpkg/backports/ubuntu12.04/versionext +++ /dev/null @@ -1 +0,0 @@ --1~ubuntu12.04+1 diff --git a/debianpkg/backports/ubuntu14.04/debian/frr.install b/debianpkg/backports/ubuntu14.04/debian/frr.install index 0b0d953acf..a3c90528b7 100644 --- a/debianpkg/backports/ubuntu14.04/debian/frr.install +++ b/debianpkg/backports/ubuntu14.04/debian/frr.install @@ -3,7 +3,6 @@ usr/bin/vtysh usr/bin/mtracebis usr/include/frr/ usr/lib/ -tools/frr etc/init.d/ usr/share/doc/frr/ usr/share/snmp/mibs/ tools/etc/* etc/ diff --git a/debianpkg/backports/ubuntu14.04/debian/frr.postinst b/debianpkg/backports/ubuntu14.04/debian/frr.postinst deleted file mode 100644 index 5a14e510cd..0000000000 --- a/debianpkg/backports/ubuntu14.04/debian/frr.postinst +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -e - -###################### -PASSWDFILE=/etc/passwd -GROUPFILE=/etc/group - -frruid=`egrep "^frr:" $PASSWDFILE | awk -F ":" '{ print $3 }'` -frrgid=`egrep "^frr:" $GROUPFILE | awk -F ":" '{ print $3 }'` -frrvtygid=`egrep "^frrvty:" $GROUPFILE | awk -F ":" '{ print $3 }'` - -[ -n ${frruid} ] || (echo "No uid for frr in ${PASSWDFILE}" && /bin/false) -[ -n ${frrgid} ] || (echo "No gid for frr in ${GROUPFILE}" && /bin/false) -[ -n ${frrVTYgid} ] || (echo "No gid for frrvty in ${GROUPFILE}" && /bin/false) - -chown -R ${frruid}:${frrgid} /etc/frr -touch /etc/frr/vtysh.conf -chgrp ${frrvtygid} /etc/frr/vtysh* -chmod 644 /etc/frr/* - -ENVIRONMENTFILE=/etc/environment -if ! egrep --quiet '^VTYSH_PAGER=' ${ENVIRONMENTFILE}; then - echo "VTYSH_PAGER=/bin/cat" >> ${ENVIRONMENTFILE} -fi -################################################## - -if [ -n "$DEBIAN_SCRIPT_DEBUG" ]; then set -v -x; DEBIAN_SCRIPT_TRACE=1; fi -${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*"} - -# This is most likely due to the answer "no" to the "really stop the server" -# question in the prerm script. -if [ "$1" = "abort-upgrade" ]; then - exit 0 -fi - -update-rc.d frr defaults > /dev/null - -#DEBHELPER# - diff --git a/debianpkg/backports/ubuntu14.04/debian/frr.postrm b/debianpkg/backports/ubuntu14.04/debian/frr.postrm deleted file mode 100644 index 48c23321f7..0000000000 --- a/debianpkg/backports/ubuntu14.04/debian/frr.postrm +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -e - -if [ -n "$DEBIAN_SCRIPT_DEBUG" ]; then set -v -x; DEBIAN_SCRIPT_TRACE=1; fi -${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*"} -# set -u not because of debhelper - -update-rc.d -f frr remove >> /dev/null - -if [ "$1" = "purge" ]; then - rm -rf /etc/frr /var/run/frr /var/log/frr - userdel frr >/dev/null 2>&1 || true -fi - -#DEBHELPER# diff --git a/debianpkg/backports/ubuntu14.04/debian/rules b/debianpkg/backports/ubuntu14.04/debian/rules index c955d0c945..537990afdf 100755 --- a/debianpkg/backports/ubuntu14.04/debian/rules +++ b/debianpkg/backports/ubuntu14.04/debian/rules @@ -178,6 +178,8 @@ override_dh_auto_test: override_dh_auto_install: dh_auto_install + cp tools/frrinit.sh debian/frr.init + # installed in frr-pythontools rm debian/tmp/usr/lib/frr/frr-reload.py diff --git a/debianpkg/rules b/debianpkg/rules index 894cd7f198..5326af81b2 100755 --- a/debianpkg/rules +++ b/debianpkg/rules @@ -170,7 +170,7 @@ override_dh_systemd_enable: # backports SRCPKG = frr -KNOWN_BACKPORTS = debian8 debian9 ubuntu12.04 ubuntu14.04 ubuntu16.04 ubuntu17.10 ubuntu18.04 +KNOWN_BACKPORTS = debian8 debian9 ubuntu14.04 ubuntu16.04 ubuntu17.10 ubuntu18.04 DEBIAN_VERSION := $(shell dh_testdir && \ dpkg-parsechangelog -c1 < debian/changelog | \ sed -rn 's/^Version: ?//p') diff --git a/debianpkg/subdir.am b/debianpkg/subdir.am index b6251962b7..af17e4642a 100644 --- a/debianpkg/subdir.am +++ b/debianpkg/subdir.am @@ -23,18 +23,8 @@ EXTRA_DIST += \ debianpkg/backports/debian9/debian/source/format \ debianpkg/backports/debian9/exclude \ debianpkg/backports/debian9/versionext \ - debianpkg/backports/ubuntu12.04/debian/control \ - debianpkg/backports/ubuntu12.04/debian/frr.install \ - debianpkg/backports/ubuntu12.04/debian/frr.postinst \ - debianpkg/backports/ubuntu12.04/debian/frr.postrm \ - debianpkg/backports/ubuntu12.04/debian/rules \ - debianpkg/backports/ubuntu12.04/debian/source/format \ - debianpkg/backports/ubuntu12.04/exclude \ - debianpkg/backports/ubuntu12.04/versionext \ debianpkg/backports/ubuntu14.04/debian/control \ debianpkg/backports/ubuntu14.04/debian/frr.install \ - debianpkg/backports/ubuntu14.04/debian/frr.postinst \ - debianpkg/backports/ubuntu14.04/debian/frr.postrm \ debianpkg/backports/ubuntu14.04/debian/rules \ debianpkg/backports/ubuntu14.04/debian/source/format \ debianpkg/backports/ubuntu14.04/exclude \ diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in index efc4826171..51ec7006df 100644 --- a/redhat/frr.spec.in +++ b/redhat/frr.spec.in @@ -631,6 +631,9 @@ fi %config(noreplace) %{_sysconfdir}/pam.d/frr %config(noreplace) %{_sysconfdir}/logrotate.d/frr %{_sbindir}/frr-reload +%{_sbindir}/frrcommon.sh +%{_sbindir}/frrinit.sh +%{_sbindir}/watchfrr.sh %files contrib diff --git a/tools/.gitignore b/tools/.gitignore index a8d01d680e..cbcd222561 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -1,3 +1,6 @@ /frr /permutations /ssd +/watchfrr.sh +/frrinit.sh +/frrcommon.sh diff --git a/tools/etc/frr/daemons b/tools/etc/frr/daemons index 474b299d90..ff36b08763 100644 --- a/tools/etc/frr/daemons +++ b/tools/etc/frr/daemons @@ -1,11 +1,5 @@ # This file tells the frr package which daemons to start. # -# Entries are in the format: =(yes|no|priority) -# 0, "no" = disabled -# 1, "yes" = highest priority -# 2 .. 10 = lower priorities -# Read /usr/share/doc/frr/README.Debian for details. -# # Sample configurations for these daemons can be found in # /usr/share/doc/frr/examples/. # @@ -18,10 +12,8 @@ # When using "vtysh" such a config file is also needed. It should be owned by # group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too. # -# The watchfrr daemon is always started. Per default in monitoring-only but -# that can be changed via /etc/frr/daemons.conf. +# The watchfrr and zebra daemons are always started. # -zebra=no bgpd=no ospfd=no ospf6d=no diff --git a/tools/etc/frr/daemons.conf b/tools/etc/frr/daemons.conf index 640437f441..ace01fd2fe 100644 --- a/tools/etc/frr/daemons.conf +++ b/tools/etc/frr/daemons.conf @@ -4,28 +4,29 @@ # Check /etc/pam.d/frr if you intend to use "vtysh"! # vtysh_enable=yes -zebra_options=" -s 90000000 --daemon -A 127.0.0.1" -bgpd_options=" --daemon -A 127.0.0.1" -ospfd_options=" --daemon -A 127.0.0.1" -ospf6d_options=" --daemon -A ::1" -ripd_options=" --daemon -A 127.0.0.1" -ripngd_options=" --daemon -A ::1" -isisd_options=" --daemon -A 127.0.0.1" -pimd_options=" --daemon -A 127.0.0.1" -ldpd_options=" --daemon -A 127.0.0.1" -nhrpd_options=" --daemon -A 127.0.0.1" -eigrpd_options=" --daemon -A 127.0.0.1" -babeld_options=" --daemon -A 127.0.0.1" -sharpd_options=" --daemon -A 127.0.0.1" -pbrd_options=" --daemon -A 127.0.0.1" -staticd_options=" --daemon -A 127.0.0.1" -bfdd_options=" --daemon -A 127.0.0.1" +zebra_options=" -A 127.0.0.1 -s 90000000" +bgpd_options=" -A 127.0.0.1" +ospfd_options=" -A 127.0.0.1" +ospf6d_options=" -A ::1" +ripd_options=" -A 127.0.0.1" +ripngd_options=" -A ::1" +isisd_options=" -A 127.0.0.1" +pimd_options=" -A 127.0.0.1" +ldpd_options=" -A 127.0.0.1" +nhrpd_options=" -A 127.0.0.1" +eigrpd_options=" -A 127.0.0.1" +babeld_options=" -A 127.0.0.1" +sharpd_options=" -A 127.0.0.1" +pbrd_options=" -A 127.0.0.1" +staticd_options="-A 127.0.0.1" +bfdd_options=" -A 127.0.0.1" # The list of daemons to watch is automatically generated by the init script. -watchfrr_enable=yes -watchfrr_options=(-d -r /usr/sbin/servicebBfrrbBrestartbB%s -s /usr/sbin/servicebBfrrbBstartbB%s -k /usr/sbin/servicebBfrrbBstopbB%s -b bB) +watchfrr_options="-r '/usr/lib/frr/watchfrr.sh restart %s' -s '/usr/lib/frr/watchfrr.sh start %s' -k '/usr/lib/frr/watchfrr.sh stop %s'" -# If valgrind_enable is 'yes' the frr daemons will be started via valgrind. -# The use case for doing so is tracking down memory leaks, etc in frr. -valgrind_enable=no -valgrind=/usr/bin/valgrind +# for debugging purposes, you can specify a "wrap" command to start instead +# of starting the daemon directly, e.g. to use valgrind on ospfd: +# ospfd_wrap="/usr/bin/valgrind" +# or you can use "all_wrap" for all daemons, e.g. to use perf record: +# all_wrap="/usr/bin/perf record --call-graph -" +# the normal daemon command is added to this at the end. diff --git a/tools/frr.service b/tools/frr.service index 5f44274ec3..03112bd7cd 100644 --- a/tools/frr.service +++ b/tools/frr.service @@ -5,7 +5,6 @@ OnFailure=heartbeat-failed@%n.service [Service] Nice=-5 -EnvironmentFile=/etc/default/frr Type=forking NotifyAccess=all StartLimitInterval=3m @@ -15,8 +14,8 @@ WatchdogSec=60s RestartSec=5 Restart=on-abnormal LimitNOFILE=1024 -ExecStart=/usr/lib/frr/frr start -ExecStop=/usr/lib/frr/frr stop -ExecReload=/usr/lib/frr/frr-reload +ExecStart=/usr/lib/frr/frrinit.sh start +ExecStop=/usr/lib/frr/frrinit.sh stop +ExecReload=/usr/lib/frr/frrinit.sh reload [Install] WantedBy=network-online.target diff --git a/tools/frrcommon.sh.in b/tools/frrcommon.sh.in new file mode 100644 index 0000000000..7278e3f9df --- /dev/null +++ b/tools/frrcommon.sh.in @@ -0,0 +1,317 @@ +#!/bin/sh +# +# This is a "library" of sorts for use by the other FRR shell scripts. It +# has most of the daemon start/stop logic, but expects the following shell +# functions/commands to be provided by the "calling" script: +# +# log_success_msg +# log_warning_msg +# log_failure_msg +# +# (coincidentally, these are LSB standard functions.) +# +# Sourcing this file in a shell script will load FRR config variables but +# not perform any action. Note there is an "exit 1" if the main config +# file does not exist. +# +# This script should be installed in @CFG_SBIN@/frrcommon.sh + +PATH=/bin:/usr/bin:/sbin:/usr/sbin +D_PATH="@CFG_SBIN@" # /usr/lib/frr +C_PATH="@CFG_SYSCONF@" # /etc/frr +V_PATH="@CFG_STATE@" # /var/run/frr +VTYSH="@vtysh_bin@" # /usr/bin/vtysh +FRR_USER="@enable_user@" # frr +FRR_GROUP="@enable_group@" # frr +FRR_VTY_GROUP="@enable_vty_group@" # frrvty + +# ORDER MATTERS FOR $DAEMONS! +# - keep zebra first +# - watchfrr does NOT belong in this list + +DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd sharpd pbrd staticd bfdd fabricd" +RELOAD_SCRIPT="$D_PATH/frr-reload.py" + +# +# general helpers +# + +debug() { + [ -n "$watchfrr_debug" ] || return 0 + + printf '%s %s(%s):' "`date +%Y-%m-%dT%H:%M:%S.%N`" "$0" $$ >&2 + # this is to show how arguments are split regarding whitespace & co. + # (e.g. for use with `debug "message" "$@"`) + while [ $# -gt 0 ]; do + printf ' "%s"' "$1" >&2 + shift + done + printf '\n' >&2 +} + +chownfrr() { + [ -n "$FRR_USER" ] && chown "$FRR_USER" "$1" + [ -n "$FRR_GROUP" ] && chgrp "$FRR_GROUP" "$1" +} + +vtysh_b () { + [ "$1" = "watchfrr" ] && return 0 + [ -r "$C_PATH/frr.conf" ] || return 0 + if [ -n "$1" ]; then + "$VTYSH" -b -n -d "$1" + else + "$VTYSH" -b -n + fi +} + +daemon_inst() { + # note this sets global variables ($dmninst, $daemon, $inst) + dmninst="$1" + daemon="${dmninst%:*}" + inst="" + [ "$daemon" != "$dmninst" ] && inst="${dmninst#*:}" +} + +daemon_list() { + # note $1 and $2 specify names for global variables to be set + local enabled disabled evar dvar + enabled="" + disabled="" + evar="$1" + dvar="$2" + + for daemon in $DAEMONS; do + eval cfg=\$$daemon + eval inst=\$${daemon}_instances + [ "$daemon" = zebra ] && cfg=yes + if [ -n "$cfg" -a "$cfg" != "no" -a "$cfg" != "0" ]; then + debug "$daemon enabled" + enabled="$enabled $daemon" + if [ -n "$inst" ]; then + debug "$daemon multi-instance $inst" + for i in $inst; do + enabled="$enabled $daemon:$inst" + done + fi + else + debug "$daemon disabled" + disabled="$disabled $daemon" + fi + done + + enabled="${enabled# }" + disabled="${disabled# }" + [ -z "$evar" ] && echo "$enabled" + [ -n "$evar" ] && eval $evar="\"$enabled\"" + [ -n "$dvar" ] && eval $dvar="\"$disabled\"" +} + +# +# individual daemon management +# + +daemon_prep() { + local daemon inst cfg + daemon="$1" + inst="$2" + [ "$daemon" = "watchfrr" ] && return 0 + [ -x "$D_PATH/$daemon" ] || { + log_failure_msg "cannot start $daemon${inst:+ (instance $inst)}: daemon binary not installed\n" + return 1 + } + [ -r "$C_PATH/frr.conf" ] && return 0 + + cfg="$C_PATH/$daemon${inst:+-$inst}.conf" + if [ ! -r "$cfg" ]; then + touch "$cfg" + chownfrr "$cfg" + fi + return 0 +} + +daemon_start() { + local dmninst daemon inst args instopt wrap bin + daemon_inst "$1" + + ulimit -n $MAX_FDS > /dev/null 2> /dev/null + daemon_prep "$daemon" "$inst" || return 1 + + eval wrap="\$${daemon}_wrap" + bin="$D_PATH/$daemon" + instopt="${inst:+-n $inst}" + eval args="\$${daemon}_options" + + if eval "$all_wrap $wrap $bin -d $instopt $args"; then + log_success_msg "Started $dmninst" + vtysh_b "$daemon" + else + log_failure_msg "Failed to start $dmninst!" + fi +} + +daemon_stop() { + local dmninst daemon inst pidfile vtyfile pid cnt fail + daemon_inst "$1" + + pidfile="$V_PATH/$daemon${inst:+-$inst}.pid" + vtyfile="$V_PATH/$daemon${inst:+-$inst}.vty" + + [ -r "$pidfile" ] || fail="pid file not found" + [ -z "$fail" ] && pid="`cat \"$pidfile\"`" + [ -z "$fail" -a -z "$pid" ] && fail="pid file is empty" + [ -n "$fail" ] || kill -0 "$pid" 2>/dev/null || fail="pid $pid not running" + + if [ -n "$fail" ]; then + log_failure_msg "Cannot stop $dmninst: $fail" + return 1 + fi + + debug "kill -2 $pid" + kill -2 "$pid" + cnt=1200 + while kill -0 "$pid" 2>/dev/null; do + sleep .1 + [ $(( cnt -= 1 )) -gt 0 ] || break + done + if kill -0 "$pid" 2>/dev/null; then + log_failure_msg "Failed to stop $dmninst, pid $pid still running" + still_running=1 + return 1 + else + log_success_msg "Stopped $dmninst" + rm -f "$pidfile" + return 0 + fi +} + +daemon_status() { + local dmninst daemon inst pidfile pid fail + daemon_inst "$1" + + pidfile="$V_PATH/$daemon${inst:+-$inst}.pid" + + [ -r "$pidfile" ] || return 3 + pid="`cat \"$pidfile\"`" + [ -z "$pid" ] && return 1 + kill -0 "$pid" 2>/dev/null || return 1 + return 0 +} + +print_status() { + daemon_status "$1" + rv=$? + if [ "$rv" -eq 0 ]; then + log_success_msg "Status of $1: running" + else + log_failure_msg "Status of $1: FAILED" + fi + return $rv +} + +# +# all-daemon commands +# + +all_start() { + daemon_list daemons + for dmninst in $daemons; do + daemon_start "$dmninst" + done +} + +all_stop() { + local pids reversed + + daemon_list daemons disabled + [ "$1" = "--reallyall" ] && daemons="$daemons $disabled" + + reversed="" + for dmninst in $daemons; do + reversed="$dmninst $reversed" + done + + for dmninst in $reversed; do + daemon_stop "$dmninst" & + pids="$pids $!" + done + for pid in $pids; do + wait $pid + done +} + +all_status() { + local fail + + daemon_list daemons + fail=0 + for dmninst in $daemons; do + print_status "$dmninst" || fail=1 + done + return $fail +} + +# +# config sourcing +# + +load_old_config() { + oldcfg="$1" + [ -r "$oldcfg" ] || return 0 + [ -s "$oldcfg" ] || return 0 + grep -v '^[[:blank:]]*\(#\|$\)' "$oldcfg" > /dev/null || return 0 + + log_warning_msg "Reading deprecated $oldcfg. Please move its settings to $C_PATH/daemons and remove it." + + # save off settings from daemons for the OR below + for dmn in $DAEMONS; do eval "_new_$dmn=\${$dmn:-no}"; done + + . "$oldcfg" + + # OR together the daemon enabling options between config files + for dmn in $DAEMONS; do eval "test \$_new_$dmn != no && $dmn=\$_new_$dmn; unset _new_$dmn"; done +} + +[ -r "$C_PATH/daemons" ] || { + log_failure_msg "cannot run $@: $C_PATH/daemons does not exist\n" + exit 1 +} +. "$C_PATH/daemons" + +load_old_config "$C_PATH/daemons.conf" +load_old_config "/etc/default/frr" +load_old_config "/etc/sysconfig/frr" + +# +# other defaults and dispatch +# + +frrcommon_main() { + local cmd + + debug "frrcommon_main" "$@" + + cmd="$1" + shift + + if [ "$1" = "all" -o -z "$1" ]; then + case "$cmd" in + start) all_start;; + stop) all_stop;; + restart) + all_stop + all_start + ;; + *) $cmd "$@";; + esac + else + case "$cmd" in + start) daemon_start "$@";; + stop) daemon_stop "$@";; + restart) + daemon_stop "$@" + daemon_start "$@" + ;; + *) $cmd "$@";; + esac + fi +} diff --git a/tools/frrinit.sh.in b/tools/frrinit.sh.in new file mode 100644 index 0000000000..3dddf5bd44 --- /dev/null +++ b/tools/frrinit.sh.in @@ -0,0 +1,90 @@ +#!/bin/sh +# +### BEGIN INIT INFO +# Provides: frr +# Required-Start: $local_fs $network $remote_fs $syslog +# Required-Stop: $local_fs $network $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: start and stop the FRR routing suite +# Description: FRR is a routing suite for IP routing protocols like +# BGP, OSPF, RIP and others. This script contols the main +# "watchfrr" daemon. +### END INIT INFO +# +# This is the main init script for FRR. It mostly wraps frrcommon.sh which +# provides the actual functions to start/stop/restart things. +# + +if [ -r "/lib/lsb/init-functions" ]; then + . /lib/lsb/init-functions +else + log_success_msg() { + echo "$@" + } + log_warning_msg() { + echo "$@" >&2 + } + log_failure_msg() { + echo "$@" >&2 + } +fi + +self="`dirname $0`" +if [ -r "$self/frrcommon.sh" ]; then + . "$self/frrcommon.sh" +else + . "@CFG_SBIN@/frrcommon.sh" +fi + +case "$1" in +start) + daemon_list daemons + watchfrr_options="$watchfrr_options $daemons" + daemon_start watchfrr + ;; +stop) + daemon_stop watchfrr + all_stop --reallyall + exit ${still_running:-0} + ;; + +restart|force-reload) + daemon_stop watchfrr + all_stop --reallyall + + daemon_list daemons + watchfrr_options="$watchfrr_options $daemons" + daemon_start watchfrr + ;; + +status) + fail=0 + print_status watchfrr || fail=1 + all_status || fail=1 + exit $fail + ;; + +reload) + if [ ! -x "$RELOAD_SCRIPT" ]; then + log_failure_msg "The frr-pythontools package is required for reload functionality." + exit 1 + fi + + # restart watchfrr to pick up added daemons. + # NB: This will NOT cause the other daemons to be restarted. + daemon_list daemons + watchfrr_options="$watchfrr_options $daemons" + daemon_stop watchfrr && \ + daemon_start watchfrr + + NEW_CONFIG_FILE="${2:-$C_PATH/frr.conf}" + [ ! -r $NEW_CONFIG_FILE ] && log_failure_msg "Unable to read new configuration file $NEW_CONFIG_FILE" && exit 1 + "$RELOAD_SCRIPT" --reload "$NEW_CONFIG_FILE" + exit $? + ;; + +*) + log_failure_msg "Unknown command: $1" >&2 + exit 1 +esac diff --git a/tools/subdir.am b/tools/subdir.am index f8a14d10cc..a13fef0217 100644 --- a/tools/subdir.am +++ b/tools/subdir.am @@ -8,6 +8,10 @@ sbin_SCRIPTS += \ tools/frr-reload \ tools/frr-reload.py \ tools/frr \ + \ + tools/frrcommon.sh \ + tools/frrinit.sh \ + tools/watchfrr.sh \ # end tools_permutations_SOURCES = tools/permutations.c diff --git a/tools/watchfrr.sh.in b/tools/watchfrr.sh.in new file mode 100644 index 0000000000..3051d91044 --- /dev/null +++ b/tools/watchfrr.sh.in @@ -0,0 +1,33 @@ +#!/bin/sh +# +# This is NOT the init script! This is the watchfrr start/stop/restart +# command handler, passed to watchfrr with the -s/-r/-k commands. It is used +# internally by watchfrr to start the protocol daemons with the appropriate +# options. +# +# This script should be installed in @CFG_SBIN@/watchfrr.sh + +log_success_msg() { + : +} + +log_warning_msg() { + echo "$@" >&2 + [ -x /usr/bin/logger ] && echo "$@" \ + | /usr/bin/logger -t watchfrr.sh -p daemon.warn +} + +log_failure_msg() { + echo "$@" >&2 + [ -x /usr/bin/logger ] && echo "$@" \ + | /usr/bin/logger -t watchfrr.sh -p daemon.err +} + +self="`dirname $0`" +if [ -r "$self/frrcommon.sh" ]; then + . "$self/frrcommon.sh" +else + . "@CFG_SBIN@/frrcommon.sh" +fi + +frrcommon_main "$@" -- 2.39.5