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
external profiles in
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.