[libvirt] [libvirt-glib PATCHv2 5/5] Implement gvir_config_domain_get_devices

Christophe Fergeau cfergeau at redhat.com
Tue Jan 3 14:50:29 UTC 2012


There are some devices which we are not able to parse yet, in these
cases a runtime warning is printed to tell what's going on.
---
 libvirt-gconfig/Makefile.am                        |    1 +
 .../libvirt-gconfig-domain-device-private.h        |   45 ++++++++++++++
 libvirt-gconfig/libvirt-gconfig-domain-device.c    |   62 ++++++++++++++++++++
 libvirt-gconfig/libvirt-gconfig-domain-disk.c      |   30 +++++++++-
 libvirt-gconfig/libvirt-gconfig-domain-graphics.c  |   33 ++++++++++
 libvirt-gconfig/libvirt-gconfig-domain-interface.c |   38 ++++++++++++
 libvirt-gconfig/libvirt-gconfig-domain.c           |   43 ++++++++++++++
 libvirt-gconfig/libvirt-gconfig-domain.h           |    1 +
 libvirt-gconfig/libvirt-gconfig-private.h          |    1 +
 libvirt-gconfig/libvirt-gconfig.sym                |    1 +
 10 files changed, 254 insertions(+), 1 deletions(-)
 create mode 100644 libvirt-gconfig/libvirt-gconfig-domain-device-private.h

diff --git a/libvirt-gconfig/Makefile.am b/libvirt-gconfig/Makefile.am
index d9eb25a..34c5cc5 100644
--- a/libvirt-gconfig/Makefile.am
+++ b/libvirt-gconfig/Makefile.am
@@ -52,6 +52,7 @@ GCONFIG_HEADER_FILES = \
 			libvirt-gconfig-storage-vol-target.h
 noinst_HEADERS = \
 			libvirt-gconfig-private.h \
+			libvirt-gconfig-domain-device-private.h \
 			libvirt-gconfig-helpers-private.h \
 			libvirt-gconfig-object-private.h \
 			libvirt-gconfig-xml-doc.h
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-device-private.h b/libvirt-gconfig/libvirt-gconfig-domain-device-private.h
new file mode 100644
index 0000000..7ba7bc6
--- /dev/null
+++ b/libvirt-gconfig/libvirt-gconfig-domain-device-private.h
@@ -0,0 +1,45 @@
+/*
+ * libvirt-gconfig-domain-device-private.h: libvirt domain device configuration
+ *
+ * Copyright (C) 2011 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: Christophe Fergeau <cfergeau at gmail.com>
+ */
+
+#ifndef __LIBVIRT_GCONFIG_DOMAIN_DEVICE_PRIVATE_H__
+#define __LIBVIRT_GCONFIG_DOMAIN_DEVICE_PRIVATE_H__
+
+#include <libvirt-gconfig/libvirt-gconfig-xml-doc.h>
+
+G_BEGIN_DECLS
+
+GVirConfigDomainDevice *
+gvir_config_domain_device_new_from_tree(GVirConfigXmlDoc *doc,
+                                        xmlNodePtr tree);
+GVirConfigDomainDevice *
+gvir_config_domain_disk_new_from_tree(GVirConfigXmlDoc *doc,
+                                      xmlNodePtr tree);
+GVirConfigDomainDevice *
+gvir_config_domain_graphics_new_from_tree(GVirConfigXmlDoc *doc,
+                                          xmlNodePtr tree);
+GVirConfigDomainDevice *
+gvir_config_domain_interface_new_from_tree(GVirConfigXmlDoc *doc,
+                                           xmlNodePtr tree);
+
+G_END_DECLS
+
+#endif /* __LIBVIRT_GCONFIG_DOMAIN_H__ */
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-device.c b/libvirt-gconfig/libvirt-gconfig-domain-device.c
index 8fcf60f..a9ae8e8 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-device.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-device.c
@@ -48,3 +48,65 @@ static void gvir_config_domain_device_init(GVirConfigDomainDevice *device)
 
     device->priv = GVIR_CONFIG_DOMAIN_DEVICE_GET_PRIVATE(device);
 }
