[libvirt] [gconfig v6 3/5] Add GVirConfigDomainHostdevPci

Zeeshan Ali (Khattak) zeeshanak at gnome.org
Thu Jul 21 17:21:58 UTC 2016


Add API to read and write PCI hostdev nodes.
---
 libvirt-gconfig/Makefile.am                        |   2 +
 .../libvirt-gconfig-domain-hostdev-pci.c           | 232 +++++++++++++++++++++
 .../libvirt-gconfig-domain-hostdev-pci.h           |  81 +++++++
 libvirt-gconfig/libvirt-gconfig-domain-hostdev.c   |   2 +-
 libvirt-gconfig/libvirt-gconfig.h                  |   1 +
 libvirt-gconfig/libvirt-gconfig.sym                |  11 +
 6 files changed, 328 insertions(+), 1 deletion(-)
 create mode 100644 libvirt-gconfig/libvirt-gconfig-domain-hostdev-pci.c
 create mode 100644 libvirt-gconfig/libvirt-gconfig-domain-hostdev-pci.h

diff --git a/libvirt-gconfig/Makefile.am b/libvirt-gconfig/Makefile.am
index a7c6c4e..0400343 100644
--- a/libvirt-gconfig/Makefile.am
+++ b/libvirt-gconfig/Makefile.am
@@ -51,6 +51,7 @@ GCONFIG_HEADER_FILES = \
 			libvirt-gconfig-domain-graphics-spice.h \
 			libvirt-gconfig-domain-graphics-vnc.h \
 			libvirt-gconfig-domain-hostdev.h \
+			libvirt-gconfig-domain-hostdev-pci.h \
 			libvirt-gconfig-domain-input.h \
 			libvirt-gconfig-domain-interface.h \
 			libvirt-gconfig-domain-interface-bridge.h \
@@ -143,6 +144,7 @@ GCONFIG_SOURCE_FILES = \
 			libvirt-gconfig-domain-graphics-spice.c \
 			libvirt-gconfig-domain-graphics-vnc.c \
 			libvirt-gconfig-domain-hostdev.c \
