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

Tatsuro Enokura fj7716hz at aa.jp.fujitsu.com
Wed Mar 14 10:12:19 UTC 2007


Hi, Hugh

Hugh Brock 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.

> Actually, you really don't need to build up a list of mac addresses and
> iterate over them. A much easier way is simply to get the XML for a
> domain and then use an xpath expression something like
> 
> 	if ctx.xpathEval("count(/domain/devices/interface/mac/@address='%s')" %
> macaddr) > 0:
> 	# handle the case where the macaddr conflicts with an existing domain
> 
> If you can rewrite the patch along these lines I'll be happy to take it.

Thank you for your suggestion.
I rewrite the patch.

Thanks,
Tatsuro Enokura

-------------------------------------------------------------------------------
diff -r 6b63ce413aab virtinst/Guest.py
--- a/virtinst/Guest.py Tue Mar 13 12:43:49 2007 -0400
+++ b/virtinst/Guest.py Wed Mar 14 18:08:31 2007 +0900
@@ -15,6 +15,7 @@ import os, os.path
  import os, os.path
  import stat, sys, time
  import re
+import libxml2

  import libvirt

@@ -148,9 +149,76 @@ class VirtualNetworkInterface:
          self.macaddr = macaddr
          self.bridge = bridge

-    def setup(self):
+    def setup(self, conn):
+        # get Running Domains
+        ids = conn.listDomainsID();
+        vms = []
+        for id in ids:
+            vm = conn.lookupByID(id)
+            vms.append(vm)
+
+        # get the Host's NIC MACaddress
+        hostdevs = util.get_host_network_devices()
+
+        # check conflict MAC address
          if self.macaddr is None:
-            self.macaddr = util.randomMAC()
+            while 1:
+                self.macaddr = util.randomMAC()
+                for vm in vms:
+                    doc = None
+                    try:
+                        doc = libxml2.parseDoc(vm.XMLDesc(0))
+                    except:
+                        continue
+                    ctx = doc.xpathNewContext()
+                    try:
+                        try:
+                            count = 
ctx.xpathEval("count(/domain/devices/interface/mac[@address='%s'])"
+                                                   % self.macaddr.upper())
+                            count += 
ctx.xpathEval("count(/domain/devices/interface/mac[@address='%s'])"
+                                                   % self.macaddr.lower())
+                            if count > 0:
+                                break
+                        except:
+                            continue
+                    finally:
+                        if ctx is not None:
+                            ctx.xpathFreeContext()
+                        if doc is not None:
+                            doc.freeDoc()
+                else:
+                    break
+        else:
+            for vm in vms:
+                doc = None
+                try:
+                    doc = libxml2.parseDoc(vm.XMLDesc(0))
+                except:
+                    continue
+                ctx = doc.xpathNewContext()
+                try:
+                    try:
+                        count = 
ctx.xpathEval("count(/domain/devices/interface/mac[@address='%s'])"
+                                               % self.macaddr.upper())
+                        count += 
ctx.xpathEval("count(/domain/devices/interface/mac[@address='%s'])"
+                                               % self.macaddr.lower())
+                        if count > 0:
+                            # conflict macaddr
+                            raise RuntimeError, "The MAC address you 
entered is already in use by another guest!"
+                    except RuntimeError:
+                        raise
+                    except:
+                        continue
+                finally:
+                    if ctx is not None:
+                        ctx.xpathFreeContext()
+                    if doc is not None:
+                        doc.freeDoc()
+            for (dummy, dummy, dummy, dummy, host_macaddr) in hostdevs:
+                if self.macaddr.upper() == host_macaddr.upper():
+                    raise ValueError, "The MAC address you entered is 
conflict with the physical NIC."
+
+
          if not self.bridge:
              self.bridge = util.default_bridge()

@@ -429,7 +497,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 6b63ce413aab virtinst/util.py
--- a/virtinst/util.py  Tue Mar 13 12:43:49 2007 -0400
+++ b/virtinst/util.py  Wed Mar 14 16:52:27 2007 +0900
@@ -123,3 +123,22 @@ 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 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