+
+G_GNUC_INTERNAL GVirConfigDomainDevice *
+gvir_config_domain_device_new_from_tree(GVirConfigXmlDoc *doc,
+                                        xmlNodePtr tree)
+{
+    GType type;
+
+    g_return_val_if_fail(GVIR_IS_CONFIG_XML_DOC(doc), NULL);
+    g_return_val_if_fail(tree != NULL, NULL);
+    g_return_val_if_fail(tree->name != NULL, NULL);
+
+    if (xmlStrEqual(tree->name, (xmlChar*)"disk")) {
+        return gvir_config_domain_disk_new_from_tree(doc, tree);
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"filesystem")) {
+        type = GVIR_TYPE_CONFIG_DOMAIN_FILESYS;
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"controller")) {
+        goto unimplemented;
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"lease")) {
+        goto unimplemented;
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"hostdev")) {
+        goto unimplemented;
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"redirdev")) {
+        goto unimplemented;
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"smartcard")) {
+        goto unimplemented;
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"interface")) {
+        return gvir_config_domain_interface_new_from_tree(doc, tree);
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"input")) {
+        type = GVIR_TYPE_CONFIG_DOMAIN_INPUT;
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"hub")) {
+        goto unimplemented;
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"graphics")) {
+        return gvir_config_domain_graphics_new_from_tree(doc, tree);
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"video")) {
+        type = GVIR_TYPE_CONFIG_DOMAIN_VIDEO;
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"parallel")) {
+        goto unimplemented;
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"serial")) {
+        goto unimplemented;
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"console")) {
+        type = GVIR_TYPE_CONFIG_DOMAIN_CONSOLE;
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"channel")) {
+        goto unimplemented;
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"watchdog")) {
+        goto unimplemented;
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"sound")) {
+        type = GVIR_TYPE_CONFIG_DOMAIN_SOUND;
+    } else if (xmlStrEqual(tree->name, (xmlChar*)"memballoon")) {
+        type = GVIR_TYPE_CONFIG_DOMAIN_MEMBALLOON;
+    } else {
+        g_warning("Unknown device node: %s", tree->name);
+        return NULL;
+    }
+
+    g_return_val_if_fail(g_type_is_a(type, GVIR_TYPE_CONFIG_DOMAIN_DEVICE), NULL);
+
+    return GVIR_CONFIG_DOMAIN_DEVICE(gvir_config_object_new_from_tree(type, doc, NULL, tree));
+unimplemented:
+    g_warning("Parsing of '%s' device nodes is unimplemented",
+            tree->name);
+    return NULL;
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-disk.c b/libvirt-gconfig/libvirt-gconfig-domain-disk.c
index 1f60213..1121007 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-disk.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-disk.c
@@ -63,12 +63,40 @@ GVirConfigDomainDisk *gvir_config_domain_disk_new_from_xml(const gchar *xml,
                                                            GError **error)
 {
     GVirConfigObject *object;
-
     object = gvir_config_object_new_from_xml(GVIR_TYPE_CONFIG_DOMAIN_DISK,
                                              "disk", NULL, xml, error);
+
     return GVIR_CONFIG_DOMAIN_DISK(object);
 }
 
+GVirConfigDomainDevice *
+gvir_config_domain_disk_new_from_tree(GVirConfigXmlDoc *doc,
+                                      xmlNodePtr tree)
+{
+    GVirConfigObject *object;
+    GVirConfigDomainDisk *disk;
+    GVirConfigDomainDiskType type;
+    xmlChar *type_str;
+
+    type_str = gvir_config_xml_get_attribute_content(tree, "type");
+    if (type_str == NULL)
+        return NULL;
+
+    type = gvir_config_genum_get_value(GVIR_TYPE_CONFIG_DOMAIN_DISK_TYPE,
+                                       (char *)type_str,
+                                       GVIR_CONFIG_DOMAIN_DISK_FILE);
+    xmlFree(type_str);
+    if (type == -1)
+        return NULL;
+
+    object = gvir_config_object_new_from_tree(GVIR_TYPE_CONFIG_DOMAIN_DISK,
+                                              doc, NULL, tree);
+    disk = GVIR_CONFIG_DOMAIN_DISK(object);
+    disk->priv->type = type;
+
+    return GVIR_CONFIG_DOMAIN_DEVICE(object);
+}
+
 void gvir_config_domain_disk_set_type(GVirConfigDomainDisk *disk,
                                       GVirConfigDomainDiskType type)
 {
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-graphics.c b/libvirt-gconfig/libvirt-gconfig-domain-graphics.c
index 53a663b..53d5e66 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-graphics.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-graphics.c
@@ -23,6 +23,7 @@
 #include <config.h>
 
 #include "libvirt-gconfig/libvirt-gconfig.h"
+#include "libvirt-gconfig/libvirt-gconfig-private.h"
 
 #define GVIR_CONFIG_DOMAIN_GRAPHICS_GET_PRIVATE(obj)                         \
         (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_TYPE_CONFIG_DOMAIN_GRAPHICS, GVirConfigDomainGraphicsPrivate))
