Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/udev hotplug #264

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions debian/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,27 @@ IgnoreOnIsolate=yes
[Service]
# avoid stopping on shutdown via stopping system-ifup.slice
Slice=system.slice
ExecStart=/sbin/ifup --allow=hotplug %I
ExecStop=/sbin/ifdown %I
Environment=HOTPLUG_ARGS=
Environment=LOCKFILE=/run/network/.lock
EnvironmentFile=-/etc/default/networking
ExecStart=/bin/sh -ec "( \
/bin/test \"$VERBOSE\" = \"yes\" && EXTRA_ARGS=-v; \
/bin/test \"$DEBUG\" = \"yes\" && EXTRA_ARGS=\"$EXTRA_ARGS -d\"; \
flock 9; \
if $(/sbin/ifquery -L 9 -l --allow=hotplug 2>/dev/null | grep -w -q \"^%I$\"); then \
exec /sbin/ifup $EXTRA_ARGS $HOTPLUG_ARGS %I -L 9 --systemd; \
fi; \
exit 1; \
) 9>$LOCKFILE"
ExecStop=/bin/sh -ec "( \
/bin/test \"$VERBOSE\" = \"yes\" && EXTRA_ARGS=-v; \
/bin/test \"$DEBUG\" = \"yes\" && EXTRA_ARGS=\"$EXTRA_ARGS -d\"; \
flock 9; \
exec /sbin/ifdown $EXTRA_ARGS %I -L 9 --systemd; \
) 9>$LOCKFILE"
RemainAfterExit=true
TimeoutStartSec=2min

# remove log duplications
StandardOutput=null
StandardError=null
161 changes: 161 additions & 0 deletions debian/ifupdown2-hotplug
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#!/bin/sh -e
#
# run /sbin/{ifup,ifdown} with the --allow=hotplug option.
#

PATH='/sbin:/bin:/usr/sbin:/usr/bin'

if [ -x /usr/bin/logger ]; then
LOGGER=/usr/bin/logger
elif [ -x /bin/logger ]; then
LOGGER=/bin/logger
else
unset LOGGER
fi

LOCKFILE=/run/network/.lock

# for diagnostics
if [ -t 1 -a -z "$LOGGER" ] || [ ! -e '/dev/log' ]; then
mesg() {
echo "$@" >&2
}
elif [ -t 1 ]; then
mesg() {
echo "$@"
$LOGGER -t "${0##*/}[$$]" "$@"
}
else
mesg() {
$LOGGER -t "${0##*/}[$$]" "$@"
}
fi

if [ -z "$INTERFACE" ]; then
mesg "Bad ifupdown udev helper invocation: \$INTERFACE is not set"
exit 1
fi

wait_for_interface() {
local interface=$1
local state

while :; do
read state /sys/class/net/$interface/operstate 2>/dev/null || true
if [ "$state" != down ]; then
return 0
fi
sleep 1
done
}

process_exclusions() {
set -- $EXCLUDE_INTERFACES
exclusions=""
for d; do
exclusions="-X $d $exclusions"
done
echo $exclusions
}

net_ifup() {
. /etc/default/networking 2>/dev/null || true

exclusions=$(process_exclusions)

# exit if the interface is not configured as allow-hotplug or excluded (querying does not require a lock)
if ! $(/sbin/ifquery --allow=hotplug -l $exclusions 2>/dev/null | grep -w -q "^$INTERFACE$"); then
exit 0
fi

if [ -d /run/systemd/system ]; then
exec systemctl --no-block start $(systemd-escape --template [email protected] $INTERFACE)
fi

EXTRA_ARGS=
[ "$VERBOSE" = yes ] && EXTRA_ARGS=-v
[ "$DEBUG" = yes ] && EXTRA_ARGS="$EXTRA_ARGS -d"
[ "$SYSLOG" = yes ] && EXTRA_ARGS="$EXTRA_ARGS --syslog"

# Take the lock and wait for lo before exec ifup.
(
flock 9
wait_for_interface lo
exec ifup $EXTRA_ARGS $HOTPLUG_ARGS -L 9 $INTERFACE
) 9>$LOCKFILE
}

net_ifdown() {

# systemd will automatically ifdown the interface on device
# removal by binding the instanced service to the network device
if [ -d /run/systemd/system ]; then
exit 0
fi

. /etc/default/networking 2>/dev/null || true

exclusions=$(process_exclusions)

# exit if the interface is not configured as allow-hotplug or excluded (querying does not require a lock)
if ! $(/sbin/ifquery --allow=hotplug -l $exclusions 2>/dev/null | grep -w -q "^$INTERFACE$"); then
exit 0
fi

EXTRA_ARGS=
[ "$VERBOSE" = yes ] && EXTRA_ARGS=-v
[ "$DEBUG" = yes ] && EXTRA_ARGS="$EXTRA_ARGS -d"
[ "$SYSLOG" = yes ] && EXTRA_ARGS="$EXTRA_ARGS --syslog"

# Take the lock and exec ifdown.
(
flock 9
exec ifdown $EXTRA_ARGS $INTERFACE -L 9
) 9>$LOCKFILE
}

do_everything() {

case "$ACTION" in
add)
# these interfaces generate hotplug events *after* they are brought up
case $INTERFACE in
ppp*|ippp*|isdn*|plip*|lo|irda*|ipsec*)
exit 0 ;;
esac

net_ifup
;;

remove)
# the pppd persist option may have been used, so it should not be killed
case $INTERFACE in
ppp*)
exit 0 ;;
esac

net_ifdown
;;

*)
mesg "NET $ACTION event not supported"
exit 1
;;
esac

}

# under systemd we don't do synchronous operations, so we can run in the
# foreground; we also need to, as forked children get killed right away under
# systemd
if [ -d /run/systemd/system ]; then
do_everything
else
# under sysvinit we need to fork as we start the long-running
# "ifup". but there, forked processes won't get killed.
# When udev_log="debug" stdout and stderr are pipes connected to udevd.
# They need to be closed or udevd will wait for this process which will
# deadlock with udevsettle until the timeout.
exec > /dev/null 2> /dev/null
do_everything &
fi
1 change: 1 addition & 0 deletions debian/ifupdown2.install
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
etc/network/ifupdown2/addons.conf /etc/network/ifupdown2/
etc/network/ifupdown2/ifupdown2.conf /etc/network/ifupdown2/
debian/ifupdown2-hotplug lib/udev
5 changes: 5 additions & 0 deletions debian/ifupdown2.udev
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Allow rfkill for users in the netdev group
KERNEL=="rfkill", MODE="0664", GROUP="netdev"

# Handle allow-hotplug interfaces
SUBSYSTEM=="net", ACTION=="add|remove", RUN+="ifupdown2-hotplug"
2 changes: 2 additions & 0 deletions debian/rules
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ override_dh_install:
mkdir -p debian/ifupdown2/lib/systemd/system/
install --mode=644 debian/[email protected] debian/ifupdown2/lib/systemd/system/

override_dh_installudev:
dh_installudev --priority=80

override_dh_systemd_start:
dh_systemd_start --name=networking --no-start
Expand Down
10 changes: 9 additions & 1 deletion ifupdown2/ifupdown/argv.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#

import sys
import os
import argparse

try:
Expand Down Expand Up @@ -239,11 +240,18 @@ def update_ifreload_argparser(self, argparser):

def update_common_argparser(self, argparser):
''' general parsing rules '''
def file_or_fd(value):
try:
fp = os.fdopen(int(value))
except ValueError:
fp = os.open(value, os.O_CREAT | os.O_TRUNC | os.O_WRONLY)
return fp

argparser.add_argument('-V', '--version', action=VersionAction, nargs=0)
argparser.add_argument(
'-L', '--lock', default='/run/network/.lock', dest='lockfile',
help='use lock file instead of default /run/network/.lock'
help='use lock file instead of default /run/network/.lock (can be fd integer)',
type=file_or_fd
)
argparser.add_argument(
"--nldebug",
Expand Down
5 changes: 2 additions & 3 deletions ifupdown2/ifupdown/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,8 @@ def importName(cls, modulename, name):
@classmethod
def lockFile(cls, lockfile):
try:
fp = os.open(lockfile, os.O_CREAT | os.O_TRUNC | os.O_WRONLY)
fcntl.flock(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
fcntl.fcntl(fp, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
fcntl.flock(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
fcntl.fcntl(lockfile, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
except IOError:
return False
return True
Expand Down
20 changes: 0 additions & 20 deletions ifupdown2/sbin/start-networking
Original file line number Diff line number Diff line change
Expand Up @@ -78,25 +78,6 @@ check_network_swap() {
done < /proc/swaps
}

ifup_hotplug () {
if [ -d /sys/class/net ]
then
ifaces=$(for iface in $(ifquery --list --allow=hotplug 2>/dev/null)
do
link=${iface##:*}
link=${link##.*}
if [ -e "/sys/class/net/$link" ]
then
echo "$iface"
fi
done)
if [ -n "$ifaces" ]
then
ifup $ifaces "$@" --systemd || true
fi
fi
}

ifup_mgmt () {
ifaces=$(ifquery --list --allow=mgmt 2>/dev/null)
if [ -n "$ifaces" ]; then
Expand Down Expand Up @@ -128,7 +109,6 @@ start)
echo ${NAME}':' "Configuring network interfaces"
ifup_mgmt
ifup -a $EXTRA_ARGS $exclusions $perfoptions --systemd
ifup_hotplug $HOTPLUG_ARGS $EXTRA_ARGS $exclusions
;;
stop)
if [ "$SKIP_DOWN_AT_SYSRESET" = "yes" ]; then
Expand Down