# HG changeset patch
# User Dan Smith <danms(a)us.ibm.com>
# Date 1199469751 28800
# Node ID 56f9f42e5b66ec661f60dee4b4c8cc3424790ff9
# 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:
- Removed stale debug statement
- Cleaned up free() of type string in cleanup_dominfo()
Signed-off-by: Dan Smith <danms(a)us.ibm.com>
diff -r d6b90a710230 -r 56f9f42e5b66 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 10:02:31 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,25 @@ 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);
+
+ 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");
+
+ return 1;
+}
+
static int do_parse(xmlNodeSet *nsv, int type, struct virt_device **l)
{
int i = 0;
@@ -209,6 +245,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 +300,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 +368,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 +560,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 +610,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 +690,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 +715,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 56f9f42e5b66 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 10:02:31 2008 -0800
@@ -48,38 +48,67 @@ 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,
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_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 56f9f42e5b66 libxkutil/xmlgen.c
--- a/libxkutil/xmlgen.c Fri Jan 04 07:28:02 2008 -0800
+++ b/libxkutil/xmlgen.c Fri Jan 04 10:02:31 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)