[libvirt] [PATCH 6/8] domain: Make <address type='pci'/> request address allocation
Cole Robinson
crobinso at redhat.com
Mon Mar 21 18:59:54 UTC 2016
On 03/21/2016 02:44 PM, John Ferlan wrote:
>
>
> On 03/08/2016 11:36 AM, Cole Robinson wrote:
>> If a bare device <address type='pci'/> is specified, set an internal
>> flag address->auto_allocate. Individual hv drivers can then check for
>> this and act on it if they want, nothing is allocated in generic code.
>>
>> If drivers allocate an address, they are expected to unset auto_allocate.
>> Generic domain conf code then checks at XML format time to ensure no
>> device addresses still have auto_allocate set; this ensures we aren't
>> formatting any bogus address XML, and informing the user if their
>> request didn't work. Add a genericxml2xml test case for this.
>>
>> The auto_allocate property is a part of the generic address structure
>> and not the PCI specific bits, this will make it easier to reuse with
>> other address types too.
>>
>> One note: we detect <address type='pci'/> by counting it's XML properties,
>> rather than comparing specifically against parsed values, which seems
>> easier to maintain.
>> ---
>> docs/schemas/domaincommon.rng | 5 +++-
>> src/conf/domain_conf.c | 29 +++++++++++++++++++++-
>> src/conf/domain_conf.h | 1 +
>> .../generic-pci-autofill-addr.xml | 27 ++++++++++++++++++++
>> tests/genericxml2xmltest.c | 17 +++++++++----
>> 5 files changed, 72 insertions(+), 7 deletions(-)
>> create mode 100644 tests/genericxml2xmlindata/generic-pci-autofill-addr.xml
>>
>
> Will also need to update 'formatdomain.html.in' to describe the new
> allowance of just "<address type='pci'>...
>
Darn I must have remembered and then forgot to update the docs like 10 times :/
> Would this be useful if "multifunction='on'" without specifying an
> address? e.g.:
>
> <address type='pci' multifunction='on'>
>
Maybe? Honestly I don't know much about when multifunction should be used.
>
> Could other address types find the functionality useful? That is, I want
> address type 'drive' or 'usb', but I have no idea how to fill in the
> rest, I want the hv to do it for me.
>
My intent with how this was implemented is that it shouldn't take much change
in generic domain_conf.c code to handle this for other address types: position
of auto_allocate in the address structure, and the generic device iterator
validating that all addresses were allocated.
>
>> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
>> index 6ca937c..d083250 100644
>> --- a/docs/schemas/domaincommon.rng
>> +++ b/docs/schemas/domaincommon.rng
>> @@ -4471,7 +4471,10 @@
>> <attribute name="type">
>> <value>pci</value>
>> </attribute>
>> - <ref name="pciaddress"/>
>> + <choice>
>> + <ref name="pciaddress"/>
>> + <empty/>
>> + </choice>
>> </group>
>> <group>
>> <attribute name="type">
>> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
>> index bc4e369..bbc42a4 100644
>> --- a/src/conf/domain_conf.c
>> +++ b/src/conf/domain_conf.c
>> @@ -3827,6 +3827,23 @@ virDomainDefPostParseTimer(virDomainDefPtr def)
>> }
>>
>>
>> + static int
> ^
> Extraneous space
>
>> +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;
>> +}
>> +
>> +
>> static int
>> virDomainDefPostParseInternal(virDomainDefPtr def,
>> virCapsPtr caps ATTRIBUTE_UNUSED,
>> @@ -3851,6 +3868,11 @@ virDomainDefPostParseInternal(virDomainDefPtr def,
>> if (virDomainDefPostParseTimer(def) < 0)
>> return -1;
>>
>> + /* ensure the driver filled in any auto_allocate addrs */
>> + if (virDomainDeviceInfoIterate(def, virDomainCheckUnallocatedDeviceAddrs,
>> + NULL) < 0)
>> + return -1;
>> +
>
> Why couldn't this go in virDomainDefPostParseDeviceIterator?
>
> That is, rather than have yet another iterator through the devices, call
> virDomainCheckUnallocatedDeviceAddrs right after or at the end of
> virDomainDeviceDefPostParse...
>
As the patches stand, it won't work with due to the ordering: this validation
check needs to come after qemuDomainAssignAddresses. When the patches are
reworked it may be able to be combined with DeviceDefPostParse
>> if (virDomainDefAddImplicitDevices(def) < 0)
>> return -1;
>>
>> @@ -4872,8 +4894,13 @@ virDomainDeviceInfoParseXML(xmlNodePtr node,
>>
>> switch ((virDomainDeviceAddressType) info->type) {
>> case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI:
>> - if (virDevicePCIAddressParseXML(address, &info->addr.pci) < 0)
>> + if (virXMLPropertyCount(address) == 1) {
>
> Wish there was some other way than counting attributes, but I guess
> since "type" is an attribute we can hopefully guarantee that only
> "type=<something>" has been supplied.
>
>> + /* Bare <address type='pci'/> is a request to allocate
>> + the address. */
>> + info->auto_allocate = true;
>> + } else if (virDevicePCIAddressParseXML(address, &info->addr.pci) < 0) {
>> goto cleanup;
>> + }
>> break;
>>
>> case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
>> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
>> index aba53a2..dd9d0b1 100644
>> --- a/src/conf/domain_conf.h
>> +++ b/src/conf/domain_conf.h
>> @@ -346,6 +346,7 @@ struct _virDomainDeviceInfo {
>> */
>> char *alias;
>> int type; /* virDomainDeviceAddressType */
>> + bool auto_allocate;
>
> The name is generic enough to make me think it could work for other
> address types, but only PCI is supported.
Yup, that's what I was going for.
- Cole
More information about the libvir-list
mailing list