
# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1199911995 28800 # Node ID a229f95979d52c955d46b93c589fd1cf4744ee27 # Parent ca8dc23eacc44970a2d79978bc9de65aaa600b92 Make device_parsing get XML description for a domain once for all phases Also, make memory devices parse the XML instead of ops on a domain. This gives us the ability to create a dominfo structure from XML-only. It would have been nice to put this into two separate patches, but I would have had to fake some memory stuff just to make the reorg work and then remove it in the next patch, so hopefully what I did is palatable to all :) Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r ca8dc23eacc4 -r a229f95979d5 libxkutil/device_parsing.c --- a/libxkutil/device_parsing.c Wed Jan 09 13:08:17 2008 +0100 +++ b/libxkutil/device_parsing.c Wed Jan 09 12:53:15 2008 -0800 @@ -24,6 +24,7 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <inttypes.h> #include <sys/stat.h> #include <libxml/tree.h> #include <libxml/parser.h> @@ -39,11 +40,13 @@ #define VCPU_XPATH (xmlChar *)"/domain/vcpu" #define NET_XPATH (xmlChar *)"/domain/devices/interface" #define EMU_XPATH (xmlChar *)"/domain/devices/emulator" +#define MEM_XPATH (xmlChar *)"/domain/memory | /domain/currentMemory" #define GRAPHICS_XPATH (xmlChar *)"/domain/devices/graphics" #define DEFAULT_BRIDGE "xenbr0" #define XSTREQ(x, y) (STREQ((char *)x, y)) +#define MAX(a,b) (((a)>(b))?(a):(b)) static void cleanup_disk_device(struct disk_device *dev) { @@ -306,6 +309,38 @@ static int parse_emu_device(xmlNode *nod return 0; } +static int parse_mem_device(xmlNode *node, struct virt_device **vdevs) +{ + struct virt_device *vdev = NULL; + struct mem_device *mdev = NULL; + char *content = NULL; + + vdev = calloc(1, sizeof(*vdev)); + if (vdev == NULL) + goto err; + + mdev = &(vdev->dev.mem); + + content = get_node_content(node); + + if (XSTREQ(node->name, "memory")) + sscanf(content, "%" PRIu64, &mdev->size); + else if (XSTREQ(node->name, "currentMemory")) + sscanf(content, "%" PRIu64, &mdev->maxsize); + + free(content); + + *vdevs = vdev; + + return 1; + + err: + free(content); + free(vdev); + + return 0; +} + static int parse_graphics_device(xmlNode *node, struct virt_device **vdevs) { struct virt_device *vdev = NULL; @@ -366,6 +401,8 @@ static int do_parse(xmlNodeSet *nsv, int do_real_parse = parse_vcpu_device; else if (type == VIRT_DEV_EMU) do_real_parse = parse_emu_device; + else if (type == VIRT_DEV_MEM) + do_real_parse = parse_mem_device; else if (type == VIRT_DEV_GRAPHICS) do_real_parse = parse_graphics_device; else @@ -414,7 +451,7 @@ static void swallow_err_msg(void *ctx, c /* do nothing, just swallow the message. */ } -static int parse_devices(char *xml, struct virt_device **_list, int type) +static int parse_devices(const char *xml, struct virt_device **_list, int type) { int len = 0; int count = 0; @@ -432,6 +469,8 @@ static int parse_devices(char *xml, stru xpathstr = VCPU_XPATH; else if (type == VIRT_DEV_EMU) xpathstr = EMU_XPATH; + else if (type == VIRT_DEV_MEM) + xpathstr = MEM_XPATH; else if (type == VIRT_DEV_GRAPHICS) xpathstr = GRAPHICS_XPATH; else @@ -500,128 +539,60 @@ struct virt_device *virt_device_dup(stru return dev; } -static int get_emu_device(virDomainPtr dom, struct virt_device **dev) +static int _get_mem_device(const char *xml, struct virt_device **list) +{ + struct virt_device *mdevs = NULL; + struct virt_device *mdev = NULL; + int ret; + + ret = parse_devices(xml, &mdevs, VIRT_DEV_MEM); + if (ret <= 0) + return ret; + + mdev = malloc(sizeof(*mdev)); + if (mdev == NULL) + return 0; + + memset(mdev, 0, sizeof(*mdev)); + + /* We could get one or two memory devices back, depending on + * if there is a currentMemory tag or not. Coalesce these + * into a single device to return + */ + + if (ret == 2) { + mdev->dev.mem.size = MAX(mdevs[0].dev.mem.size, + mdevs[1].dev.mem.size); + mdev->dev.mem.maxsize = MAX(mdevs[0].dev.mem.maxsize, + mdevs[1].dev.mem.maxsize); + } else { + mdev->dev.mem.size = MAX(mdevs[0].dev.mem.size, + mdevs[0].dev.mem.maxsize); + mdev->dev.mem.maxsize = mdev->dev.mem.size; + } + + mdev->type = VIRT_DEV_MEM; + mdev->id = strdup("mem"); + *list = mdev; + + cleanup_virt_devices(&mdevs, ret); + + return 1; +} + +int get_devices(virDomainPtr dom, struct virt_device **list, int type) { char *xml; int ret; - struct virt_device *list = NULL; xml = virDomainGetXMLDesc(dom, 0); if (xml == NULL) return 0; - ret = parse_devices(xml, &list, VIRT_DEV_EMU); - if (ret == 1) - *dev = &list[0]; + if (type == VIRT_DEV_MEM) + ret = _get_mem_device(xml, list); 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 == NULL) - 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; - int ret; - - xml = virDomainGetXMLDesc(dom, 0); - if (xml == NULL) - return 0; - - ret = parse_devices(xml, list, VIRT_DEV_DISK); - - free(xml); - - return ret; -} - -int get_net_devices(virDomainPtr dom, struct virt_device **list) -{ - char *xml; - int ret; - - xml = virDomainGetXMLDesc(dom, 0); - if (xml == NULL) - return 0; - - ret = parse_devices(xml, list, VIRT_DEV_NET); - - free(xml); - - return ret; -} - -int get_mem_devices(virDomainPtr dom, struct virt_device **list) -{ - int rc, ret; - uint64_t mem_size, mem_maxsize; - virDomainInfo dom_info; - struct virt_device *ret_list = NULL; - - rc = virDomainGetInfo(dom, &dom_info); - if (rc == -1) { - ret = -1; - goto out; - } - - mem_size = (uint64_t)dom_info.memory; - mem_maxsize = (uint64_t)dom_info.maxMem; - if (mem_size > mem_maxsize) { - ret = -1; - goto out; - } - - ret_list = malloc(sizeof(struct virt_device)); - if (ret_list == NULL) { - ret = -1; - free (ret_list); - goto out; - } - - ret_list->type = VIRT_DEV_MEM; - ret_list->dev.mem.size = mem_size; - ret_list->dev.mem.maxsize = mem_maxsize; - ret_list->id = strdup("mem"); - - ret = 1; - *list = ret_list; - out: - return ret; -} - -int get_vcpu_devices(virDomainPtr dom, struct virt_device **list) -{ - char *xml; - int ret; - - xml = virDomainGetXMLDesc(dom, 0); - if (xml == NULL) - return 0; - - ret = parse_devices(xml, list, VIRT_DEV_VCPU); + ret = parse_devices(xml, list, type); free(xml); @@ -794,14 +765,19 @@ int get_dominfo(virDomainPtr dom, struct goto out; } - get_emu_device(dom, &(*dominfo)->dev_emu); - 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); - (*dominfo)->dev_vcpu_ct = get_vcpu_devices(dom, &(*dominfo)->dev_vcpu); - + parse_devices(xml, &(*dominfo)->dev_emu, VIRT_DEV_EMU); + parse_devices(xml, &(*dominfo)->dev_graphics, VIRT_DEV_GRAPHICS); + + (*dominfo)->dev_mem_ct = _get_mem_device(xml, &(*dominfo)->dev_mem); + (*dominfo)->dev_net_ct = parse_devices(xml, + &(*dominfo)->dev_net, + VIRT_DEV_NET); + (*dominfo)->dev_disk_ct = parse_devices(xml, + &(*dominfo)->dev_disk, + VIRT_DEV_DISK); + (*dominfo)->dev_vcpu_ct = parse_devices(xml, + &(*dominfo)->dev_vcpu, + VIRT_DEV_VCPU); out: free(xml); diff -r ca8dc23eacc4 -r a229f95979d5 libxkutil/device_parsing.h --- a/libxkutil/device_parsing.h Wed Jan 09 13:08:17 2008 +0100 +++ b/libxkutil/device_parsing.h Wed Jan 09 12:53:15 2008 -0800 @@ -137,10 +137,7 @@ int get_dominfo(virDomainPtr dom, struct void cleanup_dominfo(struct domain **dominfo); -int get_disk_devices(virDomainPtr dom, struct virt_device **list); -int get_net_devices(virDomainPtr dom, struct virt_device **list); -int get_vcpu_devices(virDomainPtr dom, struct virt_device **list); -int get_mem_devices(virDomainPtr dom, struct virt_device **list); +int get_devices(virDomainPtr dom, struct virt_device **list, int type); void cleanup_virt_device(struct virt_device *dev); void cleanup_virt_devices(struct virt_device **devs, int count); diff -r ca8dc23eacc4 -r a229f95979d5 src/Virt_Device.c --- a/src/Virt_Device.c Wed Jan 09 13:08:17 2008 +0100 +++ b/src/Virt_Device.c Wed Jan 09 12:53:15 2008 -0800 @@ -283,22 +283,6 @@ int device_type_from_classname(const cha return VIRT_DEV_UNKNOWN; } -static int get_devices(virDomainPtr dom, - struct virt_device **devs, - int type) -{ - if (type == VIRT_DEV_NET) - return get_net_devices(dom, devs); - else if (type == VIRT_DEV_DISK) - return get_disk_devices(dom, devs); - else if (type == VIRT_DEV_MEM) - return get_mem_devices(dom, devs); - else if (type == VIRT_DEV_VCPU) - return get_vcpu_devices(dom, devs); - else - return -1; -} - int dom_devices(const CMPIBroker *broker, virDomainPtr dom, const char *ns, diff -r ca8dc23eacc4 -r a229f95979d5 src/Virt_DevicePool.c --- a/src/Virt_DevicePool.c Wed Jan 09 13:08:17 2008 +0100 +++ b/src/Virt_DevicePool.c Wed Jan 09 12:53:15 2008 -0800 @@ -174,7 +174,7 @@ static char *diskpool_member_of(const CM if (dom == NULL) goto out; - count = get_disk_devices(dom, &devs); + count = get_devices(dom, &devs, VIRT_DEV_DISK); for (i = 0; i < count; i++) { if (STREQ((devs[i].dev.disk.virtual_dev), dev)) { @@ -290,7 +290,7 @@ static char *netpool_member_of(const CMP if (dom == NULL) goto out; - count = get_net_devices(dom, &devs); + count = get_devices(dom, &devs, VIRT_DEV_NET); for (i = 0; i < count; i++) { if (STREQ((devs[i].id), dev)) { diff -r ca8dc23eacc4 -r a229f95979d5 src/Virt_RASD.c --- a/src/Virt_RASD.c Wed Jan 09 13:08:17 2008 +0100 +++ b/src/Virt_RASD.c Wed Jan 09 12:53:15 2008 -0800 @@ -66,16 +66,7 @@ static int list_devs(virConnectPtr conn, if (dom == NULL) return 0; - if (type == CIM_RASD_TYPE_DISK) - return get_disk_devices(dom, list); - else if (type == CIM_RASD_TYPE_NET) - return get_net_devices(dom, list); - else if (type == CIM_RASD_TYPE_PROC) - return get_vcpu_devices(dom, list); - else if (type == CIM_RASD_TYPE_MEM) - return get_mem_devices(dom, list); - else - return 0; + return get_devices(dom, list, type); } static struct virt_device *find_dev(virConnectPtr conn,