Hi, 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 <fj7716hz@xxxxxxxxxxxxxxxxx> Thanks, Tatsuro Enokura. -------------------------------------------------------------------- diff -r 3e18fa0cafc4 virtinst/Guest.py --- a/virtinst/Guest.py Fri Mar 02 09:16:33 2007 -0500 +++ b/virtinst/Guest.py Wed Mar 07 18:34:59 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() @@ -401,7 +432,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 3e18fa0cafc4 virtinst/util.py --- a/virtinst/util.py Fri Mar 02 09:16:33 2007 -0500 +++ b/virtinst/util.py Wed Mar 07 18:08:09 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 + --------------------------------------------------------------------