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

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

 



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
-------------------------------------------------------------------------------


[Index of Archives]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux