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
Attachment:
signature.asc
Description: PGP signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list