[Libvirt-cim] [PATCH 1 of 2] Add preliminary XML-parsing support for Xen FV domains

Dan Smith danms at us.ibm.com
Fri Jan 4 19:30:19 UTC 2008


# HG changeset patch
# User Dan Smith <danms at us.ibm.com>
# Date 1199478485 28800
# Node ID 4611462efdca4c1b6d45782d360d1ae6538fb407
# Parent  d6b90a71023048ba2bc601ea2180ff841ad44e5b
Add preliminary XML-parsing support for Xen FV domains

This adds a type switch for XenPV, XenFV, KVM to the struct domain.
It also adds parsing of 'graphics' and 'emulator' devices.  Finally,
amidst the compulsory changes to xmlgen.c are modifications to
generate a proper <os> block for XenFV domains.  More work will need
to be done here, but this is an example of how the domain->type switch
will be used to select different generation routines.

Changes:
 - Make VIRT_DEV_UNKNOWN start after CIM types, and with a constant
   so that automatic numbering starts again after the CIM range
 - Set the device types in the parse_*_device() functions for emu and graphics
 - Removed stale debug statement
 - Cleaned up free() of type string in cleanup_dominfo()

Signed-off-by: Dan Smith <danms at us.ibm.com>

diff -r d6b90a710230 -r 4611462efdca libxkutil/device_parsing.c
--- a/libxkutil/device_parsing.c	Fri Jan 04 07:28:02 2008 -0800
+++ b/libxkutil/device_parsing.c	Fri Jan 04 12:28:05 2008 -0800
@@ -36,6 +36,8 @@
 
 #define DISK_XPATH      (xmlChar *)"/domain/devices/disk"
 #define NET_XPATH       (xmlChar *)"/domain/devices/interface"
+#define EMU_XPATH       (xmlChar *)"/domain/devices/emulator"
+#define GRAPHICS_XPATH  (xmlChar *)"/domain/devices/graphics"
 
 #define DEFAULT_BRIDGE "xenbr0"
 
@@ -55,6 +57,17 @@ static void cleanup_net_device(struct ne
         free(dev->bridge);
 }
 