+			libvirt-gconfig-domain-hostdev-pci.c \
 			libvirt-gconfig-domain-input.c \
 			libvirt-gconfig-domain-interface.c \
 			libvirt-gconfig-domain-interface-bridge.c \
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-hostdev-pci.c b/libvirt-gconfig/libvirt-gconfig-domain-hostdev-pci.c
new file mode 100644
index 0000000..c173a8e
--- /dev/null
+++ b/libvirt-gconfig/libvirt-gconfig-domain-hostdev-pci.c
@@ -0,0 +1,232 @@
+/*
+ * libvirt-gconfig-domain-hostdev.c: libvirt domain hostdev configuration
+ *
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Zeeshan Ali (Khattak) <zeeshanak at gnome.org>
+ *          Christophe Fergeau <cfergeau at redhat.com>
+ */
+
+#include <config.h>
+
+#include "libvirt-gconfig/libvirt-gconfig.h"
+#include "libvirt-gconfig/libvirt-gconfig-private.h"
+
+#define GVIR_CONFIG_DOMAIN_HOSTDEV_PCI_GET_PRIVATE(obj)                         \
+        (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_CONFIG_TYPE_DOMAIN_HOSTDEV_PCI, GVirConfigDomainHostdevPciPrivate))
+
+struct _GVirConfigDomainHostdevPciPrivate
+{
+    gboolean unused;
+};
+
+G_DEFINE_TYPE(GVirConfigDomainHostdevPci, gvir_config_domain_hostdev_pci, GVIR_CONFIG_TYPE_DOMAIN_HOSTDEV);
+
+static void gvir_config_domain_hostdev_pci_class_init(GVirConfigDomainHostdevPciClass *klass)
+{
+    g_type_class_add_private(klass, sizeof(GVirConfigDomainHostdevPciPrivate));
+}
+
+
+static void gvir_config_domain_hostdev_pci_init(GVirConfigDomainHostdevPci *hostdev)
+{
+    hostdev->priv = GVIR_CONFIG_DOMAIN_HOSTDEV_PCI_GET_PRIVATE(hostdev);
+}
+
+/**
+ * gvir_config_domain_hostdev_pci_new:
+ *
+ * Creates a new #GVirConfigDomainHostdevPci.
+ *
+ * Returns: (transfer full): a new #GVirConfigDomainHostdevPci. The returned
+ * object should be unreffed with g_object_unref() when no longer needed.
+ */
+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. 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: (transfer full): a new #GVirConfigDomainHostdevPci, or NULL if @xml
+ * failed to be parsed. The returned object should be unreffed with
+ * g_object_unref() when no longer needed.
+ */
+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 (object == 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;
+    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));
+    node = gvir_config_object_get_xml_node(GVIR_CONFIG_OBJECT(address));
+    g_return_if_fail(node != NULL);
+
+    source = gvir_config_object_replace_child(GVIR_CONFIG_OBJECT(hostdev),
+                                              "source");
+    /* Because of https://bugzilla.redhat.com/show_bug.cgi?id=1327577, we can't
+     * just use GVirConfigDomainAddressPci's node, as is, since it contains
+     * a 'type' attribute, which is not accepted by libvirt. So we create a
+     * copy for our use and just delete the 'type' attribute from it.
+     */
+    node = xmlCopyNode(node, 1);
+    for (attr = node->properties; attr; attr = attr->next) {
+        if (g_strcmp0 ("type", (char *)attr->name) == 0) {
+            xmlRemoveProp (attr);
+            break;
+        }
+    }
+    gvir_config_object_set_child(source, node);
+    g_object_unref(source);
+}
+
+/**
+ * gvir_config_domain_hostdev_pci_get_address:
+ * @hostdev: A #GVirConfigDomainHostdevPci object.
+ *
+ * Gets the address associated with @hostdev.
+ *
+ * Returns: (transfer full): a new #GVirConfigDomainAddressPci, or NULL if no
+ * address is associated with @hostdev. The returned object should be unreffed
+ * with g_object_unref() when no longer needed.
+ */
+GVirConfigDomainAddressPci *gvir_config_domain_hostdev_pci_get_address(GVirConfigDomainHostdevPci *hostdev)
+{
+    GVirConfigObject *source;
+    GVirConfigObject* address;
+
+    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_HOSTDEV_PCI(hostdev), NULL);
+
+    source = gvir_config_object_get_child(GVIR_CONFIG_OBJECT(hostdev), "source");
+    if (source == NULL)
+        return NULL;
+
+    address = gvir_config_object_get_child_with_type(source,
+                                                     "address",
+                                                     GVIR_CONFIG_TYPE_DOMAIN_ADDRESS_PCI);
+    g_object_unref(source);
+    return GVIR_CONFIG_DOMAIN_ADDRESS_PCI(address);
+}
+
+void gvir_config_domain_hostdev_pci_set_managed(GVirConfigDomainHostdevPci *hostdev,
+                                                gboolean managed)
+{
+    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_HOSTDEV_PCI(hostdev));
+
+    gvir_config_object_set_attribute_with_type(GVIR_CONFIG_OBJECT(hostdev),
+                                               "managed",
+                                               G_TYPE_BOOLEAN,
+                                               managed,
+                                               NULL);
+}
+
+gboolean gvir_config_domain_hostdev_pci_get_managed(GVirConfigDomainHostdevPci *hostdev)
+{
+    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_HOSTDEV_PCI(hostdev), FALSE);
+
+    return gvir_config_object_get_attribute_boolean(GVIR_CONFIG_OBJECT(hostdev),
+                                                    NULL,
+                                                    "managed",
+                                                    FALSE);
+}
+
+void gvir_config_domain_hostdev_pci_set_rom_file(GVirConfigDomainHostdevPci *hostdev,
+                                                 const gchar *file)
+{
+    GVirConfigObject *rom;
+
+    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_HOSTDEV_PCI(hostdev));
+
+    rom = gvir_config_object_add_child(GVIR_CONFIG_OBJECT(hostdev), "rom");
+    gvir_config_object_set_attribute(rom,
+                                     "file", file,
+                                     NULL);
+    g_object_unref(rom);
+}
+
+void gvir_config_domain_hostdev_pci_set_rom_bar(GVirConfigDomainHostdevPci *hostdev,
+                                                gboolean bar)
+{
+    GVirConfigObject *rom;
+
+    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_HOSTDEV_PCI(hostdev));
+
+    rom = gvir_config_object_add_child(GVIR_CONFIG_OBJECT(hostdev), "rom");
+    gvir_config_object_set_attribute(rom,
+                                     "bar", bar? "on" : "off",
+                                     NULL);
+    g_object_unref(rom);
+}
+
+const gchar *gvir_config_domain_hostdev_pci_get_rom_file(GVirConfigDomainHostdevPci *hostdev)
+{
+    return gvir_config_object_get_attribute(GVIR_CONFIG_OBJECT(hostdev), "rom", "file");
+}
+
+gboolean gvir_config_domain_hostdev_pci_get_rom_bar(GVirConfigDomainHostdevPci *hostdev)
+{
+    xmlNodePtr hostdev_node;
+    xmlNodePtr rom_node;
+    const gchar *bar_str;
+
+    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_HOSTDEV_PCI(hostdev), FALSE);
+
+    hostdev_node = gvir_config_object_get_xml_node(GVIR_CONFIG_OBJECT(hostdev));
+    g_return_val_if_fail(hostdev_node != NULL, FALSE);
+
+    rom_node = gvir_config_xml_get_element(hostdev_node, "rom", NULL);
+    if (!rom_node || !(rom_node->children))
+        /* When containing rom node is missing, default value is TRUE for newer Qemu */
+        return TRUE;
+
+    bar_str = gvir_config_xml_get_attribute_content(rom_node, "bar");
+    return (g_strcmp0(bar_str, "on"));
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-hostdev-pci.h b/libvirt-gconfig/libvirt-gconfig-domain-hostdev-pci.h
new file mode 100644
index 0000000..51378aa
--- /dev/null
+++ b/libvirt-gconfig/libvirt-gconfig-domain-hostdev-pci.h
@@ -0,0 +1,81 @@
+/*
+ * libvirt-gconfig-domain-hostdev.h: libvirt domain hostdev configuration
+ *
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Zeeshan Ali (Khattak) <zeeshanak at gnome.org>
+ *          Christophe Fergeau <cfergeau at redhat.com>
+ */
+
+#if !defined(__LIBVIRT_GCONFIG_H__) && !defined(LIBVIRT_GCONFIG_BUILD)
+#error "Only <libvirt-gconfig/libvirt-gconfig.h> can be included directly."
+#endif
+
+#ifndef __LIBVIRT_GCONFIG_DOMAIN_HOSTDEV_PCI_H__
+#define __LIBVIRT_GCONFIG_DOMAIN_HOSTDEV_PCI_H__
+
+G_BEGIN_DECLS
+
+#define GVIR_CONFIG_TYPE_DOMAIN_HOSTDEV_PCI            (gvir_config_domain_hostdev_pci_get_type ())
+#define GVIR_CONFIG_DOMAIN_HOSTDEV_PCI(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GVIR_CONFIG_TYPE_DOMAIN_HOSTDEV_PCI, GVirConfigDomainHostdevPci))
+#define GVIR_CONFIG_DOMAIN_HOSTDEV_PCI_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GVIR_CONFIG_TYPE_DOMAIN_HOSTDEV_PCI, GVirConfigDomainHostdevPciClass))
+#define GVIR_CONFIG_IS_DOMAIN_HOSTDEV_PCI(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GVIR_CONFIG_TYPE_DOMAIN_HOSTDEV_PCI))
+#define GVIR_CONFIG_IS_DOMAIN_HOSTDEV_PCI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GVIR_CONFIG_TYPE_DOMAIN_HOSTDEV_PCI))
+#define GVIR_CONFIG_DOMAIN_HOSTDEV_PCI_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GVIR_CONFIG_TYPE_DOMAIN_HOSTDEV_PCI, GVirConfigDomainHostdevPciClass))
+
+typedef struct _GVirConfigDomainHostdevPci GVirConfigDomainHostdevPci;
+typedef struct _GVirConfigDomainHostdevPciPrivate GVirConfigDomainHostdevPciPrivate;
+typedef struct _GVirConfigDomainHostdevPciClass GVirConfigDomainHostdevPciClass;
+
+struct _GVirConfigDomainHostdevPci
+{
+    GVirConfigDomainHostdev parent;
+
+    GVirConfigDomainHostdevPciPrivate *priv;
+
+    /* Do not add fields to this struct */
+};
+
+struct _GVirConfigDomainHostdevPciClass
+{
+    GVirConfigDomainHostdevClass parent_class;
+
+    gpointer padding[20];
+};
+
+GType gvir_config_domain_hostdev_pci_get_type(void);
+
+GVirConfigDomainHostdevPci *gvir_config_domain_hostdev_pci_new(void);
+GVirConfigDomainHostdevPci *gvir_config_domain_hostdev_pci_new_from_xml(const gchar *xml,
+                                                                        GError **error);
+void gvir_config_domain_hostdev_pci_set_address(GVirConfigDomainHostdevPci *hostdev,
+                                                GVirConfigDomainAddressPci *address);
+GVirConfigDomainAddressPci *gvir_config_domain_hostdev_pci_get_address(GVirConfigDomainHostdevPci *hostdev);
+
+void gvir_config_domain_hostdev_pci_set_managed(GVirConfigDomainHostdevPci *hostdev,
+                                                gboolean managed);
+gboolean gvir_config_domain_hostdev_pci_get_managed(GVirConfigDomainHostdevPci *hostdev);
+void gvir_config_domain_hostdev_pci_set_rom_file(GVirConfigDomainHostdevPci *hostdev,
+                                                 const gchar *file);
+const gchar *gvir_config_domain_hostdev_pci_get_rom_file(GVirConfigDomainHostdevPci *hostdev);
+void gvir_config_domain_hostdev_pci_set_rom_bar(GVirConfigDomainHostdevPci *hostdev,
+                                                gboolean bar);
+gboolean gvir_config_domain_hostdev_pci_get_rom_bar(GVirConfigDomainHostdevPci *hostdev);
+
+G_END_DECLS
+
+#endif /* __LIBVIRT_GCONFIG_DOMAIN_HOSTDEV_PCI_H__ */
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-hostdev.c b/libvirt-gconfig/libvirt-gconfig-domain-hostdev.c
index ce5f8aa..459674d 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-hostdev.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-hostdev.c
@@ -62,7 +62,7 @@ gvir_config_domain_hostdev_new_from_tree(GVirConfigXmlDoc *doc,
     if (g_str_equal(type, "usb")) {
         goto unimplemented;
     } else if (g_str_equal(type, "pci")) {
-        goto unimplemented;
+        gtype = GVIR_CONFIG_TYPE_DOMAIN_HOSTDEV_PCI;
     } else if (g_str_equal(type, "scsi")) {
         goto unimplemented;
     } else {
diff --git a/libvirt-gconfig/libvirt-gconfig.h b/libvirt-gconfig/libvirt-gconfig.h
index cfa9dd3..6462154 100644
--- a/libvirt-gconfig/libvirt-gconfig.h
+++ b/libvirt-gconfig/libvirt-gconfig.h
@@ -68,6 +68,7 @@
 #include <libvirt-gconfig/libvirt-gconfig-domain-graphics-spice.h>
 #include <libvirt-gconfig/libvirt-gconfig-domain-graphics-vnc.h>
 #include <libvirt-gconfig/libvirt-gconfig-domain-hostdev.h>
+#include <libvirt-gconfig/libvirt-gconfig-domain-hostdev-pci.h>
 #include <libvirt-gconfig/libvirt-gconfig-domain-input.h>
 #include <libvirt-gconfig/libvirt-gconfig-domain-interface.h>
 #include <libvirt-gconfig/libvirt-gconfig-domain-interface-bridge.h>
diff --git a/libvirt-gconfig/libvirt-gconfig.sym b/libvirt-gconfig/libvirt-gconfig.sym
index 3607554..4d080b9 100644
--- a/libvirt-gconfig/libvirt-gconfig.sym
+++ b/libvirt-gconfig/libvirt-gconfig.sym
@@ -741,6 +741,17 @@ global:
 	gvir_config_domain_hostdev_get_readonly;
 	gvir_config_domain_hostdev_get_shareable;
 	gvir_config_domain_hostdev_get_type;
+	gvir_config_domain_hostdev_pci_get_address;
+	gvir_config_domain_hostdev_pci_get_managed;
+	gvir_config_domain_hostdev_pci_get_rom_bar;
+	gvir_config_domain_hostdev_pci_get_rom_file;
+	gvir_config_domain_hostdev_pci_get_type;
+	gvir_config_domain_hostdev_pci_new;
+	gvir_config_domain_hostdev_pci_new_from_xml;
+	gvir_config_domain_hostdev_pci_set_address;
+	gvir_config_domain_hostdev_pci_set_managed;
+	gvir_config_domain_hostdev_pci_set_rom_bar;
+	gvir_config_domain_hostdev_pci_set_rom_file;
 	gvir_config_domain_hostdev_set_boot_order;
 	gvir_config_domain_hostdev_set_readonly;
 	gvir_config_domain_hostdev_set_shareable;
-- 
2.7.4




More information about the libvir-list mailing list