[libvirt] [RFC PATCH 0/6] New API to normalize the device XML

Osier Yang jyang at redhat.com
Tue Jan 17 10:08:22 UTC 2012


On 2012年01月10日 06:53, Eric Blake wrote:
> On 01/09/2012 07:37 AM, Daniel P. Berrange wrote:
>> On Mon, Jan 09, 2012 at 10:29:08PM +0800, Osier Yang wrote:
>>> The initial purpose was to fix a regression for detaching device,
>>> (introduced by commit ea7182c29). There was a patch posted to
>>> resolve the problem:
>>>
>>> https://www.redhat.com/archives/libvir-list/2011-December/msg00818.html
>>>
>>> But as Eric suggested, it's not the ideal way to go, we never known
>>> how many stuffs like<address>  will be involved in future. So new API
>>> to invoke the internal parsing functions might be a right way then.
>>>
>>> However, things are not that simple (an API without internal driver
>>> support, invoking the parsing functions directly). As the domain conf
>>> is a neccessary argument to parse the device XML. (e.g. for an Input
>
> s/neccessary/necessary/
>
>>> device). Although we can bypass that by modification on
>>> virDomainDeviceDefParse, it could be trap as we will parse the device
>>> XML in another way which is different with the real parsing. So finally
>>> I choosed to implement the driver support for the new API. There might
>
> s/choosed/chose/
>
>>> be something I didn't take into consideration, (e.g. Do we need some
>>> flags for the XML parsing and formating?). But it can demo the thought
>
> s/formating/formatting/
>
>>> good enough.
>>>
>>> On the other hand, I'm wondering if it's deserved to introduce such
>>> an API, comparing it's usage, is it two heavy if we need the internal
>>> drivers support for such an API?
>>>
>>> Any thoughts and feedback is welcomed.
>>
>> I don't really understand what the use case is for this API, from
>> the description above.  Can you give an example of how, for example,
>> virt-manager would use this API todo something ?
>
> I see several potential uses:
>
> 1. XML feature probe.  For example, libvirt 0.9.9 just added the XML
> feature of having a<seclabel>  attached to a specific<disk>; older
> libvirt silently ignores that label.  Right now, I have no way to know
> if I use<seclabel>  if I will get a per-disk override; running
> virt-xml-validate on my machine doesn't help if the libvirt on the
> remote server is at a different libvirt version, and if my only
> connection to the remote machine is via libvirt connections rather than
> a direct ssh, then I can't run virt-xml-validate on the destination
> machine.  But with this new API, I could:
> construct a candidate XML
> run it through the API
> compare the resulting XML with my candidate
> if<seclabel>  is still intact, then the feature is supported; if it was
> stripped, then I am talking to an older libvirt that didn't know the feature
>
> 2. XML subset matching.  Things like 'virsh detach-device' want to be
> permissive in what the user passes in, by taking minimal XML from the
> user and expanding it to the exact XML present in the domain.  But since
> we allow interleaves, it's not easy to do the comparison from user XML
> to the order that the XML is generated by 'virsh dumpxml'.  With the new
> API, virsh could be coded to run any candidate XML through the
> normalization, prior to doing subset comparisons against the real domain
> XML, and have the assurance that all known elements and attributes
> appear in the same order.
>
> 3. XML validation.  It seems pretty easy to expand this API into taking
> a flag that says to compare the incoming XML against the RNG, and return
> NULL on failure to validate.  This would make implementation of 'virsh
> edit' smarter, by being able to validate the user's edits prior to
> trying to apply them.
>
> 4. libvirt-gconfig seems like an obvious client for taking user input
> and normalizing it into the same form that libvirt would output.
>
> However, I think the API needs to be a bit more flexible than what Osier
> proposed.  It needs to be an API on the virConnectPtr, not a
> virDomainPtr, since it is NOT tied to a specific domain, but to the
> parsing abilities of the connection in general.  I also think that the
> API can handle multiple XML types in a single API.  (Oh yuck - I just
> realized that VIR_DOMAIN_XML_INACTIVE==2, but
> VIR_INTERFACE_XML_INACTIVE==1, so we _can't_ have a common
> VIR_NORMALIZE_XML_INACTIVE).  I envision something more like:
>
> typedef enum {
>    /* All top-level elements where we have a getXMLDesc method: */
>    VIR_NORMALIZE_XML_DOMAIN   = 100, /* top-level is<domain>  */
>    VIR_NORMALIZE_XML_SNAPSHOT = 200, /* top-level is<domainsnapshot>  */
>    VIR_NORMALIZE_XML_NETWORK  = 300, /* top-level is<network>  */
>    ...
>    /* Additionally, sub-level elements that are used in various APIs: */
>    VIR_NORMALIZE_XML_DOMAIN_DEVICE = 101, /* any element that fits under
>            /domain/devices, such as<disk>  or<interface>  */
>    ...
> } virConnectNormalizeXMLTypes;
>
> typedef enum {
>    /* Reserve bits 0, 1, 2 for virDomainXMLFlags */
>    /* Reserve bits 0 for virInterfaceXMLFlags */
>    ...
>    VIR_NORMALIZE_XML_VALIDATE = (1<<  30), /* perform RNG validation */
> } virConnectNormalizeXMLFlags;
>
> /**
>   * virConnectNormalizeXML:
>   * @conn: Pointer to connection
>   * @xml: XML to be normalized
>   * @type: one value from virConnectNormalizeXMLTypes, documenting
>   *   expected top-level element of @xml
>   * @flags: bitwise-OR of virConnectNormalizeXMLFlags
>   *
>   * This function parses the incoming @xml, with root element
>   * according to @type, and returns the same XML normalized to the
>   * same form it would appear via the corresponding vir*GetXMLDesc
>   * function if it had described a real libvirt object.  No
>   * machine state is checked or changed, so while the XML may be
>   * valid, subsequent use of the XML might still fail for other
>   * reasons such as an attempt to reuse a UUID.
>   *
>   * The normalization process may reorder attributes and elements,
>   * and may add new elements describing default states. By default,
>   * unrecognized elements and attributes are silently removed, but
>   * if @flags includes VIR_NORMALIZE_XML_VALIDATE, an error is
>   * raised if any unknown input is encountered.
>   *
>   * Depending on @type, additional bits in @flags may be understood.
>   * For example, if @type specifies a domain or sub-element of a
>   * domain, the flags can include virDomainXMLFlags such as
>   * VIR_DOMAIN_XML_INACTIVE; whereas if @type specifies a host
>   * interface, the flags can include virInterfaceXMLFlags.
>   *
>   * Returns the normalized XML (caller must free), or NULL if the
>   * XML could not be normalized.
>   */
> char *
> virConnectNormalizeXML(virConnectPtr conn,
>                         const char *xml,
>                         unsigned int type,
>                         unsigned int flags);
>

The API should be defined as following if we tend to support XML
validation:

int
virConnectNormalizeXML(virConnectPtr conn,
                        const char *xmlin,
                        char *xmlout,
                        unsigned int type,
                        unsigned int flags);

Or we need a standalone API for XML validation? not mixing the
normalization with validation together instead? Personally I
want one could get what an API does easily from the its name.
i.e. I prefer two APIs. (virConnectValidateXML).

Osier




More information about the libvir-list mailing list