+static void cleanup_emu_device(struct emu_device *dev)
+{
+        free(dev->path);
+}
+
+static void cleanup_graphics_device(struct graphics_device *dev)
+{
+        free(dev->type);
+        free(dev->port);
+}
+
 void cleanup_virt_device(struct virt_device *dev)
 {
         if (dev == NULL)
@@ -64,6 +77,10 @@ void cleanup_virt_device(struct virt_dev
                 cleanup_disk_device(&dev->dev.disk);
         else if (dev->type == VIRT_DEV_NET)
                 cleanup_net_device(&dev->dev.net);
+        else if (dev->type == VIRT_DEV_EMU)
+                cleanup_emu_device(&dev->dev.emu);
+        else if (dev->type == VIRT_DEV_GRAPHICS)
+                cleanup_graphics_device(&dev->dev.graphics);
 
         free(dev->id);
 
@@ -195,6 +212,29 @@ static int parse_net_device(xmlNode *ino
         return 0;
 }
 
+static int parse_emu_device(xmlNode *node, struct virt_device *vdev)
+{
+        struct emu_device *edev = &(vdev->dev.emu);
+
+        edev->path = get_node_content(node);
+
+        vdev->type = VIRT_DEV_EMU;
+
+        return 1;
+}
+
+static int parse_graphics_device(xmlNode *node, struct virt_device *vdev)
+{
+        struct graphics_device *gdev = &(vdev->dev.graphics);
+
+        gdev->type = get_attr_value(node, "type");
+        gdev->port = get_attr_value(node, "port");
+
+        vdev->type = VIRT_DEV_GRAPHICS;
+
+        return 1;
+}
+
 static int do_parse(xmlNodeSet *nsv, int type, struct virt_device **l)
 {
         int i = 0;
@@ -209,6 +249,10 @@ static int do_parse(xmlNodeSet *nsv, int
                 do_real_parse = &parse_net_device; 
         else if (type == VIRT_DEV_DISK)        
                 do_real_parse = &parse_disk_device; 
+        else if (type == VIRT_DEV_EMU)
+                do_real_parse = parse_emu_device;
+        else if (type == VIRT_DEV_GRAPHICS)
+                do_real_parse = parse_graphics_device;
         else
                 goto err;                      
 
@@ -260,6 +304,10 @@ static int parse_devices(char *xml, stru
                 xpathstr = NET_XPATH;
         else if (type == VIRT_DEV_DISK)
                 xpathstr = DISK_XPATH;
+        else if (type == VIRT_DEV_EMU)
+                xpathstr = EMU_XPATH;
+        else if (type == VIRT_DEV_GRAPHICS)
+                xpathstr = GRAPHICS_XPATH;
         else
                 goto err1;
         
@@ -324,6 +372,48 @@ struct virt_device *virt_device_dup(stru
         return dev;
 }
 
+static int get_emu_device(virDomainPtr dom, struct virt_device **dev)
+{
+        char *xml;
+        int ret;
+        struct virt_device *list = NULL;
+
+        xml = virDomainGetXMLDesc(dom, 0);
+        if (!xml)
+                return 0;
+
+        ret = parse_devices(xml, &list, VIRT_DEV_EMU);
+        if (ret == 1)
+                *dev = &list[0];
+        else
+                *dev = NULL;
+
+        free(xml);
+
+        return ret;
+}
+
+static int get_graphics_device(virDomainPtr dom, struct virt_device **dev)
+{
+        char *xml;
+        int ret;
+        struct virt_device *list = NULL;
+
+        xml = virDomainGetXMLDesc(dom, 0);
+        if (!xml)
+                return 0;
+
+        ret = parse_devices(xml, &list, VIRT_DEV_GRAPHICS);
+        if (ret == 1)
+                *dev = &list[0];
+        else
+                *dev = NULL;
+
+        free(xml);
+
+        return ret;
+}
+
 int get_disk_devices(virDomainPtr dom, struct virt_device **list)
 {
         char *xml;
@@ -474,14 +564,30 @@ static int parse_os(struct domain *domin
 
         for (child = os->children; child != NULL; child = child->next) {
                 if (XSTREQ(child->name, "type"))
-                        STRPROP(dominfo, os_info.type, child);
+                        STRPROP(dominfo, os_info.pv.type, child);
                 else if (XSTREQ(child->name, "kernel"))
-                        STRPROP(dominfo, os_info.kernel, child);
+                        STRPROP(dominfo, os_info.pv.kernel, child);
                 else if (XSTREQ(child->name, "initrd"))
-                        STRPROP(dominfo, os_info.initrd, child);
+                        STRPROP(dominfo, os_info.pv.initrd, child);
                 else if (XSTREQ(child->name, "cmdline"))
-                        STRPROP(dominfo, os_info.cmdline, child);
-        }
+                        STRPROP(dominfo, os_info.pv.cmdline, child);
+                else if (XSTREQ(child->name, "loader"))
+                        STRPROP(dominfo, os_info.fv.loader, child);
+                else if (XSTREQ(child->name, "boot"))
+                        dominfo->os_info.fv.boot = get_attr_value(child,
+                                                                     "dev");
+        }
+
+        if ((STREQC(dominfo->os_info.fv.type, "hvm")) &&
+            (STREQC(dominfo->typestr, "xen")))
+                dominfo->type = DOMAIN_XENFV;
+        else if ((STREQC(dominfo->os_info.fv.type, "hvm")) &&
+                 (STREQC(dominfo->typestr, "kvm")))
+                dominfo->type = DOMAIN_KVM;
+        else if (STREQC(dominfo->os_info.pv.type, "linux"))
+                dominfo->type = DOMAIN_XENPV;
+        else
+                dominfo->type = -1;
 
         return 1;
 }
@@ -508,6 +614,8 @@ static int parse_domain(xmlNodeSet *nsv,
         xmlNode *child;
 
         memset(dominfo, 0, sizeof(*dominfo));
+
+        dominfo->typestr = get_attr_value(nodes[0], "type");
 
         for (child = nodes[0]->children; child != NULL; child = child->next) {
                 if (XSTREQ(child->name, "name"))
@@ -586,6 +694,9 @@ int get_dominfo(virDomainPtr dom, struct
                 goto out;
         }
 
+        ret = get_emu_device(dom, &(*dominfo)->dev_emu);
+        ret = get_graphics_device(dom, &(*dominfo)->dev_graphics);
+
         (*dominfo)->dev_mem_ct = get_mem_devices(dom, &(*dominfo)->dev_mem);
         (*dominfo)->dev_net_ct = get_net_devices(dom, &(*dominfo)->dev_net);
         (*dominfo)->dev_disk_ct = get_disk_devices(dom, &(*dominfo)->dev_disk);
@@ -608,10 +719,19 @@ void cleanup_dominfo(struct domain **dom
         free(dom->uuid);
         free(dom->bootloader);
         free(dom->bootloader_args);
-        free(dom->os_info.type);
-        free(dom->os_info.kernel);
-        free(dom->os_info.initrd);
-        free(dom->os_info.cmdline);
+
+        if (dom->type == DOMAIN_XENPV) {
+                free(dom->os_info.pv.type);
+                free(dom->os_info.pv.kernel);
+                free(dom->os_info.pv.initrd);
+                free(dom->os_info.pv.cmdline);
+        } else if (dom->type == DOMAIN_XENFV) {
+                free(dom->os_info.fv.type);
+                free(dom->os_info.fv.loader);
+                free(dom->os_info.fv.boot);
+        } else {
+                CU_DEBUG("Unknown domain type %i", dom->type);
+        }
 
         cleanup_virt_devices(&dom->dev_mem, dom->dev_mem_ct);
         cleanup_virt_devices(&dom->dev_net, dom->dev_net_ct);
diff -r d6b90a710230 -r 4611462efdca libxkutil/device_parsing.h
--- a/libxkutil/device_parsing.h	Fri Jan 04 07:28:02 2008 -0800
+++ b/libxkutil/device_parsing.h	Fri Jan 04 12:28:05 2008 -0800
@@ -48,38 +48,68 @@ struct mem_device {
         uint64_t maxsize;
 };
 
+struct emu_device {
+        char *path;
+};
+
+struct graphics_device {
+        char *type;
+        char *port;
+};
+
 struct virt_device {
-        enum {VIRT_DEV_UNKNOWN,
+        enum {
               VIRT_DEV_NET = CIM_RASD_TYPE_NET,
               VIRT_DEV_DISK = CIM_RASD_TYPE_DISK,
               VIRT_DEV_MEM = CIM_RASD_TYPE_MEM,
               VIRT_DEV_VCPU = CIM_RASD_TYPE_PROC,
+              VIRT_DEV_UNKNOWN = 1000,
+              VIRT_DEV_EMU,
+              VIRT_DEV_GRAPHICS,
         } type;
         union {
                 struct disk_device disk;
                 struct net_device net;
                 struct mem_device mem;
                 struct _virVcpuInfo vcpu;
+                struct emu_device emu;
+                struct graphics_device graphics;
         } dev;
         char *id;
 };
 
-struct os_info {
+struct pv_os_info {
         char *type;
         char *kernel;
         char *initrd;
         char *cmdline;
 };
 
+struct fv_os_info {
+        char *type; /* Should always be 'hvm' */
+        char *loader;
+        char *boot;
+};
+
 struct domain {
+        enum { DOMAIN_XENPV, DOMAIN_XENFV, DOMAIN_KVM } type;
         char *name;
+        char *typestr; /*xen, kvm, etc */
         char *uuid;
         char *bootloader;
         char *bootloader_args;
-        struct os_info os_info;
+
+        union {
+                struct pv_os_info pv;
+                struct fv_os_info fv;
+        } os_info;
+
         int on_poweroff;
         int on_reboot;
         int on_crash;
+
+        struct virt_device *dev_graphics;
+        struct virt_device *dev_emu;
 
         struct virt_device *dev_mem;
         int dev_mem_ct;
diff -r d6b90a710230 -r 4611462efdca libxkutil/xmlgen.c
--- a/libxkutil/xmlgen.c	Fri Jan 04 07:28:02 2008 -0800
+++ b/libxkutil/xmlgen.c	Fri Jan 04 12:28:05 2008 -0800
@@ -271,9 +271,9 @@ static char *system_xml(struct domain *d
         return xml;
 }
 
-static char *os_xml(struct domain *domain)
-{
-        struct os_info *os = &domain->os_info;
+static char *_xenpv_os_xml(struct domain *domain)
+{
+        struct pv_os_info *os = &domain->os_info.pv;
         int ret;
         char *xml;
         char *type = NULL;
@@ -312,6 +312,60 @@ static char *os_xml(struct domain *domai
         free(cmdline);
 
         return xml;
+}
+
+static char *_xenfv_os_xml(struct domain *domain)
+{
+        struct fv_os_info *os = &domain->os_info.fv;
+        int ret;
+        char *xml;
+        char *type;
+        char *loader;
+        char *boot;
+        struct kv bootattr = {"dev", NULL};
+
+        if (os->type == NULL)
+                os->type = strdup("hvm");
+
+        if (os->loader == NULL)
+                os->loader = strdup("/usr/lib/xen/boot/hvmloader");
+
+        if (os->boot == NULL)
+                os->boot = strdup("hd");
+
+        type = tagify("type", os->type, NULL, 0);
+        loader = tagify("loader", os->loader, NULL, 0);
+
+        bootattr.val = os->boot;
+        boot = tagify("boot", NULL, &bootattr, 1);
+
+        ret = asprintf(&xml,
+                       "<os>\n"
+                       "  %s\n"
+                       "  %s\n"
+                       "  %s\n"
+                       "</os>\n",
+                       type,
+                       loader,
+                       boot);
+        if (ret == -1)
+                xml = NULL;
+
+        free(type);
+        free(loader);
+        free(boot);
+
+        return xml;
+}
+
+static char *os_xml(struct domain *domain)
+{
+        if (domain->type == DOMAIN_XENPV)
+                return _xenpv_os_xml(domain);
+        else if (domain->type == DOMAIN_XENFV)
+                return _xenfv_os_xml(domain);
+        else
+                return strdup("<!-- unsupported domain type -->\n");
 }
 
 char *system_to_xml(struct domain *dominfo)




More information about the Libvirt-cim mailing list