
# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1199395653 28800 # Node ID 65a07575d2cfc4dfd3c1d57e0a0828c88dacf540 # Parent 3a838dfd165b5f721687a2bb0b2e03bb0c8192b7 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. Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r 3a838dfd165b -r 65a07575d2cf libxkutil/device_parsing.c --- a/libxkutil/device_parsing.c Thu Jan 03 08:22:48 2008 -0800 +++ b/libxkutil/device_parsing.c Thu Jan 03 13:27:33 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" @@ -195,6 +197,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 +230,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 +285,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 +353,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 +545,32 @@ 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"); + } + + printf("Type string: %s\n", dominfo->typestr); + + 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 +597,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 +677,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 +702,18 @@ 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); + + free(dom->os_info.pv.type); + if (dom->type == DOMAIN_XENPV) { + 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.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 3a838dfd165b -r 65a07575d2cf libxkutil/device_parsing.h --- a/libxkutil/device_parsing.h Thu Jan 03 08:22:48 2008 -0800 +++ b/libxkutil/device_parsing.h Thu Jan 03 13:27:33 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 3a838dfd165b -r 65a07575d2cf libxkutil/xmlgen.c --- a/libxkutil/xmlgen.c Thu Jan 03 08:22:48 2008 -0800 +++ b/libxkutil/xmlgen.c Thu Jan 03 13:27:33 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)