Move init system detection from configure to resolvconf.
authorRoy Marples <roy@marples.name>
Tue, 23 Feb 2016 21:18:17 +0000 (21:18 +0000)
committerRoy Marples <roy@marples.name>
Tue, 23 Feb 2016 21:18:17 +0000 (21:18 +0000)
resolvconf -r service can now restart a service, resolvconf -R will show how.

This allows a user to have OpenRC and/or SystemD alongside their base init
system and resolvconf will pick the one that is actually in use.
This, of course, can be overriden per subscriber.

Makefile
configure
dnsmasq.in
libc.in
named.in
resolvconf.8.in
resolvconf.in
unbound.in

index 3171a032c2f7895648b20ec074ab039f0c560161..5c1f8cab4bf54818a4da679644a41d886d2ca6df 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 PKG=           openresolv
-VERSION=       3.7.3
+VERSION=       3.8.0
 
 # Nasty hack so that make clean works without configure being run
 _CONFIG_MK!=   test -e config.mk && echo config.mk || echo config-null.mk
@@ -10,10 +10,6 @@ SBINDIR?=    /sbin
 SYSCONFDIR?=   /etc
 LIBEXECDIR?=   /libexec/resolvconf
 VARDIR?=       /var/run/resolvconf
-RCDIR?=                /etc/rc.d
-RESTARTCMD?=   if ${RCDIR}/\1 status >/dev/null 2>\&1; then \
-                       ${RCDIR}/\1 restart; \
-               fi
 
 INSTALL?=      install
 SED?=          sed
@@ -33,7 +29,8 @@ SED_SYSCONFDIR=               -e 's:@SYSCONFDIR@:${SYSCONFDIR}:g'
 SED_LIBEXECDIR=                -e 's:@LIBEXECDIR@:${LIBEXECDIR}:g'
 SED_VARDIR=            -e 's:@VARDIR@:${VARDIR}:g'
 SED_RCDIR=             -e 's:@RCDIR@:${RCDIR}:g'
-SED_RESTARTCMD=                -e 's:@RESTARTCMD \(.*\)@:${RESTARTCMD}:g'
+SED_RESTARTCMD=                -e 's:@RESTARTCMD@:${RESTARTCMD}:g'
+SED_RCDIR=             -e 's:@RCDIR@:${RCDIR}:g'
 
 DISTPREFIX?=   ${PKG}-${VERSION}
 DISTFILEGZ?=   ${DISTPREFIX}.tar.gz
@@ -46,7 +43,7 @@ all: ${TARGET}
 
 .in:
        ${SED}  ${SED_SBINDIR} ${SED_SYSCONFDIR} ${SED_LIBEXECDIR} \
-               ${SED_VARDIR} ${SED_RCDIR} ${SED_RESTARTCMD} \
+               ${SED_VARDIR} ${SED_RCDIR} ${SED_RESTARTCMD} ${SED_RCDIR} \
                $< > $@
 
 clean:
index 2065794abce8255eeb013dc027b06b8f8aa7a640..f96edc5c718bad3b6dc7a27e115a17673b7e2bc7 100755 (executable)
--- a/configure
+++ b/configure
@@ -6,8 +6,6 @@ OS=
 BUILD=
 HOST=
 TARGET=
-RESTARTCMD=
-RCDIR=
 
 for x do
        opt=${x%%=*}
@@ -117,7 +115,7 @@ echo "Configuring openresolv for ... $OS"
 rm -rf $CONFIG_MK
 echo "# $OS" >$CONFIG_MK
 
