[PATCH 0 of 5] KVM XML parsing and generation support

This set adds most of the support we'll need for parsing and generating KVM domain XML. It updates the xml_parse_test app for KVM and allows testing of generated xml. I've tested with PV, FV, and KVM domains and it works for me. The next step after this will be making VSMS aware of how to create a KVM dominfo from RASDs, which will allow us to actually define a domain with DefineSystem for KVM.

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1199480010 28800 # Node ID 2cdaa36e4a78c8013ca4a8b58d4796d5e2012a68 # Parent ff56b87755fa9608a7d046976ef011cf48ce92f1 Extend xml_parse_test for KVM Also allow specification of a URI as the second argument on the command-line to allow connecting to libvirt for KVM. Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r ff56b87755fa -r 2cdaa36e4a78 libxkutil/xml_parse_test.c --- a/libxkutil/xml_parse_test.c Fri Jan 04 12:28:09 2008 -0800 +++ b/libxkutil/xml_parse_test.c Fri Jan 04 12:53:30 2008 -0800 @@ -26,6 +26,12 @@ static void print_os(struct domain *dom, print_value(d, "Args", dom->os_info.pv.cmdline); } else if (dom->type == DOMAIN_XENFV) { print_value(d, "Domain Type", "Xen FV"); + print_value(d, "Type", dom->os_info.fv.type); + print_value(d, "Loader", dom->os_info.fv.loader); + print_value(d, "Boot", dom->os_info.fv.boot); + + } else if (dom->type == DOMAIN_KVM) { + print_value(d, "Domain Type", "KVM/QEMU"); print_value(d, "Type", dom->os_info.fv.type); print_value(d, "Loader", dom->os_info.fv.loader); print_value(d, "Boot", dom->os_info.fv.boot); @@ -130,12 +136,15 @@ int main(int argc, char **argv) virDomainPtr dom; struct domain *dominfo; - if (argc != 2) { + if (argc < 2) { printf("Usage: %s domain\n", argv[0]); return 1; } - conn = virConnectOpen("xen:///"); + if (argc > 2) + conn = virConnectOpen(argv[2]); + else + conn = virConnectOpen("xen:///"); if (conn == NULL) { printf("Unable to connect to libvirt\n"); return 2;

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1199480010 28800 # Node ID c16905cea2137a9fb6275883550e08e1f83f2cc1 # Parent 2cdaa36e4a78c8013ca4a8b58d4796d5e2012a68 Make 'driver' not a required field, since it's not Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r 2cdaa36e4a78 -r c16905cea213 libxkutil/device_parsing.c --- a/libxkutil/device_parsing.c Fri Jan 04 12:53:30 2008 -0800 +++ b/libxkutil/device_parsing.c Fri Jan 04 12:53:30 2008 -0800 @@ -161,7 +161,7 @@ static int parse_disk_device(xmlNode *dn goto err; } } - if (! (ddev->driver && ddev->source && ddev->virtual_dev)) + if (! (ddev->source && ddev->virtual_dev)) goto err; vdev->type = VIRT_DEV_DISK; vdev->id = strdup(ddev->virtual_dev);

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1199480010 28800 # Node ID 6cd4300ae6a3509caec3a5076a6ccc498f06abcc # Parent c16905cea2137a9fb6275883550e08e1f83f2cc1 Make xml_parse_test capable of printing the generated XML for a domain Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r c16905cea213 -r 6cd4300ae6a3 libxkutil/xml_parse_test.c --- a/libxkutil/xml_parse_test.c Fri Jan 04 12:53:30 2008 -0800 +++ b/libxkutil/xml_parse_test.c Fri Jan 04 12:53:30 2008 -0800 @@ -3,6 +3,7 @@ #include <libvirt/libvirt.h> #include "device_parsing.h" +#include "xmlgen.h" static void print_value(FILE *d, const char *name, const char *val) { @@ -130,6 +131,18 @@ static void print_devices(struct domain } } +static void print_domxml(struct domain *dominfo, + FILE *d) +{ + char *xml; + + xml = system_to_xml(dominfo); + if (xml == NULL) + printf("Failed to create system XML\n"); + else + printf("%s\n", xml); +} + int main(int argc, char **argv) { virConnectPtr conn; @@ -137,7 +150,7 @@ int main(int argc, char **argv) struct domain *dominfo; if (argc < 2) { - printf("Usage: %s domain\n", argv[0]); + printf("Usage: %s domain [URI] [xml]\n", argv[0]); return 1; } @@ -163,8 +176,12 @@ int main(int argc, char **argv) printf("Parsed domain info\n"); - print_dominfo(dominfo, stdout); - print_devices(dominfo, stdout); + if ((argc > 3) && (argv[3][0] == 'x')) + print_domxml(dominfo, stdout); + else { + print_dominfo(dominfo, stdout); + print_devices(dominfo, stdout); + } return 0; }

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1199480010 28800 # Node ID 389b558dcf738da99f2c23f87d62ea5255defd56 # Parent 6cd4300ae6a3509caec3a5076a6ccc498f06abcc Make disk devices detect dev= or file= as a flag for which to use Also make VSMS set the flag properly based on the mode of the path we get in a RASD. Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r 6cd4300ae6a3 -r 389b558dcf73 libxkutil/device_parsing.c --- a/libxkutil/device_parsing.c Fri Jan 04 12:53:30 2008 -0800 +++ b/libxkutil/device_parsing.c Fri Jan 04 12:53:30 2008 -0800 @@ -24,6 +24,7 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <sys/stat.h> #include <libxml/tree.h> #include <libxml/parser.h> #include <libxml/xpath.h> @@ -149,11 +150,15 @@ static int parse_disk_device(xmlNode *dn goto err; } else if (STREQ((char*)child->name, "source")) { ddev->source = get_attr_value(child, "file"); - if (ddev->source) + if (ddev->source) { + ddev->disk_type = DISK_FILE; continue; + } ddev->source = get_attr_value(child, "dev"); - if (ddev->source) + if (ddev->source) { + ddev->disk_type = DISK_PHY; continue; + } goto err; } else if (STREQ((char*)child->name, "target")) { ddev->virtual_dev = get_attr_value(child, "dev"); @@ -825,6 +830,21 @@ int change_device(virDomainPtr dom, stru return 0; } +int disk_type_from_file(const char *path) +{ + struct stat s; + + if (stat(path, &s) < 0) + return DISK_UNKNOWN; + + if (S_ISBLK(s.st_mode)) + return DISK_PHY; + else if (S_ISREG(s.st_mode)) + return DISK_FILE; + else + return DISK_UNKNOWN; +} + /* * Local Variables: * mode: C diff -r 6cd4300ae6a3 -r 389b558dcf73 libxkutil/device_parsing.h --- a/libxkutil/device_parsing.h Fri Jan 04 12:53:30 2008 -0800 +++ b/libxkutil/device_parsing.h Fri Jan 04 12:53:30 2008 -0800 @@ -35,6 +35,7 @@ struct disk_device { char *driver; char *source; char *virtual_dev; + enum {DISK_UNKNOWN, DISK_PHY, DISK_FILE} disk_type; }; struct net_device { @@ -126,6 +127,8 @@ struct domain { struct virt_device *virt_device_dup(struct virt_device *dev); +int disk_type_from_file(const char *path); + int get_dominfo(virDomainPtr dom, struct domain **dominfo); void cleanup_dominfo(struct domain **dominfo); diff -r 6cd4300ae6a3 -r 389b558dcf73 libxkutil/xmlgen.c --- a/libxkutil/xmlgen.c Fri Jan 04 12:53:30 2008 -0800 +++ b/libxkutil/xmlgen.c Fri Jan 04 12:53:30 2008 -0800 @@ -22,7 +22,6 @@ #include <string.h> #include <stdlib.h> #include <inttypes.h> -#include <sys/stat.h> #include <uuid/uuid.h> #include "xmlgen.h" @@ -101,7 +100,6 @@ static char *disk_block_xml(const char * ret = asprintf(&xml, "<disk type='block' device='disk'>\n" - " <driver name='phy'/>\n" " <source dev='%s'/>\n" " <target dev='%s'/>\n" "</disk>\n", @@ -120,7 +118,6 @@ static char *disk_file_xml(const char *p ret = asprintf(&xml, "<disk type='file' device='disk'>\n" - " <driver name='tap' type='aio'/>\n" " <source file='%s'/>\n" " <target dev='%s'/>\n" "</disk>\n", @@ -134,17 +131,14 @@ static char *disk_file_xml(const char *p static char *disk_to_xml(struct disk_device *disk) { - struct stat s; - - if (stat(disk->source, &s) < 0) - return NULL; - - if (S_ISBLK(s.st_mode)) + if (disk->disk_type == DISK_PHY) return disk_block_xml(disk->source, disk->virtual_dev); - else + else if (disk->disk_type == DISK_FILE) /* If it's not a block device, we assume a file, which should be a reasonable fail-safe */ return disk_file_xml(disk->source, disk->virtual_dev); + else + return strdup("<!-- Unknown disk type -->\n"); } static char *net_to_xml(struct net_device *net) diff -r 6cd4300ae6a3 -r 389b558dcf73 src/Virt_VirtualSystemManagementService.c --- a/src/Virt_VirtualSystemManagementService.c Fri Jan 04 12:53:30 2008 -0800 +++ b/src/Virt_VirtualSystemManagementService.c Fri Jan 04 12:53:30 2008 -0800 @@ -206,6 +206,7 @@ static int rasd_to_vdev(CMPIInstance *in free(dev->dev.disk.source); dev->dev.disk.source = strdup(val); + dev->dev.disk.disk_type = disk_type_from_file(val); } else if (type == VIRT_DEV_NET) { free(dev->dev.net.mac); dev->dev.net.mac = devid;

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1199480024 28800 # Node ID ea65740aa1ffe73b47a4a14c8a853dbb3f040016 # Parent 389b558dcf738da99f2c23f87d62ea5255defd56 Changes to xmlgen for KVM domains Includes support for graphics and emulator devices, which benefit XenFV and XenPV domains as well. Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r 389b558dcf73 -r ea65740aa1ff libxkutil/xmlgen.c --- a/libxkutil/xmlgen.c Fri Jan 04 12:53:30 2008 -0800 +++ b/libxkutil/xmlgen.c Fri Jan 04 12:53:44 2008 -0800 @@ -186,6 +186,35 @@ static char *mem_to_xml(struct mem_devic return xml; } +static char *emu_to_xml(struct emu_device *emu) +{ + int ret; + char *xml; + + ret = asprintf(&xml, + "<emulator>%s</emulator>\n", + emu->path); + if (ret == -1) + xml = NULL; + + return xml; +} + +static char *graphics_to_xml(struct graphics_device *graphics) +{ + int ret; + char *xml; + + ret = asprintf(&xml, + "<graphics type='%s' port='%s'/>\n", + graphics->type, + graphics->port); + if (ret == -1) + xml = NULL; + + return xml; +} + char *device_to_xml(struct virt_device *dev) { switch (dev->type) { @@ -197,6 +226,10 @@ char *device_to_xml(struct virt_device * return mem_to_xml(&dev->dev.mem); case VIRT_DEV_VCPU: return proc_to_xml(&dev->dev.vcpu); + case VIRT_DEV_EMU: + return emu_to_xml(&dev->dev.emu); + case VIRT_DEV_GRAPHICS: + return graphics_to_xml(&dev->dev.graphics); default: return NULL; }; @@ -242,8 +275,16 @@ static char *system_xml(struct domain *d char *bl_args = NULL; char *xml; - bl = tagify("bootloader", domain->bootloader, NULL, 0); - bl_args = tagify("bootloader_args", domain->bootloader_args, NULL, 0); + if (domain->bootloader) + bl = tagify("bootloader", + domain->bootloader, + NULL, + 0); + if (domain->bootloader_args) + bl_args = tagify("bootloader_args", + domain->bootloader_args, + NULL, + 0); ret = asprintf(&xml, "<name>%s</name>\n" @@ -252,8 +293,8 @@ static char *system_xml(struct domain *d "<on_poweroff>%s</on_poweroff>\n" "<on_crash>%s</on_crash>\n", domain->name, - bl, - bl_args, + bl ? bl : "", + bl_args ? bl_args : "", vssd_recovery_action_str(domain->on_poweroff), vssd_recovery_action_str(domain->on_crash)); if (ret == -1) @@ -352,12 +393,39 @@ static char *_xenfv_os_xml(struct domain return xml; } +static char *_kvm_os_xml(struct domain *domain) +{ + struct fv_os_info *os = &domain->os_info.fv; + int ret; + char *xml; + char *type; + + if (os->type == NULL) + os->type = strdup("hvm"); + + type = tagify("type", os->type, NULL, 0); + + ret = asprintf(&xml, + "<os>\n" + " %s\n" + "</os>\n", + type); + if (ret == -1) + xml = NULL; + + free(type); + + 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 if (domain->type == DOMAIN_KVM) + return _kvm_os_xml(domain); else return strdup("<!-- unsupported domain type -->\n"); } @@ -372,6 +440,14 @@ char *system_to_xml(struct domain *domin int ret; uint8_t uuid[16]; char uuidstr[37]; + const char *domtype; + + if ((dominfo->type == DOMAIN_XENPV) || (dominfo->type == DOMAIN_XENFV)) + domtype = "xen"; + else if (dominfo->type == DOMAIN_KVM) + domtype = "kvm"; + else + domtype = "unknown"; if (dominfo->uuid) { strcpy(uuidstr, dominfo->uuid); @@ -385,6 +461,12 @@ char *system_to_xml(struct domain *domin concat_devxml(&devxml, dominfo->dev_net, dominfo->dev_net_ct); concat_devxml(&devxml, dominfo->dev_disk, dominfo->dev_disk_ct); + if (dominfo->dev_emu) + concat_devxml(&devxml, dominfo->dev_emu, 1); + + if (dominfo->dev_graphics) + concat_devxml(&devxml, dominfo->dev_graphics, 1); + concat_devxml(&sysdevxml, dominfo->dev_mem, dominfo->dev_mem_ct); concat_devxml(&sysdevxml, dominfo->dev_vcpu, dominfo->dev_vcpu_ct); @@ -392,7 +474,7 @@ char *system_to_xml(struct domain *domin osxml = os_xml(dominfo); ret = asprintf(&xml, - "<domain type='xen'>\n" + "<domain type='%s'>\n" "<uuid>%s</uuid>\n" "%s" "%s" @@ -401,6 +483,7 @@ char *system_to_xml(struct domain *domin "%s" "</devices>\n" "</domain>\n", + domtype, uuidstr, sysxml, osxml,

Dan Smith wrote:
This set adds most of the support we'll need for parsing and generating KVM domain XML. It updates the xml_parse_test app for KVM and allows testing of generated xml. I've tested with PV, FV, and KVM domains and it works for me.
The next step after this will be making VSMS aware of how to create a KVM dominfo from RASDs, which will allow us to actually define a domain with DefineSystem for KVM.
No comments from me. +1 -- Kaitlin Rupert IBM Linux Technology Center karupert@us.ibm.com

Dan Smith wrote:
This set adds most of the support we'll need for parsing and generating KVM domain XML. It updates the xml_parse_test app for KVM and allows testing of generated xml. I've tested with PV, FV, and KVM domains and it works for me.
The next step after this will be making VSMS aware of how to create a KVM dominfo from RASDs, which will allow us to actually define a domain with DefineSystem for KVM.
_______________________________________________ Libvirt-cim mailing list Libvirt-cim@redhat.com https://www.redhat.com/mailman/listinfo/libvirt-cimD
When trying to compile I get the following error on my 32-bit machine: gcc -DHAVE_CONFIG_H -I. -I. -I.. -DCMPI_VERSION=100 -I/usr/local/include/cmpi -I/usr/local/include/libvirt -I/usr/include/libxml2 -I/usr/local/include/libcmpiutil -g -O2 -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -Wall -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wpointer-arith -Wformat=2 -Wformat-security -Wformat-nonliteral -Wno-format-y2k -Wcast-align -Wno-unused-value -Werror -c xml_parse_test.c cc1: warnings being treated as errors xml_parse_test.c: In function ‘print_u64’: xml_parse_test.c:15: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 5 has type ‘uint64_t’ make[3]: *** [xml_parse_test.o] Error 1 I haven't seen that the print_u64() function was touched by these patches, so I don't want to say that they cause this error. But maybe this can be fixed as part of this patch series. I I'm completely wrong with this scenario, then maybe my vacation was too long and I did a pretty ugly mistake when trying to compile ;). -- Regards Heidi Eckhart Software Engineer IBM Linux Technology Center - Open Hypervisor

HE> I I'm completely wrong with this scenario, then maybe my vacation was HE> too long and I did a pretty ugly mistake when trying to compile ;). Nope, that's my problem. I should have used PRIu64 there. I'll cook up a patch. Thanks! -- Dan Smith IBM Linux Technology Center Open Hypervisor Team email: danms@us.ibm.com
participants (3)
-
Dan Smith
-
Heidi Eckhart
-
Kaitlin Rupert