[libvirt] [libvirt-glib 2/3] Add GVirConfigDomainHostdevPci

Christophe Fergeau cfergeau at redhat.com
Tue Feb 9 10:29:01 UTC 2016


On Mon, Feb 08, 2016 at 04:58:34PM +0000, Zeeshan Ali (Khattak) wrote:
> Hi,
> 
> >> + */
> >> +GVirConfigDomainHostdevPci *gvir_config_domain_hostdev_pci_new(void)
> >> +{
> >> +    GVirConfigObject *object;
> >> +
> >> +    object = gvir_config_object_new(GVIR_CONFIG_TYPE_DOMAIN_HOSTDEV_PCI,
> >> +                                    "hostdev", NULL);
> >> +    gvir_config_object_set_attribute(object, "mode", "subsystem", NULL);
> >> +    gvir_config_object_set_attribute(object, "type", "pci", NULL);
> >> +
> >> +    return GVIR_CONFIG_DOMAIN_HOSTDEV_PCI(object);
> >> +}
> >> +
> >> +/**
> >> + * gvir_config_domain_hostdev_pci_new_from_xml:
> >> + * @xml: xml data to create the host device from
> >> + * @error: return location for a #GError, or NULL
> >> + *
> >> + * Creates a new #GVirConfigDomainHostdevPci with a reference count of 1.
> >> + * The host device object will be created using the XML description stored
> >> + * in @xml. This is a fragment of libvirt domain XML whose root node is
> >> + * <hostdev>.
> >> + *
> >> + * Returns: a new #GVirConfigDomainHostdevPci, or NULL if @xml failed to
> >> + * be parsed.
> >> + */
> >> +GVirConfigDomainHostdevPci *gvir_config_domain_hostdev_pci_new_from_xml(const gchar *xml,
> >> +                                                                        GError **error)
> >> +{
> >> +    GVirConfigObject *object;
> >> +
> >> +    object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_HOSTDEV_PCI,
> >> +                                             "hostdev", NULL, xml, error);
> >> +    if (*error != NULL)
> >> +        return NULL;
> >> +
> >> +    if (g_strcmp0(gvir_config_object_get_attribute(object, NULL, "type"), "pci") != 0) {
> >> +        g_object_unref(G_OBJECT(object));
> >> +        g_return_val_if_reached(NULL);
> >> +    }
> >> +
> >> +    return GVIR_CONFIG_DOMAIN_HOSTDEV_PCI(object);
> >> +}
> >> +
> >> +void gvir_config_domain_hostdev_pci_set_address(GVirConfigDomainHostdevPci *hostdev,
> >> +                                                GVirConfigDomainAddressPci *address)
> >> +{
> >> +    GVirConfigObject *source;
> >> +    GVirConfigObject *addr_object;
> >> +    xmlNodePtr node;
> >> +    xmlAttrPtr attr;
> >> +
> >> +    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_HOSTDEV_PCI(hostdev));
> >> +    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_ADDRESS_PCI(address));
> >> +    addr_object = GVIR_CONFIG_OBJECT(address);
> >> +    node = gvir_config_object_get_xml_node(addr_object);
> >> +    g_return_if_fail(node != NULL);
> >> +
> >> +    source = gvir_config_object_replace_child(GVIR_CONFIG_OBJECT(hostdev),
> >> +                                              "source");
> >> +    /* We can't just use GVirConfigDomainAddressPci's node, as is, since it
> >> +     * contains a 'type' attribute that's not valid in this context. So we
> >> +     * create a copy for our use and just delete the 'type' node from it.
> >> +     */
> >
> > It took me a while to understand what this comment meant exactly, and
> > why this was needed. If I followed correctly, in libvirt RelaxNG schema,
> > the address for a PCI hostdev device is a 'pciaddress', which do not
> > have a 'type' attribute contrary to most other addresses. This means
> > that for the PCI address of a hostdev device, trying to set a 'type' attribute
> > will trigger errors from libvirt when it tries to parse the domain XML.
> 
> Yeah, I tried tried with `virsh edit` and it tells me xml doesn't
> confirm to schema.

What I mainly meant was that it would be nice to improve this comment,
ie replace "in this context" with something like "for addresses used in
a hostdevice node context".

> 
> > In my opinion, this is a libvirt bug that type="pci" is not accepted
> > here as libvirt documentation says:
> > « Device Addresses
> >
> > Many devices have an optional <address> sub-element to describe where
> > the device is placed on the virtual bus presented to the guest.[...]
> >
> > Every address has a mandatory attribute type that describes which bus
> > the device is on. »
> >
> > Maybe here things are a bit special as this address is not a direct
> > child of the <hostdev> element, but is contained within a <source>
> > element, but I still think it would be nicer of libvirt, and more
> > consistent to accept an optional type="pci" attribute here rather than
> > rejecting it. This would have spared us the ugly workaround below :(
> 
> Yeah but even if it's resolved in libvirt, we'd still want to have a
> work around for older libvirt.

Yes, of course, all I'm saying is that this looks like we are working
around a libvirt bug (either code/rng or documentation). In both case we
should make sure it's fixed/known, even if we'll have to deal with it in
libvirt-glib anyway.

> 
> >> +
> >> +const gchar *gvir_config_domain_hostdev_pci_get_rom(GVirConfigDomainHostdevPci *hostdev,
> >> +                                                    gboolean *bar)
> >> +{
> >> +    xmlNodePtr hostdev_node;
> >> +    xmlNodePtr rom_node;
> >> +    const gchar *bar_str;
> >> +
> >> +    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_HOSTDEV_PCI(hostdev), NULL);
> >> +
> >> +    hostdev_node = gvir_config_object_get_xml_node(GVIR_CONFIG_OBJECT(hostdev));
> >> +    g_return_val_if_fail(hostdev_node != NULL, NULL);
> >> +
> >> +    rom_node = gvir_config_xml_get_element(hostdev_node, "rom", NULL);
> >> +    if (!rom_node || !(rom_node->children))
> >> +        return NULL;
> >> +
> >> +    bar_str = gvir_config_xml_get_attribute_content(rom_node, "bar");
> >> +    if (g_strcmp0(bar_str, "on"))
> >> +        *bar = TRUE;
> >> +    else
> >> +        *bar = FALSE;
> >> +
> >> +    return (const char *) rom_node->children->content;
> >
> > The filename is in the file attribute, it's not in the node content
> > (addressed in a patch I'm going to send by switching to using
> > GVirConfigObject helpers).
> >
> > Regarding the API, I don't think there are other places in
> > libvirt-gconfig where we set (or get) 2 things with a single
> > setter/getter. Are these 2 parameters tightly coupled together?
> > It seems to me we could do something similar to the <os><type>
> > attributes ('arch' and 'machine'). These 2 attributes are set by 2
> > separate helpers, but these helpers are in the GVirConfigOs class:
> > gvir_config_domain_os_set_arch
> > gvir_config_domain_os_set_machine
> 
> Both 'arch' and 'machine' are separate attributes on the 'type' node
> but "bar" is an attribute of "rom" node, that I think is unlikely to
> be used in isolation. If we keep this API, I think I should change
> 'rom' to be nullable. I see your point though and I don't have hard
> feeling either way.

This _get_rom() method is returning a const char * and a gboolean bar, I
assume the returned const char * is the 'file' attribute (iirc that's
consistent with what is done in the unit test), and the gboolean is the
bar. So we are also talking about 2 separate attributes on the "rom"
node here.

Christophe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20160209/074d5e41/attachment-0001.sig>


More information about the libvir-list mailing list