@@ -2930,7 +2930,10 @@
(<span class="since">since 0.9.7, requires QEMU
0.13</span>). <code>multifunction</code> defaults to 'off',
but should be set to 'on' for function 0 of a slot that will
- have multiple functions used.
+ have multiple functions used.<br/>
+ <span class="since">Since 1.3.5</span>, some hypervisor drivers
+ may accept a bare <code><address type='pci'/></code> XML block
+ as an explicit request to allocate a PCI address for the device.
</dd>
<dt><code>drive</code></dt>
<dd>Drive addresses have the following additional
@@ -4538,7 +4538,10 @@
<attribute name="type">
<value>pci</value>
</attribute>
- <ref name="pciaddress"/>
+ <choice>
+ <ref name="pciaddress"/>
+ <empty/>
+ </choice>
</group>
<group>
<attribute name="type">
@@ -3924,6 +3924,23 @@ virDomainDefPostParseTimer(virDomainDefPtr def)
}
+static int
+virDomainCheckUnallocatedDeviceAddrs(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainDeviceDefPtr dev,
+ virDomainDeviceInfoPtr info,
+ void *data ATTRIBUTE_UNUSED)
+{
+ if (!info->auto_allocate)
+ return 0;
+
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("driver didn't allocate requested address type '%s' for device '%s'"),
+ virDomainDeviceAddressTypeToString(info->type),
+ virDomainDeviceTypeToString(dev->type));
+ return -1;
+}
+
+
/* Check if a drive type address $controller:$bus:$target:$unit is already
* taken by a disk or not.
*/
@@ -4455,6 +4472,12 @@ virDomainDefPostParse(virDomainDefPtr def,
return ret;
}
+ /* Ensure the driver filled in any auto_allocate addresses.
+ This must come after the assignAddressesCallback */
+ if (virDomainDeviceInfoIterate(def, virDomainCheckUnallocatedDeviceAddrs,
+ NULL) < 0)
+ return -1;
+
if (virDomainDefPostParseCheckFeatures(def, xmlopt) < 0)
return -1;
@@ -5091,8 +5114,13 @@ virDomainDeviceInfoParseXML(xmlNodePtr node,
switch ((virDomainDeviceAddressType) info->type) {
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI:
- if (virPCIDeviceAddressParseXML(address, &info->addr.pci) < 0)
+ if (virXMLPropertyCount(address) == 1) {
+ /* Bare <address type='pci'/> is a request to allocate
+ the address. */
+ info->auto_allocate = true;
+ } else if (virPCIDeviceAddressParseXML(address, &info->addr.pci) < 0) {
goto cleanup;
+ }
break;
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
@@ -347,6 +347,7 @@ struct _virDomainDeviceInfo {
*/
char *alias;
int type; /* virDomainDeviceAddressType */
+ bool auto_allocate;
union {
virPCIDeviceAddress pci;
virDomainDeviceDriveAddress drive;
new file mode 100644
@@ -0,0 +1,27 @@
+<domain type='test'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='vda' bus='virtio'/>
+ <address type='pci'/>
+ </disk>
+ <controller type='usb' index='0'>
+ <address type='pci'/>
+ </controller>
+ </devices>
+</domain>
@@ -91,6 +91,9 @@ mymain(void)
DO_TEST_FULL("name-slash-parse", 0, false,
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
+ DO_TEST_FULL("pci-autofill-addr", 0, false,
+ TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
+
virObjectUnref(caps);
virObjectUnref(xmlopt);