tags 325614 patch
thanks
Followup-For: Bug #325614
Package: ifplugd
Version: 0.28-11
-- Package-specific info:
/proc/net/dev interfaces:
lo
eth0
eth1
-- System Information:
Debian Release: lenny/sid
APT prefers unstable
APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.6.25-7.slh.1-sidux-686 (SMP w/1 CPU core; PREEMPT)
Locale: LANG=en_AU.UTF-8, LC_CTYPE=en_AU.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Versions of packages ifplugd depends on:
ii debconf [debconf-2.0] 1.5.22 Debian configuration management sy
ii libc6 2.7-12 GNU C Library: Shared libraries
ii libdaemon0 0.12-2 lightweight C library for daemons
Versions of packages ifplugd recommends:
ii ifupdown 0.6.8+nmu1 high level tools to configure netw
-- debconf information:
* ifplugd/interfaces:
* ifplugd/hotplug_interfaces: eth0
* ifplugd/args: -q -f -u0 -d10 -I
* ifplugd/suspend_action: stop
Robustify the udev hotplugging agent script for ifplugd.
Using the HOTPLUG_INTERFACES variable of /etc/default/ifplugd, I was not able
to reliably boot up with networking started as is if would if device was
present at boot time and listed in the INTERFACES variable (thus ifplugd
started by initscript). So I began to look at how the hotplug mechanism works.
A udev rule has been installed to invoke ifplugd.agent udev helper for
network subsystem interface add/remove events. These events can occur very
early in the boot process if the device is present at boot time, far earlier
than when networking infrastructure is prepared for connections. ifplugd.agent
in its current state doesn't seem to have a mechanism to delay the launch of
ifplugd daemon until such a time when network connections can be established.
Nor does the ifupdown action script (/etc/ifplugd/action.d/ifupdown, #245651).
ifplugd's udev agent script is very similar to that of ifupdown's net.agent
script. ifplugd.agent can use the wait_for_interface() function from net.agent
to delay the launch of ifplugd daemon until the loopback interface has been
prepared, as this propoerty indicates that the system networking infrastructure
is ready to function.
This patch implements the delay of ifplugd daemon start by moving existing code
into a shell function that may be backgrounded when executed by udev rule. This
function uses "wait_for_interface lo" to sleep until networking is appropriate,
before finally exec'ing the ifplugd daemon.
Closes: #325614
Related to: #245651
This patch also (naughtily) cleans up/changes some of the existing shell code:
- use consistent code flow, if []; then .. fi and not [] || { ;}
- IFPLUGD variable was a duplicate of DAEMON variable
- logically order the sanity testing for existance of binary and config files
at head of script
- refactor search_interfaces() function to take interface name as first
argument followed by list of candidate interfaces. Do explicit test for
special interface keyword "all". Makes function easier to understand.
- remove export of DEBUG=yes, this should probably not be default
- no point using the --wait-on-kill when backgrounding command that kills
a potentially running ifplugd daemon
When this mode of starting ifplugd is working well, I consider it to be far
better than the initscript method. It allows ifplugd to be useful as early as
possible in boot sequence.
Thanks, Kel.
---
--- a/debian/ifplugd.udev.agent
+++ b/debian/ifplugd.udev.agent
@@ -1,59 +1,90 @@
#!/bin/sh
# udev agent script
-DAEMON_NAME=ifplugd
-
-DAEMON=/usr/sbin/$DAEMON_NAME
-CFG=/etc/default/$DAEMON_NAME
-
-[ -x $DAEMON ] || exit 0
-
HOTPLUGFUNCS=/lib/udev/hotplug.functions
-
[ -f $HOTPLUGFUNCS ] || exit 1
. $HOTPLUGFUNCS
-DEBUG=yes export DEBUG
-[ "$INTERFACE" ] || { mesg Bad invocation: \$INTERFACE is not set ; exit 1 ; }
+if [ -z "$INTERFACE" ]; then
+ mesg Bad invocation: \$INTERFACE is not set
+ exit 1
+fi
-[ -f $CFG ] || { mesg No $DAEMON_NAME configuration file ; exit 1 ; }
-. $CFG
+DAEMON_NAME=ifplugd
+DAEMON=/usr/sbin/$DAEMON_NAME
+if [ ! -x $DAEMON ]; then
+ mesg No $DAEMON_NAME executable: $DAEMON
+ exit 1
+fi
-# return true (0) if interface from list $1 is in list $2
+CFG=/etc/default/$DAEMON_NAME
+if [ -f $CFG ]; then
+ . $CFG
+else
+ mesg No $DAEMON_NAME configuration file
+ exit 1
+fi
+
+# return true (0) if interface ($1) is in argument list ($@)
# return false (1) otherwise
search_interfaces () {
- for IF in $2 ; do
- for SEARCH_IF in $1 ; do
- if [ "$SEARCH_IF" = "$IF" ] ; then
- return 0
- fi
- done
+ local interface=$1
+ shift
+
+ for i in $@; do
+ if [ "$i" = "$interface" ] || [ "$i" = "all" ]; then
+ return 0
+ fi
done
+
return 1
}
-IFPLUGD=/usr/sbin/ifplugd
-test -x $IFPLUGD || exit 0
+# wait for networking to be available, taken from net.agent (ifupdown)
+wait_for_interface () {
+ local interface=$1
+
+ while :; do
+ local state="$(cat /sys/class/net/${interface}/operstate 2>/dev/null ||
true)"
+ if [ "$state" != down ]; then
+ return 0
+ fi
+ sleep 1
+ done
+}
-search_interfaces "$INTERFACE" "$INTERFACES"
-if [ $? -gt 0 ] ; then
- # Interface isn't statically managed by ifplugd
- search_interfaces "all $INTERFACE" "$HOTPLUG_INTERFACES"
- if [ $? -eq 0 ] ; then
- # Interface is in hotplug allowed list
- case $ACTION in
- add|register)
- debug_mesg Invoking $DAEMON_NAME for $INTERFACE
- IF1=$(echo $INTERFACE | sed "s/-/_/")
- A=$(eval echo \$\{ARGS_${IF1}\})
- [ -z "$A" ] && A="$ARGS"
- exec $IFPLUGD -i $INTERFACE $A &
- ;;
- remove|unregister)
- debug_mesg Stopping $DAEMON_NAME for $INTERFACE
- exec $IFPLUGD -k --wait-on-kill -i $INTERFACE &
- ;;
- esac
- break
+ifplugd_daemon () {
+ search_interfaces "$INTERFACE" $INTERFACES
+ if [ $? -gt 0 ]; then
+ # Interface isn't statically managed by ifplugd
+ search_interfaces "$INTERFACE" $HOTPLUG_INTERFACES
+ if [ $? -eq 0 ]; then
+ # Interface is in hotplug allowed list
+ case "$ACTION" in
+ add|register)
+ debug_mesg Invoking $DAEMON_NAME for $INTERFACE
+
+ # check for interface specific arguments
+ IF1=$(echo $INTERFACE | sed "s/-/_/")
+ A=$(eval echo \$\{ARGS_${IF1}\})
+ [ -z "$A" ] && A="$ARGS"
+
+ # wait for loopback interface to exist, we may have
+ # been invoked very early in boot sequence
+ wait_for_interface lo
+
+ # spawn ifplugd daemon
+ exec $DAEMON -i $INTERFACE $A
+ ;;
+ remove|unregister)
+ debug_mesg Stopping $DAEMON_NAME for $INTERFACE
+
+ # kill a running ifplugd daemon
+ exec $DAEMON -k -i $INTERFACE
+ ;;
+ esac
+ fi
fi
-fi
+}
+
+ifplugd_daemon &
---
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]