Using ifplugd to resolve NAS booting problems

Updated March 2013 to include configuration files for `ifplugd`.

A year or two ago, I built a small Linux server for use as a NAS (network attached storage) and router. It evolved through a number of iterations, but in its latest configuration is running a fairly vanilla Arch Linux. There was one problem that kept bugging me when I moved it to a new residence/network, though--it always refused to finish the booting process the first time that I plugged it in. Because I have it set up as a NAT router, with two ethernet ports, I would try to debug the situation by plugging my laptop into the "LAN" side port. When I did that, the machine would have no problems at all booting up. The problem was exacerbated because I ran the server headless, and it would not finish bringing up the WAN side interface before it froze, so I couldn't even open an SSH session to see what was going on.

I eventually traced the problem to a quirk of the Arch Linux boot scripts. I am using net-profiles, so I have internal and external profiles in /etc/network.d. internal was set to a static IP address, and netcfg wouldn't allow the boot to continue if no cable was plugged into the port for internal. This explains both the booting problem and the symptom that it would magically work after I plugged in my laptop.

By searching the Arch forums, I found ifplugd, which automatically brings up/takes down network interfaces depending on the media presence. It's useful for laptops which have the ethernet cable frequently connected or disconnected, but it has also come in handy in my situation. Instead of letting Arch start my network interfaces automatically, I set them to use ifplugd instead. If the media are connected at boot, ifplugd will bring up the respective interfaces, but if (for example) the internal interface is not connected to anything, ifplugd won't bring it up (until it is connected). This neatly solves my problem, and ifplugd is already available in Arch repository extra. I used this this configuration, which also starts/stops dnsmasq, a DNS/DHCP server, with the internal interface:

# /etc/ifplugd/ifplugd.conf
INTERFACES="eth0 eth1"
# Run this script when a cable is plugged/unplugged
ARGS="--run=/etc/ifplugd/net_dnsmasq.action"

Here's the action file:

# /etc/ifplugd/net_dnsmasq.action

#!/bin/bash
# $1=[eth0|eth1], $2=[start|stop]
/etc/ifplugd/netcfg.action $1 $2
NETCFG_RETURN=$?

# Start/stop dnsmasq if eth1
if [[ "$1" == "eth1" ]]; then
    case "$2" in
        up)
        systemctl start dnsmasq
        ;;
        down)
        systemctl stop dnsmasq
        ;;
    esac
fi

exit $NETCFG_RETURN

netcfg.action is included with the Arch package for ifplugd (it determines the appropriate network profile for an interface and starts/stops it accordingly). The script I wrote, net_dnsmasq.action, is just a simple wrapper for the included netcfg.action which starts/stops dnsmasq as appropriate.

Comments

comments powered by Disqus