-for x in SYSCONFDIR SBINDIR LIBEXECDIR VARDIR MANDIR; do
+for x in SYSCONFDIR SBINDIR LIBEXECDIR VARDIR MANDIR RESTARTCMD RCDIR; do
        eval v=\$$x
        # Make files look nice for import
        l=$((10 - ${#x}))
@@ -126,99 +124,6 @@ for x in SYSCONFDIR SBINDIR LIBEXECDIR VARDIR MANDIR; do
        echo "$x=$t     $v" >>$CONFIG_MK
 done
 
-if [ -z "$RESTARTCMD" ]; then
-       printf "Checking for systemd ... "
-       if [ -x /bin/systemctl ]; then
-               RESTARTCMD="/bin/systemctl"
-               echo "yes"
-       elif [ -x /usr/bin/systemctl ]; then
-               RESTARTCMD="/usr/bin/systemctl"
-               echo "yes"
-       else
-               echo "no"
-       fi
-       if [ -n "$RESTARTCMD"]; then
-               RESTARTCMD="if $RESTARTCMD --quiet is-active \1.service; then $RESTARTCMD restart \1.service; fi"
-       fi
-fi
-
-# Arch upgraded to systemd, so this check has to be just after systemd
-# but higher than the others
-if [ -z "$RESTARTCMD" ]; then
-       printf "Checking for Arch ... "
-       if [ -e /etc/arch-release -a -d /etc/rc.d ]; then
-               RCDIR=/etc/rc.d
-               RESTARTCMD="[ -e /var/run/daemons/\1 ] \&\& /etc/rc.d/\1 restart"
-               echo "yes"
-       else
-               echo "no"
-       fi
-fi
-
-if [ -z "$RESTARTCMD" ]; then
-       printf "Checking for OpenRC ... "
-       if [ -x /sbin/rc-service ]; then
-               RESTARTCMD="if /sbin/rc-service -e \1; then /sbin/rc-service \1 -- -Ds restart; fi"
-               echo "yes"
-       else
-               echo "no"
-       fi
-fi
-if [ -z "$RESTARTCMD" ]; then
-       printf "Checking for invoke-rc.d ... "
-       if [ -x /usr/sbin/invoke-rc.d ]; then
-               RCDIR=/etc/init.d
-               RESTARTCMD="if /usr/sbin/invoke-rc.d --quiet \1 status >/dev/null 2>\&1; then /usr/sbin/invoke-rc.d \1 restart; fi"
-               echo "yes"
-       else
-               echo "no"
-       fi
-fi
-if [ -z "$RESTARTCMD" ]; then
-       printf "Checking for service ... "
-       if [ -x /sbin/service ]; then
-               RCDIR=/etc/init.d
-               RESTARTCMD="if /sbin/service \1; then /sbin/service \1 restart; fi"
-               echo "yes"
-       else
-               echo "no"
-       fi
-fi
-if [ -z "$RESTARTCMD" ]; then
-       printf "Checking for runit... "
-       if [ -x /bin/sv ]; then
-               RESTARTCMD="/bin/sv try-restart \1"
-               echo "yes"
-       elif [ -x /usr/bin/sv ]; then
-               RESTARTCMD="/usr/bin/sv try-restart \1"
-               echo "yes"
-       else
-               echo "no"
-       fi
-fi
-if [ -z "$RESTARTCMD" ]; then
-       for x in /etc/init.d/rc.d /etc/rc.d /etc/init.d; do
-               printf "Checking for $x ... "
-               if [ -d $x ]; then
-                       RCDIR=$x
-                       RESTARTCMD="if $x/\1 status >/dev/null 2>\&1; then $x/\1 restart; fi"
-                       echo "yes"
-                       break
-               else
-                       echo "no"
-               fi
-       done
-fi
-
-if [ -z "$RESTARTCMD" ]; then
-       echo "$0: WARNING: No means of interacting with system services detected!"
-       exit 1
-fi
-
-echo "RCDIR=           $RCDIR" >>$CONFIG_MK
-# Work around bug in the dash shell as "echo 'foo \1'" does bad things
-printf "%s\n" "RESTARTCMD=     $RESTARTCMD" >>$CONFIG_MK
-
 echo
 echo "   SYSCONFDIR =          $SYSCONFDIR"
 echo "   SBINDIR =             $SBINDIR"
@@ -226,3 +131,6 @@ echo "   LIBEXECDIR =               $LIBEXECDIR"
 echo "   VARDIR =              $RUNDIR"
 echo "   MANDIR =              $MANDIR"
 echo
+echo "   RESTARTCMD =          $RESTARTCMD"
+echo "   RCDIR =               $RCDIR"
+echo
index 1b6ad16640c7562516ef4b1d1bdc87e56cb047af..77194eba3e508cea2306017ec85bd5b4520986f5 100644 (file)
@@ -37,7 +37,6 @@ NL="
 [ -s "$dnsmasq_pid" ] || dnsmasq_pid=/var/run/dnsmasq/dnsmasq.pid
 [ -s "$dnsmasq_pid" ] || unset dnsmasq_pid
 : ${dnsmasq_service:=dnsmasq}
-: ${dnsmasq_restart:=@RESTARTCMD ${dnsmasq_service}@}
 newconf="# Generated by resolvconf$NL"
 newresolv="$newconf"
 
@@ -180,7 +179,14 @@ if [ -n "$dnsmasq_resolv" ]; then
 fi
 
 if $changed; then
-       eval $dnsmasq_restart
+       if [ -n "$dnsmasq_restart" ]; then
+               eval $dnsmasq_restart
+       elif [ -n "$RESTARTCMD" ]; then
+               set -- ${dnsmasq_service}
+               eval $RESTARTCMD
+       else
+               @SBINDIR@/resolvconf -r ${dnsmasq_service}
+       fi
 fi
 if $dbus; then
        if [ -s "$dnsmasq_pid" ]; then
diff --git a/libc.in b/libc.in
index 3be134bfc83f6a4eea71274c1601de637a44b69d..be9c491f612a6f784cb33f154b9c104f6a1823d5 100644 (file)
--- a/libc.in
+++ b/libc.in
@@ -97,7 +97,6 @@ elif [ -d "$SYSCONFDIR"/resolvconf ]; then
 fi
 : ${resolv_conf:=/etc/resolv.conf}
 : ${libc_service:=nscd}
-: ${libc_restart:=@RESTARTCMD ${libc_service}@}
 : ${list_resolv:=@SBINDIR@/resolvconf -l}
 if [ "${resolv_conf_head-x}" = x -a -f "$SYSCONFDIR"/resolv.conf.head ]; then
        resolv_conf_head="$(cat "${SYSCONFDIR}"/resolv.conf.head)"
@@ -229,7 +228,14 @@ fi
 
 # Create our resolv.conf now
 (umask 022; printf %s "$newconf" >"$resolv_conf")
-eval $libc_restart
+if [ -n "$libc_restart" ]; then
+       eval $libc_restart
+elif [ -n "$RESTARTCMD" ]; then
+       set -- ${libc_service}
+       eval $RESTARTCMD
+else
+       @SBINDIR@/resolvconf -r ${libc_service}
+fi
 
 retval=0
 # Notify users of the resolver
index 43ceabb5e972caa3ace50c6e55c54747f7550ebd..b90ad61b08104f17491879f230715d0bac8b949e 100644 (file)
--- a/named.in
+++ b/named.in
@@ -35,18 +35,17 @@ NL="
 
 # Platform specific kludges
 if [ -z "$named_service" -a -z "$named_restart" -a \
-       -d "@RCDIR@" -a ! -x "@RCDIR@"/named ]
+       -d "$RCDIR" -a ! -x "$RCDIR"/named ]
 then
-       if [ -x "@RCDIR@"/bind9 ]; then
+       if [ -x "$RCDIR"/bind9 ]; then
                # Debian and derivatives
                named_service=bind9
-       elif [ -x "@RCDIR@"/rc.bind ]; then
+       elif [ -x "$RCDIR"/rc.bind ]; then
                # Slackware
                named_service=rc.bind
        fi
 fi
 : ${named_service:=named}
-: ${named_restart:=@RESTARTCMD ${named_service}@}
 newoptions="# Generated by resolvconf$NL"
 newzones="$newoptions"
 
@@ -102,5 +101,12 @@ if [ -n "$named_zones" ]; then
 fi
 
 if $changed; then
-       eval $named_restart
+       if [ -n "$named_restart" ]; then
+               eval $named_restart
+       elif [ -n "$RESTARTCMD" ]; then
+               set -- ${named_service}
+               eval $RESTARTCMD
+       else
+               @SBINDIR@/resolvconf -r ${named_service}
+       fi
 fi
index bfbfc7f4726a9c92ca1082e135f1fa239090a36c..6930b0f962d64d7eb6488956b34751972e17daac 100644 (file)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2007-2015 Roy Marples
+.\" Copyright (c) 2007-2016 Roy Marples
 .\" All rights reserved
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd April 27, 2015
+.Dd February 23, 2016
 .Dt RESOLVCONF 8
 .Os
 .Sh NAME
@@ -125,24 +125,28 @@ file(s) for all the
 on the
 .Ar interface .
 .Pp
-Here are some more options that
-.Nm
-has:-
+Here are some options for the above commands:-
 .Bl -tag -width indent
-.It Fl I
-Initialise the state directory
-.Pa @VARDIR@ .
-This only needs to be called if the initial system boot sequence does not
-automatically clean it out; for example the state directory is moved
-somewhere other than
-.Pa /var/run .
-If used, it should only be called once as early in the system boot sequence
-as possible and before
-.Nm
-is used to add interfaces.
 .It Fl f
 Ignore non existant interfaces.
 Only really useful for deleting interfaces.
+.It Fl m Ar metric
+Set the metric of the interface when adding it, default of 0.
+Lower metrics take precedence.
+This affects the default order of interfaces when listed.
+.It Fl p
+Marks the interface
+.Pa resolv.conf
+as private.
+.It Fl x
+Mark the interface
+.Pa resolv.conf
+as exclusive when adding, otherwise only use the latest exclusive interface.
+.El
+.Pp
+.Nm
+has some more commands for general usage:-
+.Bl -tag -width indent
 .It Fl i Ar pattern
 List the interfaces and protocols, optionally matching
 .Ar pattern ,
@@ -157,14 +161,6 @@ If
 .Ar pattern
 is specified then we list the files for the interfaces and protocols
 that match it.
-.It Fl m Ar metric
-Set the metric of the interface when adding it, default of 0.
-Lower metrics take precedence.
-This affects the default order of interfaces when listed.
-.It Fl p
-Marks the interface
-.Pa resolv.conf
-as private.
 .It Fl u
 Force
 .Nm
@@ -172,15 +168,31 @@ to update all its subscribers.
 .Nm
 does not update the subscribers when adding a resolv.conf that matches
 what it already has for that interface.
-.It Fl x
-Mark the interface
-.Pa resolv.conf
-as exclusive when adding, otherwise only use the latest exclusive interface.
 .El
 .Pp
 .Nm
-also has some options designed to be used by its subscribers:-
+also has some commands designed to be used by it's subscribers and
+system startup:-
 .Bl -tag -width indent
+.It Fl I
+Initialise the state directory
+.Pa @VARDIR@ .
+This only needs to be called if the initial system boot sequence does not
+automatically clean it out; for example the state directory is moved
+somewhere other than
+.Pa /var/run .
+If used, it should only be called once as early in the system boot sequence
+as possible and before
+.Nm
+is used to add interfaces.
+.It Fl R
+Echo the command used to restart a service.
+.It Fl r Ar service
+If the
+.Ar service
+is running then restart it.
+If the service does not exist or is not running then zero is returned,
+otherwise the result of restarting the service.
 .It Fl v
 Echo variables DOMAINS, SEARCH and NAMESERVERS so that the subscriber can
 configure the resolver easily.
index 829321e16e8fc26a6fc5c7db1fc33fd0deadb426..1e1e1761ee5c245f7e47c2a0f85f00f8f54a404a 100644 (file)
@@ -28,6 +28,8 @@ RESOLVCONF="$0"
 SYSCONFDIR=@SYSCONFDIR@
 LIBEXECDIR=@LIBEXECDIR@
 VARDIR=@VARDIR@
+RCDIR=@RCDIR@
+RESTARTCMD=@RESTARTCMD@
 
 # Disregard dhcpcd setting
 unset interface_order state_dir
@@ -71,28 +73,39 @@ error_exit()
 usage()
 {
        cat <<-EOF
-       Usage: ${RESOLVCONF##*/} [options]
+       Usage: ${RESOLVCONF##*/} [options] command [argument]
 
        Inform the system about any DNS updates.
 
-       Options:
+       Commands:
          -a \$INTERFACE    Add DNS information to the specified interface
                           (DNS supplied via stdin in resolv.conf format)
-         -m metric        Give the added DNS information a metric
-         -p               Mark the interface as private
-         -x               Mark the interface as exclusive
          -d \$INTERFACE    Delete DNS information from the specified interface
-         -f               Ignore non existant interfaces
-         -I               Init the state dir
-         -u               Run updates from our current DNS information
-         -l [\$PATTERN]    Show DNS information, optionally from interfaces
-                          that match the specified pattern
+         -h               Show this help cruft
          -i [\$PATTERN]    Show interfaces that have supplied DNS information
                    optionally from interfaces that match the specified
                    pattern
+         -l [\$PATTERN]    Show DNS information, optionally from interfaces
+                          that match the specified pattern
+
+         -u               Run updates from our current DNS information
+
+       Options:
+         -f               Ignore non existant interfaces
+         -m metric        Give the added DNS information a metric
+         -p               Mark the interface as private
+         -x               Mark the interface as exclusive
+
+       Subscriber and System Init Commands:
+         -I               Init the state dir
+         -r \$SERVICE      Restart the system service
+                          (restarting a non-existent or non-running service
+                           should have no output and return 0)
+         -R               Show the system service restart command
          -v [\$PATTERN]    echo NEWDOMAIN, NEWSEARCH and NEWNS variables to
                           the console
-         -h               Show this help cruft
+         -V [\$PATTERN]    Same as -v, but only uses configuration in
+                          $SYSCONFDIR/resolvconf.conf
        EOF
        [ -z "$1" ] && exit 0
        echo
@@ -260,6 +273,77 @@ config_mkdirs()
        return $e
 }
 
+# With the advent of alternative init systems, it's possible to have
+# more than one installed. So we need to try and guess what one we're
+# using unless overriden by configure.
+detect_init()
+{
+       [ -n "$RESTARTCMD" ] && return 0
+
+       # Detect the running init system.
+       # As systemd and OpenRC can be installed on top of legacy init
+       # systems we try to detect them first.
+       _service_status=
+       if [ -x /bin/systemctl -a -S /run/systemd/private ]; then
+               RESTARTCMD="if /bin/systemctl --quiet is-active; then
+       /bin/systemctl restart \$1.service;
+fi"
+       elif [ -x /usr/bin/systemctl -a -S /run/systemd/private ]; then
+               RESTARTCMD="if /usr/bin/systemctl --quiet is-active; then
+       /usr/bin/systemctl restart \$1.service;
+fi"
+       elif [ -x /sbin/rc-service -a \
+           -s /libexec/rc/init.d/softlevel -o -s /run/openrc/softlevel ]
+       then
+               RESTARTCMD="/sbin/rc-service -i \$1 -- -Ds restart"
+       elif [ -x /usr/sbin/invoke-rc.d ]; then
+               RCDIR=/etc/init.d
+               RESTARTCMD="if /usr/sbin/invoke-rc.d --quiet \$1 status 1>/dev/null 2>&1; then
+       /usr/sbin/invoke-rc.d \$1 restart;
+fi"
+       elif [ -x /sbin/service ]; then
+               RCDIR=/etc/init.d
+               RESTARTCMD="if /sbin/service \$1; then
+/sbin/service \$1 restart;
+fi"
+       elif [ -x /bin/sv ]; then
+               RESTARTCMD="/bin/sv try-restart \$1"
+       elif [ -x /usr/bin/sv ]; then
+               RESTARTCMD="/usr/bin/sv try-restart \$1"
+       elif [ -e /etc/arch-release -a -d /etc/rc.d ]; then
+               RCDIR=/etc/rc.d
+               RESTARTCMD="if [ -e /var/run/daemons/\$1 ]; then
+       /etc/rc.d/\$1 restart;
+fi"
+       elif [ -e /etc/slackware-version -a -d /etc/rc.d ]; then
+               RESTARTCMD="if /etc/rc.d/rc.\$1 status 1>/dev/null 2>&1; then
+       /etc/rc.d/rc.\$1 restart;
+fi"
+       elif [ -e /etc/rc.d/rc.subr -a -d /etc/rc.d ]; then
+               RESTARTCMD="if /etc/rc.d/rc.\$1 check 1>/dev/null 2>&1; then
+       /etc/rc.d/rc.\$1 restart;
+fi"
+       else
+               for x in /etc/init.d/rc.d /etc/rc.d /etc/init.d; do
+                       [ -d $x ] || continue
+                       RESTARTCMD="if $x/\$1 status 1>/dev/null 2>&1; then
+       $x/\$1 restart;
+fi"
+                       break
+               done
+       fi
+
+       if [ -z "$RESTARTCMD" ]; then
+               if [ "$NOINIT_WARNED" != true ]; then
+                       warn "could not detect a useable init system"
+                       _NOINIT_WARNED=true
+               fi
+               return 1
+       fi
+       _NOINIT_WARNED=
+       return 0
+}
+
 list_resolv()
 {
        [ -d "$IFACEDIR" ] || return 0
@@ -498,7 +582,7 @@ make_vars()
 
 force=false
 VFLAG=
-while getopts a:Dd:fhIilm:puvVx OPT; do
+while getopts a:Dd:fhIilm:pRruvVx OPT; do
        case "$OPT" in
        f) force=true;;
        h) usage;;
@@ -540,6 +624,18 @@ if [ "$cmd" = l -o "$cmd" = i ]; then
        exit $?
 fi
 
+# Restart a service or echo the command to restart a service
+if [ "$cmd" = r -o "$cmd" = R ]; then
+       detect_init || exit 1
+       if [ "$cmd" = r ]; then
+               set -- $args
+               eval $RESTARTCMD
+       else
+               echo "$RESTARTCMD"
+       fi
+       exit $?
+fi
+
 # Not normally needed, but subscribers should be able to run independently
 if [ "$cmd" = v -o -n "$VFLAG" ]; then
        make_vars "$iface"
@@ -764,6 +860,10 @@ case "${resolvconf:-YES}" in
 *) exit 0;;
 esac
 
+# Try and detect a suitable init system for our scripts
+detect_init
+export RESTARTCMD RCDIR _NOINIT_WARNED
+
 eval "$(make_vars)"
 export RESOLVCONF DOMAINS SEARCH NAMESERVERS LOCALNAMESERVERS
 : ${list_resolv:=list_resolv -l}
index a803615783fc9627036c1b05fc2a331faf66dd7e..a9e978ae139651f1693f39f5520bee224e78b924 100644 (file)
@@ -37,7 +37,6 @@ NL="
 
 : ${unbound_pid:=/var/run/unbound.pid}
 : ${unbound_service:=unbound}
-: ${unbound_restart:=@RESTARTCMD ${unbound_service}@}
 newconf="# Generated by resolvconf$NL"
 
 for d in $DOMAINS; do
@@ -71,6 +70,18 @@ else
        @SBINDIR@/resolvconf -D "$unbound_conf"
 fi
 
+restart_unbound()
+{
+       if [ -n "$unbound_restart" ]; then
+               eval $unbound_restart
+       elif [ -n "$RESTARTCMD" ]; then
+               set -- ${unbound_service}
+               eval $RESTARTCMD
+       else
+               @SBINDIR@/resolvconf -r ${unbound_service}
+       fi
+}
+
 if [ ! -f "$unbound_conf" ] || \
        [ "$(cat "$unbound_conf")" != "$(printf %s "$newconf")" ]
 then
@@ -78,9 +89,9 @@ then
        # If we can't sent a HUP then force a restart
        if [ -s "$unbound_pid" ]; then
                if ! kill -HUP $(cat "$unbound_pid") 2>/dev/null; then
-                       eval $unbound_restart
+                       restart_unbound
                fi
        else
-               eval $unbound_restart
+               restart_unbound
        fi
 fi