[et-mgmt-tools] [PATCH] Check the making domain's mac address
Tatsuro Enokura
fj7716hz at aa.jp.fujitsu.com
Thu Mar 15 10:52:16 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.
>
> I'm reviewing this now. I'm trying to work out if there's a way to do it
> without repeating so much code... :)...
Thank you for viewing my code.
I rewrite the patch that the repeating code become the method.
Thanks,
Tatsuro Enokura
--------------------------------------------------------------------
diff -r 057e8c1b54df virtinst/Guest.py
--- a/virtinst/Guest.py Wed Mar 14 16:11:43 2007 -0400
+++ b/virtinst/Guest.py Thu Mar 15 15:07:26 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,32 @@ 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()
+ if self.countMACaddr(vms) > 0:
+ continue
+ else:
+ break
+ else:
+ if self.countMACaddr(vms) > 0:
+ raise RuntimeError, "The MAC address you entered is
already in use by another guest!"
+ for (dummy, dummy, dummy, dummy, host_macaddr) in hostdevs:
+ if self.macaddr.upper() == host_macaddr.upper():
+ raise RuntimeError, "The MAC address you entered is
conflict with the physical NIC."
+
if not self.bridge:
self.bridge = util.default_bridge()
@@ -160,6 +184,30 @@ class VirtualNetworkInterface:
" <mac address='%(mac)s'/>\n" + \
" </interface>\n") % \
{ "bridge": self.bridge, "mac": self.macaddr }
+
+ def countMACaddr(self, vms):
+ count = 0
+ 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())
+ except:
+ continue
+ finally:
+ if ctx is not None:
+ ctx.xpathFreeContext()
+ if doc is not None:
+ doc.freeDoc()
+ return count
# Back compat class to avoid ABI break
class XenNetworkInterface(VirtualNetworkInterface):
@@ -429,7 +477,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 057e8c1b54df virtinst/util.py
--- a/virtinst/util.py Wed Mar 14 16:11:43 2007 -0400
+++ b/virtinst/util.py Thu Mar 15 14:05:00 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