xenserver: Bring up bond slave device before adding to bond.
authorBen Pfaff <blp@nicira.com>
Fri, 5 Jun 2009 21:08:36 +0000 (14:08 -0700)
committerBen Pfaff <blp@nicira.com>
Fri, 5 Jun 2009 21:08:36 +0000 (14:08 -0700)
Until now, we've added network devices to the ovs-vswitchd configuration
file before bringing them up.  This works suboptimally for bond slaves,
because vswitchd takes the initial carrier state of the bond slaves as
whether to initially enable or disable them, and a device that is down
always reports "no carrier".  So this commit changes interface-reconfigure
to bring up bond slaves before adding them to the configuration file,
which gives them a chance to detect carrier before vswitchd checks for it.

This might still be an imperfect situation, because it takes quite a while
(maybe 1 second?) for some network devices to detect carrier after being
brought up.  But the kernel implementation of bonding seems to do the very
same thing, so we should be at least no worse than it.

Incidentally, this is only important for bonds that have long updelays.
XenServer uses an updelay of 31 seconds (!), so it is especially important
there.

Bug #1247.

xenserver/opt_xensource_libexec_interface-reconfigure

index 29d79added53d0f4cc1c1fb2e72d14d72523e4f3..74f06f8c52d3b1e74f3f4bce2508690ca348a81a 100755 (executable)
@@ -786,6 +786,10 @@ def action_up(pif):
         bond_master = pif
     else:
         bond_master = None
+    if bond_master:
+        bond_slaves = get_bond_slaves_of_pif(bond_master)
+    else:
+        bond_slaves = []
     bond_masters = get_bond_masters_of_pif(pif)
 
     # Support "rpm -e vswitch" gracefully by keeping Centos configuration
@@ -872,6 +876,16 @@ def action_up(pif):
         net = db.get_pif_record(nwpif)['network']
         network_uuids += [db.get_network_record(net)['uuid']]
 
+    # Bring up bond slaves early, because ovs-vswitchd initially
+    # enables or disables bond slaves based on whether carrier is
+    # detected when they are added, and a network device that is down
+    # always reports "no carrier".
+    bond_slave_physdevs = []
+    for slave in bond_slaves:
+        bond_slave_physdevs += physdev_names(slave)
+    for slave_physdev in bond_slave_physdevs:
+        up_netdev(slave_physdev)
+
     # Now modify the ovs-vswitchd config file.
     argv = []
     for port in set(del_ports):
@@ -906,10 +920,11 @@ def action_up(pif):
     # Configure network devices.
     configure_netdev(pif)
 
-    # Bring up VLAN slave and bond slaves.
+    # Bring up VLAN slave, plus physical devices other than bond
+    # slaves (which we brought up earlier).
     if vlan_slave:
         up_netdev(ipdev_name(vlan_slave))
-    for physdev in physdevs:
+    for physdev in set(physdevs) - set(bond_slave_physdevs):
         up_netdev(physdev)
 
     # Update /etc/issue (which contains the IP address of the management interface)