Package: ifplugd
Version: 0.28-15
Severity: normal

Ifplugd can restart interfaces on suspend/resume, but only static interfaces
that are managed by /etc/init.d/ifplugd.

The same is needed for hotplug interfaces, for which ifplugd is started by
udev. Otherwise the network might not work after resume because no
DHCP lease is requested, etc.

Attached is a script for pm-utils and apmd, that implements restarting
for hotplug interfaces. It should be put in /etc/pm/sleep.d and 
/etc/apm/scripts.d and replace the current script. 

This script extends the one attached to #527583. 


-- Package-specific info:
 /sys/class/net/ interfaces:
/sys/class/net/eth0/
/sys/class/net/lo/

-- System Information:
Debian Release: squeeze/sid
  APT prefers testing
  APT policy: (990, 'testing'), (500, 'unstable'), (500, 'stable'), (1, 
'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.31.4-amd64 (SMP w/2 CPU cores)
Locale: LANG=POSIX, LC_CTYPE=de_AT.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages ifplugd depends on:
ii  debconf [debconf-2.0]         1.5.27     Debian configuration management sy
ii  libc6                         2.9-25     GNU C Library: Shared libraries
ii  libdaemon0                    0.13-3     lightweight C library for daemons 
ii  lsb-base                      3.2-23     Linux Standard Base 3.2 init scrip

Versions of packages ifplugd recommends:
ii  ifupdown                      0.6.9      high level tools to configure netw

Versions of packages ifplugd suggests:
pn  wpasupplicant                 <none>     (no description available)

-- debconf information:
  ifplugd/interfaces:
  ifplugd/hotplug_interfaces:
  ifplugd/args: -q -f -u0 -d10 -w -I
  ifplugd/suspend_action: stop
#!/bin/sh
#
# suspend/resume ifplugd

[ -f /etc/default/ifplugd ] || exit 0
. /etc/default/ifplugd
[ "$SUSPEND_ACTION" ] || [ "$SUSPEND_ACTION" != "none" ] || exit 0

if [ "$SUSPEND_ACTION" = "suspend" ] ; then
  RESUME_ACTION="resume"
elif [ "$SUSPEND_ACTION" = "stop" ] ; then
  RESUME_ACTION="start"
else
  exit 0
fi

# Hotplug interfaces
#
# ifplugd for interfaces in HOTPLUG_INTERFACES is started by udev.
# The ifplugd init.d script doesn't touch them. We still want to 
# stop/start these interfaces on suspend/resume. Here is some
# hackery to do this.

# use pm-utils functions for state save/restore, if available
[ -f "${PM_FUNCTIONS}" ] && . "${PM_FUNCTIONS}"

# name of the save/restore state
IFPLUGD_STATE="ifplugd_ifs"

# return 0 if the first parm is an element of the remaining parms
# or they contain the special value "all"
elem_of() {
    local E=$1
    shift
    echo $@ | grep -Eq "(\\<all\\>)|(\\<${E}\\>)" 
}

# save state using pm-utils
save_state() {
    savestate ${IFPLUGD_STATE} 2>/dev/null
}

# load saved state using pm-utils
load_state() {
    restorestate ${IFPLUGD_STATE} 2>/dev/null
}

# filter only hotplug interfaces
filter_hotplug_ifs() {
    while read L; do
        for IF in $L; do
            # interface is managed statically
            elem_of "${IF}" "${INTERFACES}" && continue
            # interface is not managed by udev
            elem_of "${IF}" "${HOTPLUG_INTERFACES}" || continue
            # ignore lo
            [ "x${IF}" = "xlo" ] && continue
            echo -n "${IF} "
        done 
    done
    echo ""
}

# get interfaces of running ifplugds for hotplug IFs
get_running_ifs() {
    ps --no-headers -o args -C ifplugd | \
    sed -e 's/.*-[[:alpha:]]*i[[:space:]]*\([^[:space:]]\+\).*/\1/' | \
    filter_hotplug_ifs
}

# get all existing hotplug IFs
get_hotplug_ifs() {
    local IFACES=""
    for IF in /sys/class/net/*; do
        echo "${IF##*/} "
    done | filter_hotplug_ifs
}

# stop all ifplugd instances that where started by udev
# stop_udev_ifs <action>
stop_udev_ifs() {
    local ACTION=$1
    local IFACES
    local IF

    IFACES=`get_running_ifs`

    # save list of interfaces we stop, so we can restart them
    echo "${IFACES}" | save_state || true

    for IF in ${IFACES}; do
        if [ "x${ACTION}" = "xsuspend" ]; then
            ifplugd -i ${IF} -S
        else
            ifplugd -i ${IF} -k
        fi
        # ifplugd started by udev doesn't take down the IF
        /etc/ifplugd/ifplugd.action ${IF} down
    done
}

# start ifplugd for all interfaces that were stopped by us
# start_udev_ifs <action>
start_udev_ifs() {
    local ACTION=$1
    local IFACES
    local IF

    # try to load list of interfaces
    # if it can't be loaded, we just start all hotplug interfaces
    IFACES=`load_state || get_hotplug_ifs`

    for IF in ${IFACES}; do
        if [ "x${ACTION}" = "xresume" ] && ifplugd -i ${IF} -c; then
            ifplugd -i ${IF} -R
        else
            # start ifplugd just as udev would
            INTERFACE=${IF} ACTION=add /lib/udev/ifplugd.agent
        fi
    done
}


case "$1" in
        hibernate|suspend|suspend_hybrid)
                /etc/init.d/ifplugd ${SUSPEND_ACTION}
                stop_udev_ifs ${SUSPEND_ACTION}
                ;;
        thaw|resume)
                if [ "x$2" != "xstandby" ]; then
                    start_udev_ifs ${RESUME_ACTION}
                    /etc/init.d/ifplugd ${RESUME_ACTION}
                fi
                ;;
        *) exit 1
                ;;
esac

exit 0

Reply via email to