Commit 3c3918cb authored by Leigh B Stoller's avatar Leigh B Stoller

Change to run DHCP on a specific set of interfaces. When XENVIFROUTING

is off, this is just the control net interface (xenbr0). But when
XENVIFROUTING is on, we want to listen on the control net bridge plus
all of the container vifs. Since these are not created until the
container is started, we have to call restartDHCP from emulab-cnet (we
were already doing that), and now we also call reconfigDHCP() when the
contain is destroyed so that interface list is correct (note that DHCPD
does not seem to care if an interface dissappears, or even if an
interface does not exist when starting.

The main point here, is that on shared nodes we have to restrict the
number of interfaces that DHCPd listens on (or even looks at) since it
can be 100s, and dhcpd was taking well over a minute to start up each

Aside; minor change to not look at the IP config for bridges, just the
mac. Takes to long when there are 100s of bridges.
parent d045249f
......@@ -33,10 +33,11 @@ use Exporter;
downloadImage getKernelVersion createExtraFS
forwardPort removePortForward lvSize lvExists
DoIPtables DoIPtablesNoFail
restartDHCP computeStripeSize
restartDHCP reconfigDHCP computeStripeSize
use Data::Dumper;
BEGIN { require "/etc/emulab/"; import emulabpaths; }
use libutil;
use libgenvnode;
use libsetup;
......@@ -48,6 +49,7 @@ use libtestbed;
my $PCNET_IP_FILE = "/var/emulab/boot/myip";
my $PCNET_MASK_FILE = "/var/emulab/boot/mynetmask";
my $PCNET_GW_FILE = "/var/emulab/boot/routerip";
my $VIFROUTING = ((-e "$ETCDIR/xenvifrouting") ? 1 : 0);
# Other local constants
my $IPTABLES = "/sbin/iptables";
......@@ -565,6 +567,13 @@ sub getIfaceInfoNoCache($) {
$mac = lc($mac);
$ret = { 'mac' => $mac, 'iface' => $iface };
# We do not care about any of the stuff below for our bridges, and
# on a shared node this was taking 60 seconds every time we called
# makeIfaceMaps(), which we do a lot, plus we now call it from
# emulab-cnet when containers are booting or shutting down.
return $ret
if ($iface =~ /^br\d+$/);
# Find IP info
my $pip = `ip addr show dev $iface | grep 'inet '`;
......@@ -920,6 +929,52 @@ sub lvSize($)
return $lv_size;
# Reset the list of interfaces that DHCPD should listen on.
sub reconfigDHCP()
my @vifs = "";
my $defaults = '/etc/default/isc-dhcp-server';
# We want to set the list of vifs that dhcpd listens on, since if
# there are too many VMs coming and going, it can take a long time
# for dhcpd to process all the virtual interfaces that exist
# (like ifbs, veths, bridges, etc) that it does not care about
# cause they are down or otherwise. So figure out the vif list
# and write that into the /etc/defaults.
my $devdir = '/sys/class/net';
if (!opendir(SD,$devdir)) {
print STDERR "Could not find $devdir!\n";
return -1;
@vifs = grep { /^vif.*/ && -f "$devdir/$_/address" } readdir(SD);
# Also need the control network bridge.
my ($cnet_iface) = findControlNet();
my @ifaces = "$cnet_iface @vifs";
if (! -e $defaults) {
mysystem2("echo 'INTERFACES=\"@ifaces\"' > $defaults");
else {
mysystem2("/bin/sed -i.bak -e ".
" 's,^INTERFACES=.*\$,INTERFACES=\"@ifaces\",i' $defaults");
return -1
if ($?);
return 0;
sub restartDHCP()
my $dhcpd_service = 'dhcpd';
......@@ -927,6 +982,9 @@ sub restartDHCP()
-f '/lib/systemd/system/isc-dhcp-server.service') {
$dhcpd_service = 'isc-dhcp-server';
if (reconfigDHCP()) {
# make sure dhcpd is running
if (-x '/sbin/initctl') {
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment