Automatically add multifunction address parameter when needed

Also check for use of duplicate addresses before passing such XML to
libvirt.  And fix tests (of course).
This commit is contained in:
Martin Kletzander 2013-09-02 16:56:53 +02:00
parent 57aab5de17
commit 70fae14635
2 changed files with 25 additions and 2 deletions

View File

@ -46,7 +46,7 @@
</controller> </controller>
<controller type="usb" index="0" model="ich9-uhci1"> <controller type="usb" index="0" model="ich9-uhci1">
<master startport="0"/> <master startport="0"/>
<address type="pci" domain="0" bus="0" slot="4" function="0"/> <address type="pci" domain="0" bus="0" slot="4" function="0" multifunction="on"/>
</controller> </controller>
<controller type="usb" index="0" model="ich9-uhci2"> <controller type="usb" index="0" model="ich9-uhci2">
<master startport="2"/> <master startport="2"/>
@ -134,7 +134,7 @@
</controller> </controller>
<controller type="usb" index="0" model="ich9-uhci1"> <controller type="usb" index="0" model="ich9-uhci1">
<master startport="0"/> <master startport="0"/>
<address type="pci" domain="0" bus="0" slot="4" function="0"/> <address type="pci" domain="0" bus="0" slot="4" function="0" multifunction="on"/>
</controller> </controller>
<controller type="usb" index="0" model="ich9-uhci2"> <controller type="usb" index="0" model="ich9-uhci2">
<master startport="2"/> <master startport="2"/>

View File

@ -612,6 +612,7 @@ class Guest(XMLBuilder):
for dev in self.get_all_devices(): for dev in self.get_all_devices():
dev.set_defaults() dev.set_defaults()
self._add_implied_controllers() self._add_implied_controllers()
self._check_address_multi()
self._set_disk_defaults() self._set_disk_defaults()
self._set_net_defaults() self._set_net_defaults()
self._set_input_defaults() self._set_input_defaults()
@ -697,6 +698,28 @@ class Guest(XMLBuilder):
ctrl.address.set_addrstr("spapr-vio") ctrl.address.set_addrstr("spapr-vio")
self.add_device(ctrl) self.add_device(ctrl)
def _check_address_multi(self):
addresses = {}
for d in self._devices:
if d.address.type != d.address.ADDRESS_TYPE_PCI:
continue
addr = d.address
addrstr = "%d%d%d" % (d.address.domain,
d.address.bus,
d.address.slot)
if addrstr not in addresses:
addresses[addrstr] = {}
if addr.function in addresses[addrstr]:
raise ValueError(_("Duplicate address for devices %s and %s") %
(str(d), str(addresses[addrstr][addr.function])))
addresses[addrstr][addr.function] = d
for devs in addresses.values():
if len(devs) > 1 and 0 in devs:
devs[0].address.multifunction = True
def _can_virtio(self, key): def _can_virtio(self, key):
if not self.conn.is_qemu(): if not self.conn.is_qemu():
return False return False