@@ -47,3 +48,35 @@ static void gvir_config_domain_graphics_init(GVirConfigDomainGraphics *graphics)
 
     graphics->priv = GVIR_CONFIG_DOMAIN_GRAPHICS_GET_PRIVATE(graphics);
 }
+
+G_GNUC_INTERNAL GVirConfigDomainDevice *
+gvir_config_domain_graphics_new_from_tree(GVirConfigXmlDoc *doc,
+                                          xmlNodePtr tree)
+{
+    xmlChar *type;
+    GType gtype;
+
+    type = gvir_config_xml_get_attribute_content(tree, "type");
+    if (type == NULL)
+        return NULL;
+
+    if (xmlStrEqual(type, (xmlChar*)"sdl")) {
+        gtype = GVIR_TYPE_CONFIG_DOMAIN_GRAPHICS_SDL;
+    } else if (xmlStrEqual(type, (xmlChar*)"vnc")) {
+        gtype = GVIR_TYPE_CONFIG_DOMAIN_GRAPHICS_VNC;
+    } else if (xmlStrEqual(type, (xmlChar*)"spice")) {
+        gtype = GVIR_TYPE_CONFIG_DOMAIN_GRAPHICS_SPICE;
+    } else if (xmlStrEqual(type, (xmlChar*)"rdp")) {
+        g_warning("Parsing of '%s' graphics nodes is unimplemented", type);
+        return NULL;
+    } else if (xmlStrEqual(type, (xmlChar*)"desktop")) {
+        g_warning("Parsing of '%s' graphics nodes is unimplemented", type);
+        return NULL;
+    } else {
+        g_warning("Unknown graphics node: %s", type);
+        return NULL;
+    }
+    xmlFree(type);
+
+    return GVIR_CONFIG_DOMAIN_DEVICE(gvir_config_object_new_from_tree(gtype, doc, NULL, tree));
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-interface.c b/libvirt-gconfig/libvirt-gconfig-domain-interface.c
index 2d87040..0f427ff 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-interface.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-interface.c
@@ -95,3 +95,41 @@ void gvir_config_domain_interface_set_model(GVirConfigDomainInterface *interface
     gvir_config_object_replace_child_with_attribute(GVIR_CONFIG_OBJECT(interface),
                                                     "model", "type", model);
 }
+
+G_GNUC_INTERNAL GVirConfigDomainDevice *
+gvir_config_domain_interface_new_from_tree(GVirConfigXmlDoc *doc,
+                                           xmlNodePtr tree)
+{
+    xmlChar *type;
+    GType gtype;
+
+    type = gvir_config_xml_get_attribute_content(tree, "type");
+    if (type == NULL)
+        return NULL;
+
+    if (xmlStrEqual(type, (xmlChar*)"network")) {
+        gtype = GVIR_TYPE_CONFIG_DOMAIN_INTERFACE_NETWORK;
+    } else if (xmlStrEqual(type, (xmlChar*)"user")) {
+        gtype = GVIR_TYPE_CONFIG_DOMAIN_INTERFACE_USER;
+    } else if (xmlStrEqual(type, (xmlChar*)"bridge")) {
+        goto unimplemented;
+    } else if (xmlStrEqual(type, (xmlChar*)"direct")) {
+        goto unimplemented;
+    } else if (xmlStrEqual(type, (xmlChar*)"server")) {
+        goto unimplemented;
+    } else if (xmlStrEqual(type, (xmlChar*)"mcast")) {
+        goto unimplemented;
+    } else if (xmlStrEqual(type, (xmlChar*)"ethernet")) {
+        goto unimplemented;
+    } else {
+        g_warning("Unknown domain interface node: %s", type);
+        return NULL;
+    }
+    xmlFree(type);
+
+    return GVIR_CONFIG_DOMAIN_DEVICE(gvir_config_object_new_from_tree(gtype, doc, NULL, tree));
+
+unimplemented:
+    g_warning("Parsing of '%s' domain interface nodes is unimplemented", type);
+    return NULL;
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain.c b/libvirt-gconfig/libvirt-gconfig-domain.c
index 0d4cd8c..26ffc87 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain.c
@@ -362,3 +362,46 @@ void gvir_config_domain_add_device(GVirConfigDomain *domain,
     gvir_config_object_attach(devices_node, GVIR_CONFIG_OBJECT(device));
     g_object_unref(G_OBJECT(devices_node));
 }
+
+struct GetDeviceData {
+    GVirConfigXmlDoc *doc;
+    GList *devices;
+};
+
+static gboolean add_one_device(xmlNodePtr node, gpointer opaque)
+{
+    struct GetDeviceData* data = (struct GetDeviceData*)opaque;
+    GVirConfigDomainDevice *device;
+
+    device = gvir_config_domain_device_new_from_tree(data->doc, node);
+    g_warn_if_fail(device != NULL);
+    if (device != NULL)
+        data->devices = g_list_append(data->devices, device);
+
+    return TRUE;
+}
+
+/**
+ * gvir_config_domain_get_devices:
+ *
+ * Gets the list of devices attached to @domain
+ *
+ * Returns: (element-type LibvirtGConfig.DomainDevice) (transfer full):
+ * a newly allocated #GList of #GVirConfigDomainDevice.
+ */
+GList *gvir_config_domain_get_devices(GVirConfigDomain *domain)
+{
+    struct GetDeviceData data;
+
+    g_return_val_if_fail(GVIR_IS_CONFIG_DOMAIN(domain), NULL);
+
+    g_object_get(G_OBJECT(domain), "doc", &data.doc, NULL);
+    data.devices = NULL;
+    gvir_config_object_foreach_child(GVIR_CONFIG_OBJECT(domain), "devices",
+                                     add_one_device, &data);
+    if (data.doc != NULL) {
+        g_object_unref(G_OBJECT(data.doc));
+    }
+
+    return data.devices;
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain.h b/libvirt-gconfig/libvirt-gconfig-domain.h
index 2b631ea..f46cc35 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain.h
+++ b/libvirt-gconfig/libvirt-gconfig-domain.h
@@ -120,6 +120,7 @@ void gvir_config_domain_set_devices(GVirConfigDomain *domain,
                                     GList *devices);
 void gvir_config_domain_add_device(GVirConfigDomain *domain,
                                    GVirConfigDomainDevice *device);
+GList *gvir_config_domain_get_devices(GVirConfigDomain *domain);
 void gvir_config_domain_set_lifecycle(GVirConfigDomain *domain,
                                       GVirConfigDomainLifecycleEvent event,
                                       GVirConfigDomainLifecycleAction action);
diff --git a/libvirt-gconfig/libvirt-gconfig-private.h b/libvirt-gconfig/libvirt-gconfig-private.h
index e985ebd..d4df030 100644
--- a/libvirt-gconfig/libvirt-gconfig-private.h
+++ b/libvirt-gconfig/libvirt-gconfig-private.h
@@ -23,6 +23,7 @@
 #ifndef __LIBVIRT_GCONFIG_PRIVATE_H__
 #define __LIBVIRT_GCONFIG_PRIVATE_H__
 
+#include <libvirt-gconfig/libvirt-gconfig-domain-device-private.h>
 #include <libvirt-gconfig/libvirt-gconfig-helpers-private.h>
 #include <libvirt-gconfig/libvirt-gconfig-object-private.h>
 #include <libvirt-gconfig/libvirt-gconfig-xml-doc.h>
diff --git a/libvirt-gconfig/libvirt-gconfig.sym b/libvirt-gconfig/libvirt-gconfig.sym
index 87afa9d..7200da5 100644
--- a/libvirt-gconfig/libvirt-gconfig.sym
+++ b/libvirt-gconfig/libvirt-gconfig.sym
@@ -14,6 +14,7 @@ LIBVIRT_GCONFIG_0.0.3 {
 	gvir_config_domain_new;
 	gvir_config_domain_new_from_xml;
 	gvir_config_domain_set_clock;
+	gvir_config_domain_get_devices;
 	gvir_config_domain_set_devices;
 	gvir_config_domain_get_features;
 	gvir_config_domain_set_features;
-- 
1.7.7.5




More information about the libvir-list mailing list