[et-mgmt-tools] [PATCH] Check the making domain's mac address

Tatsuro Enokura fj7716hz at aa.jp.fujitsu.com
Tue Mar 13 08:27:14 UTC 2007


Hi,

Would you give me a comment on this patch?
If not, please apply it.

Tatsuro Enokura wrote:
> The virt-install command can specify the making domain's vnif
> MAC address. The MAC address must be unique on the system,
> but the virt-install command doesn't check that
> the MAC address is unique among the running domains and host.
> 
> The attached patch resolve this issue in the following way:
> 
>   1) Get the running Domain's vnif MAC address.
>   2) Get the host's NIC MAC address.
>   3) Check the making domain's MAC address with 1) and 2) 's data.

Signed-off-by: Tatsuro Enokura <fj1826dm at aa.jp.fujitsu.com>

Thanks,
Tatsuro Enokura

---------------------------------------------------------------------
diff -r 95196b0f37a5 virtinst/Guest.py
--- a/virtinst/Guest.py Mon Mar 12 12:39:59 2007 -0400
+++ b/virtinst/Guest.py Tue Mar 13 17:21:11 2007 +0900
@@ -148,9 +148,40 @@ class VirtualNetworkInterface:
         self.macaddr = macaddr
         self.bridge = bridge

-    def setup(self):
+    def setup(self, conn):
+        # get the running domain's vNIC MACaddresss
+        macaddrlist = []
+        ids = conn.listDomainsID();
+        for id in ids:
+            vm = conn.lookupByID(id)
+            disks = util.get_network_devices(vm)
+            for (dummy, dummy, dummy, vm_macaddr) in disks:
+                macaddrlist.append(vm_macaddr)
+
+        # get the Host's NIC MACaddress
+        host_macaddrlist = []
+        hostdevs = util.get_host_network_devices()
+        for(dummy, dummy, dummy, dummy, host_macaddr) in hostdevs:
+            host_macaddrlist.append(host_macaddr)
+
         if self.macaddr is None:
-            self.macaddr = util.randomMAC()
+            # macaddrs used check
+            retryFlg = True
+            while retryFlg:
+                self.macaddr = util.randomMAC()
+                for macaddr in macaddrlist:
+                    if self.macaddr.upper() == macaddr.upper():
+                        break
+                else:
+                    retryFlg = False
+        else:
+            for macaddr in macaddrlist:
+                if self.macaddr.upper() == macaddr.upper():
+                    raise ValueError, "MAC address has been already
used by the running domain."
+            for macaddr in host_macaddrlist:
+                if self.macaddr.upper() == macaddr.upper():
+                    raise ValueError, "MAC address has been collided
with the physical NIC."
+
         if not self.bridge:
             self.bridge = util.default_bridge()

@@ -429,7 +460,7 @@ class Guest(object):
         for disk in self.disks:
             disk.setup(progresscb)
         for nic in self.nics:
-            nic.setup()
+            nic.setup(self.conn)

     def _get_disk_xml(self, install = True):
         """Get the disk config in the libvirt XML format"""
diff -r 95196b0f37a5 virtinst/util.py
--- a/virtinst/util.py  Mon Mar 12 12:39:59 2007 -0400
+++ b/virtinst/util.py  Tue Mar 13 17:18:23 2007 +0900
@@ -14,6 +14,7 @@

 import random
 import os.path
+import libxml2
 from sys import stderr

 def default_bridge():
@@ -123,3 +124,60 @@ def uuidFromString(s):
 def uuidFromString(s):
     s = s.replace('-', '')
     return [ int(s[i : i + 2], 16) for i in range(0, 32, 2) ]
+
+# the following function is from virt-manager/src/virtManager/domain.py
+def get_network_devices(vm):
+    xml = vm.XMLDesc(0)
+    doc = None
+    try:
+        doc = libxml2.parseDoc(xml)
+    except:
+        return []
+    ctx = doc.xpathNewContext()
+    disks = []
+    try:
+        ret = ctx.xpathEval("/domain/devices/interface")
+
+        for node in ret:
+            type = node.prop("type")
+            devmac = None
+            source = None
+            for child in node.children:
+                if child.name == "source":
+                    if type == "bridge":
+                        source = child.prop("bridge")
+                elif child.name == "mac":
+                    devmac = child.prop("address")
+
+            if source == None:
+                source = "-"
+
+            devdst = "eth%d" % len(disks)
+
+            disks.append([type, source, devdst, devmac])
+    finally:
+        if ctx != None:
+            ctx.xpathFreeContext()
+        if doc != None:
+            doc.freeDoc()
+    return disks
+
+# the following function quotes from python2.5/uuid.py
+def get_host_network_devices():
+    device = []
+    for dir in ['', '/sbin/', '/usr/sbin']:
+        executable = os.path.join(dir, "ifconfig")
+        if not os.path.exists(executable):
+            continue
+        try:
+            cmd = 'LC_ALL=C %s -a 2>/dev/null' % (executable)
+            pipe = os.popen(cmd)
+        except IOError:
+            continue
+        for line in pipe:
+            words = line.lower().split()
+            for i in range(len(words)):
+                if words[i] == "hwaddr":
+                    device.append(words)
+    return device
+
--------------------------------------------------------------------




More information about the et-mgmt-tools mailing list