[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-API] [PATCH 21 of 33] interface-reconfigure: explicitly rename devices early



to match the XenAPI datamodel MAC->device mapping rather than relying
on ifup/ifdown to do it.

In particular ifdown does not do renaming and if ifup hasn't already
done it (i.e. at start of day when we are just ensuring the device is
down) then it can get into an infinite loop:

- ifdown ethX
   -> oh, that device is actually called ethY
       -> ifdown ethY
           -> oh, that device is actually called ethX
               -> ifdown ethX
                   -> etc

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

diff -r 4992b8f5eff0 -r d51959c290a2 scripts/interface-reconfigure
--- a/scripts/interface-reconfigure     Fri Dec 18 14:16:32 2009 +0000
+++ b/scripts/interface-reconfigure     Fri Dec 18 14:16:32 2009 +0000
@@ -47,6 +47,7 @@
 import traceback
 import time
 import re
+import random
 from xml.dom.minidom import getDOMImplementation
 from xml.dom.minidom import parse as parseXML
 
@@ -666,6 +667,78 @@
 
     run_command(["/sbin/ifup", netdev])
 
+def netdev_remap_name(pif, already_renamed=[]):
+    """Check whether 'pif' exists and has the correct MAC.
+    If not, try to find a device with the correct MAC and rename it.
+    'already_renamed' is used to avoid infinite recursion.
+    """
+
+    def read1(name):
+        file = None
+        try:
+            file = open(name, 'r')
+            return file.readline().rstrip('\n')
+        finally:
+            if file != None:
+                file.close()
+
+    def get_netdev_mac(device):
+        try:
+            return read1("/sys/class/net/%s/address" % device)
+        except:
+            # Probably no such device.
+            return None
+
+    def get_netdev_tx_queue_len(device):
+        try:
+            return int(read1("/sys/class/net/%s/tx_queue_len" % device))
+        except:
+            # Probably no such device.
+            return None
+
+    def get_netdev_by_mac(mac):
+        for device in os.listdir("/sys/class/net"):
+            dev_mac = get_netdev_mac(device)
+            if (dev_mac and mac.lower() == dev_mac.lower() and
+                get_netdev_tx_queue_len(device)):
+                return device
+        return None
+
+    def rename_netdev(old_name, new_name):
+        log("Changing the name of %s to %s" % (old_name, new_name))
+        run_command(['/sbin/ifconfig', old_name, 'down'])
+        if not run_command(['/sbin/ip', 'link', 'set', old_name, 'name', 
new_name]):
+            raise Error("Could not rename %s to %s" % (old_name, new_name))
+
+    pifrec = db.get_pif_record(pif)
+    device = pifrec['device']
+    mac = pifrec['MAC']
+
+    # Is there a network device named 'device' at all?
+    device_exists = netdev_exists(device)
+    if device_exists:
+        # Yes.  Does it have MAC 'mac'?
+        found_mac = get_netdev_mac(device)
+        if found_mac and mac.lower() == found_mac.lower():
+            # Yes, everything checks out the way we want.  Nothing to do.
+            return
+    else:
+        log("No network device %s" % device)
+
+    # What device has MAC 'mac'?
+    cur_device = get_netdev_by_mac(mac)
+    if not cur_device:
+        log("No network device has MAC %s" % mac)
+        return
+
+    # First rename 'device', if it exists, to get it out of the way
+    # for 'cur_device' to replace it.
+    if device_exists:
+        rename_netdev(device, "dev%d" % random.getrandbits(24))
+
+    # Rename 'cur_device' to 'device'.
+    rename_netdev(cur_device, device)
+
 #
 # IP Network Devices -- network devices with IP configuration
 #
@@ -1078,6 +1151,19 @@
     f.close()
 
     return f
+
+def pif_rename_physical_devices(pif):
+
+    if pif_is_vlan(pif):
+        pif = pif_get_vlan_slave(pif)
+
+    if pif_is_bond(pif):
+        pifs = pif_get_bond_slaves(pif)
+    else:
+        pifs = [pif]
+
+    for pif in pifs:
+        netdev_remap_name(pif)
 
 def bring_down_interface(pif, destroy=False):
     """Bring down the interface associated with PIF.
@@ -1420,6 +1506,8 @@
 
     f.close()
     
+    pif_rename_physical_devices(pif)
+
     # if there is a bridge using this pif then bring it down
     ifdown(ipdev)
 

_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.