[PATCH 00/47] Solution to solve unsupported tag missing issue

These patches are based on commit 04bfeb825e5e155ffa72119253de608ccf3bd72b. So I may need more work on rebasing. Most of bugs reported recently are about some tags libvirt-cim doesn't support will be dropped after resource updated. So a new member was added into every virt_device and domain structure. And a new structure named unknown device was added to save those tags new added. The original implementaion is reading every member of virt_device structure from xml and save it. But the defect of this is some tags were not a member of virt_device were dropped. After resource updated, every data in the virt_device will be used to regenerate new xml. Hence the tags unsupported above, disappeared. So I added a member into every virt_device and domain structure, 'others'. It's a link list and used to save all data read from xml. Another new structure 'unknown_device' was added to save data except libvirt-cim could recognize. The new implementation is, firstly parse_*_device() could read all nodes and properties from xml and save them into 'others' link list. Then every member of virt_device will fetch data from others link list and save it. So that nodes in the 'others' link list could be saved until they are used to re- generate xml. After resource updating finished, libvirt-cim will call *_xml() to generate xml. The new process of generating xml like this, firstly all data in the members of virt_device will be restored into 'others' link list, then a function (others_to_xml) will use this link list to generate xml. Some points I have updated, 1. 'others' link list has to be processed in _get_proc_device() and _get_mem_device(). They should be copied into new data structure. 2. If resource updating happened, others field should be cleared because this device has been changed and they are useless. Besides above some logic may be a little strange or boring. Implemention like that is just to be compatible with upper layer functions (to make changes as less as possible). After keep a balance I decided to devide the whole xml into several parts: <domain>------------------------others in domain to save unsupported sub-nodes of domain -some fields (devices, mem, vcpu...) will be skiped because -they have their own parsing functions. <name>xxx</name> <uuid>xxx</uuid> <vcpu>xxx</vcpu> <mem>xxx</mem> <devices> <disk>xxx</disk>------- others in virt_device to save unsupported tags of this device <emulator>xxx</emulator> ...----------- unknown_device to save unsupported device except like <disk>,<emu>,etc. </devices> </domain> Hence, all nodes read from xml will be restored after xml generation. Xu Wang (47): Add others member for saving unsupported tag and unknown device Add others and unknown_device clean up Add basic operations for reading data from xml node Fix xml parsing algorithm for parse_fs_device() Fix xml parsing algorithm for parse_block_device() Fix xml parsing algorithm for parse_vsi_device() Fix xml parsing algorithm for parse_net_device() Fix xml parsing algorithm for parse_vcpu_device() Fix xml parsing algorithm for parse_emu_device() Fix xml parsing algorithm for parse_mem_device() Fix xml parsing algorithm for parse_graphics_device() Fix xml parsing algorithm for parse_input_device() Add parse_unknown_device() Add parse_devices() for unknown type in get_dominfo_from_xml() Fix xml parsing algorithm in parse_domain() Fix xml parsing algorithm in parse_os() Fix xml parsing algorithm in parse_feature() Add dup function for device copy Add type CIM_RES_TYPE_DELETED and modify type as it after resource_del Add basic functions about converting others link list to xml Fix xml generation algorithm in disk_block_xml() Fix xml generation algorithm in disk_file_xml() Fix xml generation algorithm in disk_fs_xml() Fix xml generation algorithm in set_net_vsi() Fix xml generation algorithm in set_net_source() Fix xml generation algorithm in bridge_net_to_xml() Fix xml generation algorithm in net_xml() Fix xml generation algorithm in vcpu_xml() Fix xml generation algorithm in cputune_xml() Fix xml generation algorithm in mem_xml() Fix xml generation algorithm in emu_xml() Fix xml generation algorithm in graphics_vnc_xml() Fix xml generation algorithm in graphics_pty_xml() Fix xml generation algorithm in input_xml() Fix xml generation algorithm in system_xml() Fix xml generation algorithm in _xenpv_os_xml() Fix xml generation algorithm in _fv_bootlist_xml() Fix xml generation algorithm in _xenfv_os_xml() Fix xml generation algorithm in _kvm_os_xml() Fix xml generation algorithm in _lxc_os_xml() Fix xml generation algorithm in os_xml() Fix xml generation algorithm in features_xml() Add functions for xml generation of unknown devices Fix xml generation algorithm in system_to_xml() Add cleanup_others() calling during rasd_to_vdev() Add others handling in _get_mem_device() Add dup_others() into _get_proc_device() libxkutil/device_parsing.c | 1351 +++++++++++++++++++++----- libxkutil/device_parsing.h | 56 ++ libxkutil/xmlgen.c | 1470 +++++++++++++++++++++++------ src/Virt_VirtualSystemManagementService.c | 20 +- src/svpc_types.h | 1 + 5 files changed, 2346 insertions(+), 552 deletions(-)

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.h | 35 +++++++++++++++++++++++++++++++++++ 1 files changed, 35 insertions(+), 0 deletions(-) diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h index 2b6d3d1..027dd21 100644 --- a/libxkutil/device_parsing.h +++ b/libxkutil/device_parsing.h @@ -33,6 +33,26 @@ #include "../src/svpc_types.h" +/* The structure for saving unknown tag in the xml */ +enum others_type { + TYPE_PROP, + TYPE_NODE +}; + +struct others { + char *name; + char *parent; + enum others_type type; + char *value; + struct others *next; +}; + +/* The structure for saving unknown device */ +struct unknown_device { + char *name; + struct others *others; +}; + struct vsi_device { char *vsi_type; char *manager_id; @@ -56,6 +76,7 @@ struct disk_device { char *bus_type; char *cache; char *access_mode; /* access modes for DISK_FS (filesystem) type */ + struct others *others; }; struct net_device { @@ -70,21 +91,25 @@ struct net_device { uint64_t reservation; uint64_t limit; struct vsi_device vsi; + struct others *others; }; struct mem_device { uint64_t size; uint64_t maxsize; + struct others *others; }; struct vcpu_device { uint64_t quantity; uint32_t weight; uint64_t limit; + struct others *others; }; struct emu_device { char *path; + struct others *others; }; struct vnc_device { @@ -92,12 +117,14 @@ struct vnc_device { char *host; char *keymap; char *passwd; + struct others *others; }; struct sdl_device { char *display; char *xauth; char *fullscreen; + struct others *others; }; struct graphics_device { @@ -106,11 +133,13 @@ struct graphics_device { struct vnc_device vnc; struct sdl_device sdl; } dev; + struct others *others; }; struct input_device { char *type; char *bus; + struct others *others; }; struct virt_device { @@ -123,6 +152,7 @@ struct virt_device { struct emu_device emu; struct graphics_device graphics; struct input_device input; + struct unknown_device unknown; } dev; char *id; }; @@ -193,6 +223,11 @@ struct domain { struct virt_device *dev_vcpu; int dev_vcpu_ct; + + struct virt_device *dev_unknown; + int dev_unknown_ct; + + struct others *others; }; struct virt_device *virt_device_dup(struct virt_device *dev); -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.h | 35 +++++++++++++++++++++++++++++++++++ 1 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h [...]
struct mem_device { uint64_t size; uint64_t maxsize; + struct others *others;
On 10/08/2013 08:13 AM, Xu Wang wrote: this doesn't apply because the dumpCore support is missing
};
it would help if you rebase against current master (shouldn't be too much) and resend... -- Mit freundlichen Grüßen/Kind Regards Viktor Mihajlovski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martina Köderitz Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 53 insertions(+), 0 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 7900e06..ea84d07 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -52,6 +52,49 @@ /* Device parse function */ typedef int (*dev_parse_func_t)(xmlNode *, struct virt_device **); +static void cleanup_node_of_others(struct others *others) +{ + if (others == NULL) { + return; + } + + if (others->name) { + free(others->name); + } + + if (others->parent) { + free(others->parent); + } + + if (others->value) { + free(others->value); + } + + free(others); +} + +static void cleanup_others(struct others *others) +{ + struct others *head = others; + + if (others == NULL) + return; + + while (head) { + head = others->next; + cleanup_node_of_others(others); + others = head; + } +} + +static void cleanup_unknown_device(struct unknown_device *dev) +{ + if (dev == NULL) + return; + + cleanup_others(dev->others); +} + static void cleanup_disk_device(struct disk_device *dev) { if (dev == NULL) @@ -66,6 +109,7 @@ static void cleanup_disk_device(struct disk_device *dev) free(dev->virtual_dev); free(dev->bus_type); free(dev->access_mode); + cleanup_others(dev->others); } static void cleanup_vsi_device(struct vsi_device *dev) @@ -94,6 +138,7 @@ static void cleanup_net_device(struct net_device *dev) free(dev->device); free(dev->net_mode); free(dev->filter_ref); + cleanup_others(dev->others); } static void cleanup_emu_device(struct emu_device *dev) @@ -102,6 +147,7 @@ static void cleanup_emu_device(struct emu_device *dev) return; free(dev->path); + cleanup_others(dev->others); } static void cleanup_vnc_device(struct graphics_device *dev) @@ -110,6 +156,7 @@ static void cleanup_vnc_device(struct graphics_device *dev) free(dev->dev.vnc.host); free(dev->dev.vnc.keymap); free(dev->dev.vnc.passwd); + cleanup_others(dev->dev.vnc.others); } static void cleanup_sdl_device(struct graphics_device *dev) @@ -117,6 +164,7 @@ static void cleanup_sdl_device(struct graphics_device *dev) free(dev->dev.sdl.display); free(dev->dev.sdl.xauth); free(dev->dev.sdl.fullscreen); + cleanup_others(dev->dev.sdl.others); } static void cleanup_graphics_device(struct graphics_device *dev) @@ -130,6 +178,7 @@ static void cleanup_graphics_device(struct graphics_device *dev) cleanup_vnc_device(dev); free(dev->type); + cleanup_others(dev->others); } static void cleanup_input_device(struct input_device *dev) @@ -139,6 +188,7 @@ static void cleanup_input_device(struct input_device *dev) free(dev->type); free(dev->bus); + cleanup_others(dev->others); } void cleanup_virt_device(struct virt_device *dev) @@ -156,6 +206,8 @@ void cleanup_virt_device(struct virt_device *dev) cleanup_graphics_device(&dev->dev.graphics); else if (dev->type == CIM_RES_TYPE_INPUT) cleanup_input_device(&dev->dev.input); + else if (dev->type == CIM_RES_TYPE_UNKNOWN) + cleanup_unknown_device(&dev->dev.unknown); free(dev->id); @@ -1351,6 +1403,7 @@ void cleanup_dominfo(struct domain **dominfo) cleanup_virt_devices(&dom->dev_vcpu, dom->dev_vcpu_ct); cleanup_virt_devices(&dom->dev_graphics, dom->dev_graphics_ct); cleanup_virt_devices(&dom->dev_input, dom->dev_input_ct); + cleanup_virt_devices(&dom->dev_unknown, dom->dev_unknown_ct); free(dom); -- 1.7.1

Mit freundlichen Grüßen/Kind regards Boris Fiuczynski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martina Köderitz Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294 On 10/08/2013 08:13 AM, Xu Wang wrote:
Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 53 insertions(+), 0 deletions(-)
diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 7900e06..ea84d07 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -52,6 +52,49 @@ /* Device parse function */ typedef int (*dev_parse_func_t)(xmlNode *, struct virt_device **);
+static void cleanup_node_of_others(struct others *others) +{ + if (others == NULL) { + return; + } remove curly brackets + + if (others->name) { + free(others->name); + } + + if (others->parent) { + free(others->parent); + } + + if (others->value) { + free(others->value); + } All other cleanup methods neglect the NULL check. + + free(others); +} + +static void cleanup_others(struct others *others) +{ + struct others *head = others; + + if (others == NULL) + return; + + while (head) { You could join the three lines above into "while (others) {" + head = others->next; + cleanup_node_of_others(others); + others = head; + } +} + +static void cleanup_unknown_device(struct unknown_device *dev) +{ + if (dev == NULL) + return; free(dev->name); ??? + + cleanup_others(dev->others); +} + static void cleanup_disk_device(struct disk_device *dev) { if (dev == NULL) @@ -66,6 +109,7 @@ static void cleanup_disk_device(struct disk_device *dev) free(dev->virtual_dev); free(dev->bus_type); free(dev->access_mode); + cleanup_others(dev->others); }
static void cleanup_vsi_device(struct vsi_device *dev) @@ -94,6 +138,7 @@ static void cleanup_net_device(struct net_device *dev) free(dev->device); free(dev->net_mode); free(dev->filter_ref); + cleanup_others(dev->others); }
static void cleanup_emu_device(struct emu_device *dev) @@ -102,6 +147,7 @@ static void cleanup_emu_device(struct emu_device *dev) return;
free(dev->path); + cleanup_others(dev->others); }
static void cleanup_vnc_device(struct graphics_device *dev) @@ -110,6 +156,7 @@ static void cleanup_vnc_device(struct graphics_device *dev) free(dev->dev.vnc.host); free(dev->dev.vnc.keymap); free(dev->dev.vnc.passwd); + cleanup_others(dev->dev.vnc.others); }
static void cleanup_sdl_device(struct graphics_device *dev) @@ -117,6 +164,7 @@ static void cleanup_sdl_device(struct graphics_device *dev) free(dev->dev.sdl.display); free(dev->dev.sdl.xauth); free(dev->dev.sdl.fullscreen); + cleanup_others(dev->dev.sdl.others); }
static void cleanup_graphics_device(struct graphics_device *dev) @@ -130,6 +178,7 @@ static void cleanup_graphics_device(struct graphics_device *dev) cleanup_vnc_device(dev);
free(dev->type); + cleanup_others(dev->others); }
static void cleanup_input_device(struct input_device *dev) @@ -139,6 +188,7 @@ static void cleanup_input_device(struct input_device *dev)
free(dev->type); free(dev->bus); + cleanup_others(dev->others); }
void cleanup_virt_device(struct virt_device *dev) @@ -156,6 +206,8 @@ void cleanup_virt_device(struct virt_device *dev) cleanup_graphics_device(&dev->dev.graphics); else if (dev->type == CIM_RES_TYPE_INPUT) cleanup_input_device(&dev->dev.input); + else if (dev->type == CIM_RES_TYPE_UNKNOWN) + cleanup_unknown_device(&dev->dev.unknown);
free(dev->id);
@@ -1351,6 +1403,7 @@ void cleanup_dominfo(struct domain **dominfo) cleanup_virt_devices(&dom->dev_vcpu, dom->dev_vcpu_ct); cleanup_virt_devices(&dom->dev_graphics, dom->dev_graphics_ct); cleanup_virt_devices(&dom->dev_input, dom->dev_input_ct); + cleanup_virt_devices(&dom->dev_unknown, dom->dev_unknown_ct);
cleanup_others(dom->others); ???
free(dom);

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 200 +++++++++++++++++++++++++++++++++++++++++++- libxkutil/device_parsing.h | 21 +++++ 2 files changed, 219 insertions(+), 2 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index ea84d07..09dab97 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -52,7 +52,7 @@ /* Device parse function */ typedef int (*dev_parse_func_t)(xmlNode *, struct virt_device **); -static void cleanup_node_of_others(struct others *others) +void cleanup_node_of_others(struct others *others) { if (others == NULL) { return; @@ -73,7 +73,7 @@ static void cleanup_node_of_others(struct others *others) free(others); } -static void cleanup_others(struct others *others) +void cleanup_others(struct others *others) { struct others *head = others; @@ -254,6 +254,202 @@ char *get_node_content(xmlNode *node) return buf; } +void print_others(struct others *head) +{ + while (head) { + CU_DEBUG("---------------------------"); + CU_DEBUG("- others name: %s", head->name); + CU_DEBUG("- others value: %s", head->value); + CU_DEBUG("- others type: %d", head->type); + CU_DEBUG("- others parent: %s", head->parent); + CU_DEBUG("---------------------------"); + head = head->next; + } +} + +struct others *add_others(struct others *head, + xmlNode *node, + const xmlChar *name, + enum others_type type, + const xmlChar *parent) +{ + struct others *new = NULL; + + new = calloc(1, sizeof(*new)); + if (new == NULL) { + CU_DEBUG("calloc space failed."); + return NULL; + } + + new->name = strdup((char *)name); + if (parent) { + new->parent = strdup((char *)parent); + } + new->type = type; + if (type == TYPE_PROP) { + new->value = get_attr_value(node, (char *)name); + } else if (type == TYPE_NODE) { + new->value = get_node_content(node); + } + new->next = NULL; + + if (head == NULL) { + head = new; + } else { + new->next = head; + head = new; + } + + return head; +} + +bool compare_parent(const char *a, const char *b) +{ + if ((a == NULL) && (b == NULL)) { + return true; + } + + if ((a != NULL) && (b != NULL) && + STREQ(a, b)) { + return true; + } + + return false; +} + +char *fetch_from_others(struct others **head, + char *name, + enum others_type type, + char *parent) +{ + struct others *tmp = *head; + struct others *last = NULL; + char *value = NULL; + + while (tmp) { + if (STREQ(tmp->name, name) && + compare_parent(tmp->parent, parent) && + tmp->type == type) { + value = strdup(tmp->value); + if (tmp == *head) { + /* The first node is we needed. */ + if ((*head)->next) { + /* There are more than two nodes in others. */ + *head = (*head)->next; + } else { + *head = NULL; + } + } else { + last->next = tmp->next; + } + cleanup_node_of_others(tmp); + return value; + } + last = tmp; + tmp = tmp->next; + } + + return NULL; +} + +static bool seek_in_others(struct others **head, + char *name, + enum others_type type, + char *parent) +{ + struct others *tmp = *head; + struct others *last = NULL; + + while (tmp) { + if (STREQ(tmp->name, name) && + compare_parent(tmp->parent, parent) && + tmp->type == type) { + if (tmp == *head) { + if (tmp->next) { + *head = (*head)->next; + } else { + *head = NULL; + } + } else { + last->next = tmp->next; + } + cleanup_node_of_others(tmp); + + return true; + } + last = tmp; + tmp = tmp->next; + } + + return false; +} + +struct others *combine_others(struct others *head1, + struct others *head2) +{ + struct others *tail1 = head1; + + if (tail1 == NULL) { + return head2; + } + + while (tail1->next) { + tail1 = tail1->next; + } + + tail1->next = head2; + return head1; +} + +static struct others *parse_data_to_others(xmlNode *node, const xmlChar *parent) +{ + xmlNode *child = NULL; + xmlAttrPtr attrPtr = NULL; + struct others *head = NULL; + struct others *head2 = NULL; + + /* If name of node is "text", all operations will skip */ + if (XSTREQ(node->name, "text")) { + return NULL; + } + + head = add_others(head, + node, + node->name, + TYPE_NODE, + parent); + + if (head == NULL) { + goto err; + } + + /* Get properties of node */ + attrPtr = node->properties; + while (attrPtr) { + head = add_others(head, + node, + attrPtr->name, + TYPE_PROP, + node->name); + if (head == NULL) { + goto err; + } + + attrPtr = attrPtr->next; + } + + for (child = node->children; child != NULL; child = child->next) { + /* Recursion to restore child's properties or child if have */ + head2 = parse_data_to_others(child, node->name); + head = combine_others(head, head2); + } + + return head; +err: + CU_DEBUG("add_others failed."); + return NULL; +} + static int parse_fs_device(xmlNode *dnode, struct virt_device **vdevs) { struct virt_device *vdev = NULL; diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h index 027dd21..166f305 100644 --- a/libxkutil/device_parsing.h +++ b/libxkutil/device_parsing.h @@ -258,6 +258,27 @@ int change_device(virDomainPtr dom, struct virt_device *dev); bool has_kvm_domain_type(xmlNodePtr node); +struct others *add_others(struct others *head, + xmlNode *node, + const xmlChar *name, + enum others_type type, + const xmlChar *parent); + +char *fetch_from_others(struct others **head, + char *name, + enum others_type type, + char *parent); + +void cleanup_node_of_others(struct others *others); + +bool compare_parent(const char *a, const char *b); + +void print_others(struct others *head); + +void cleanup_others(struct others *others); + +struct others *combine_others(struct others *head1, struct others *head2); + #define XSTREQ(x, y) (STREQ((char *)x, y)) #define STRPROP(d, p, n) (d->p = get_node_content(n)) -- 1.7.1

Mit freundlichen Grüßen/Kind regards Boris Fiuczynski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martina Köderitz Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294 On 10/08/2013 08:13 AM, Xu Wang wrote:
Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 200 +++++++++++++++++++++++++++++++++++++++++++- libxkutil/device_parsing.h | 21 +++++ 2 files changed, 219 insertions(+), 2 deletions(-)
diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index ea84d07..09dab97 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -52,7 +52,7 @@ /* Device parse function */ typedef int (*dev_parse_func_t)(xmlNode *, struct virt_device **);
-static void cleanup_node_of_others(struct others *others) +void cleanup_node_of_others(struct others *others) { if (others == NULL) { return; @@ -73,7 +73,7 @@ static void cleanup_node_of_others(struct others *others) free(others); }
-static void cleanup_others(struct others *others) +void cleanup_others(struct others *others) { struct others *head = others;
@@ -254,6 +254,202 @@ char *get_node_content(xmlNode *node) return buf; }
+void print_others(struct others *head) +{ + while (head) { + CU_DEBUG("---------------------------"); + CU_DEBUG("- others name: %s", head->name); + CU_DEBUG("- others value: %s", head->value); + CU_DEBUG("- others type: %d", head->type); + CU_DEBUG("- others parent: %s", head->parent); + CU_DEBUG("---------------------------"); + head = head->next; + } +} Is the method above ever used?
+ +struct others *add_others(struct others *head, + xmlNode *node, + const xmlChar *name, + enum others_type type, + const xmlChar *parent) +{ + struct others *new = NULL; + + new = calloc(1, sizeof(*new)); + if (new == NULL) { + CU_DEBUG("calloc space failed."); + return NULL; + } + + new->name = strdup((char *)name); + if (parent) { + new->parent = strdup((char *)parent); + } + new->type = type; + if (type == TYPE_PROP) { + new->value = get_attr_value(node, (char *)name); + } else if (type == TYPE_NODE) { + new->value = get_node_content(node); + } + new->next = NULL; + + if (head == NULL) { + head = new; + } else { + new->next = head; + head = new; + } Suggestion for the 8 lines above: new->next = head; head = new;
+ + return head; +} + +bool compare_parent(const char *a, const char *b) +{ + if ((a == NULL) && (b == NULL)) { + return true; + } + + if ((a != NULL) && (b != NULL) && + STREQ(a, b)) { + return true; + } + + return false; +} + +char *fetch_from_others(struct others **head, You have an add method, a fetch method and a seek method... Fetch and seek methods both have the side effect to remove the entries if found. To me the name should therefore be more like add/remove or put/remove + char *name, + enum others_type type, + char *parent) I am just wondering: Is the parent as a simple string contain uniqueness that tags are placed correctly? Isn't in some cases the order of tags within the domain important? would that be maintained? Looking at the add and fetch/seek methods seems like it would reverse the order. +{ + struct others *tmp = *head; + struct others *last = NULL; + char *value = NULL; + + while (tmp) { + if (STREQ(tmp->name, name) && + compare_parent(tmp->parent, parent) && + tmp->type == type) { + value = strdup(tmp->value); + if (tmp == *head) { + /* The first node is we needed. */ + if ((*head)->next) { + /* There are more than two nodes in others. */ + *head = (*head)->next; + } else { + *head = NULL; + } Aren't the above 6 lines the same as: *head = (*head)->next; + } else { + last->next = tmp->next; + } + cleanup_node_of_others(tmp); + return value; + } + last = tmp; + tmp = tmp->next; + } + + return NULL; +} + +static bool seek_in_others(struct others **head, Naming? See above. + char *name, + enum others_type type, + char *parent) +{ + struct others *tmp = *head; + struct others *last = NULL; + + while (tmp) { + if (STREQ(tmp->name, name) && + compare_parent(tmp->parent, parent) && + tmp->type == type) { + if (tmp == *head) { + if (tmp->next) { + *head = (*head)->next; + } else { + *head = NULL; + } + } else { + last->next = tmp->next; + } + cleanup_node_of_others(tmp); + + return true; + } + last = tmp; + tmp = tmp->next; + } + + return false; +} To me it looks like this method could reuse fetch_from_others.
+ +struct others *combine_others(struct others *head1, + struct others *head2) +{ + struct others *tail1 = head1; + + if (tail1 == NULL) { + return head2; + } remove curly brackets?
Suggestion: if (head2 == NULL) return head1;
+ + while (tail1->next) { + tail1 = tail1->next; + } remove curly brackets? + + tail1->next = head2; + return head1; +} + +static struct others *parse_data_to_others(xmlNode *node, const xmlChar *parent) +{ + xmlNode *child = NULL; + xmlAttrPtr attrPtr = NULL; + struct others *head = NULL; + struct others *head2 = NULL; + + /* If name of node is "text", all operations will skip */ + if (XSTREQ(node->name, "text")) { + return NULL; + } remove curly brackets? + + head = add_others(head, + node, + node->name, + TYPE_NODE, + parent); + + if (head == NULL) { + goto err; + } remove curly brackets? + + /* Get properties of node */ + attrPtr = node->properties; + while (attrPtr) { + head = add_others(head, + node, + attrPtr->name, + TYPE_PROP, + node->name); + if (head == NULL) { + goto err; + } + + attrPtr = attrPtr->next; + } + + for (child = node->children; child != NULL; child = child->next) { + /* Recursion to restore child's properties or child if have */ + head2 = parse_data_to_others(child, node->name); + head = combine_others(head, head2); wouldn't it make things easier if instead of combining/flattening xml subtags into a single list the xml structure would be replicated on the others structure e.g. by adding a child pointer into the others structure? + } + + return head; +err: + CU_DEBUG("add_others failed."); + return NULL; +} + static int parse_fs_device(xmlNode *dnode, struct virt_device **vdevs) { struct virt_device *vdev = NULL; diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h index 027dd21..166f305 100644 --- a/libxkutil/device_parsing.h +++ b/libxkutil/device_parsing.h @@ -258,6 +258,27 @@ int change_device(virDomainPtr dom, struct virt_device *dev);
bool has_kvm_domain_type(xmlNodePtr node);
+struct others *add_others(struct others *head, + xmlNode *node, + const xmlChar *name, + enum others_type type, + const xmlChar *parent); + +char *fetch_from_others(struct others **head, + char *name, + enum others_type type, + char *parent); + +void cleanup_node_of_others(struct others *others); + +bool compare_parent(const char *a, const char *b); + +void print_others(struct others *head); + +void cleanup_others(struct others *others); + +struct others *combine_others(struct others *head1, struct others *head2); + #define XSTREQ(x, y) (STREQ((char *)x, y)) #define STRPROP(d, p, n) (d->p = get_node_content(n))

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 80 ++++++++++++++++++++++++++++++++----------- 1 files changed, 59 insertions(+), 21 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 09dab97..d29a09a 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -454,7 +454,8 @@ static int parse_fs_device(xmlNode *dnode, struct virt_device **vdevs) { struct virt_device *vdev = NULL; struct disk_device *ddev = NULL; - xmlNode *child = NULL; + + CU_DEBUG("Enter parse_fs_device()."); vdev = calloc(1, sizeof(*vdev)); if (vdev == NULL) @@ -462,35 +463,72 @@ static int parse_fs_device(xmlNode *dnode, struct virt_device **vdevs) ddev = (&vdev->dev.disk); - ddev->type = get_attr_value(dnode, "type"); + ddev->others = parse_data_to_others(dnode, BAD_CAST "devices"); + if (ddev->others == NULL) { + CU_DEBUG("parse xml failed."); + goto err; + } + + /* fetch out <disk> tag from others. It will be removed + * after others management finished. */ + fetch_from_others(&ddev->others, + "filesystem", + TYPE_NODE, + "devices"); + + ddev->type = fetch_from_others(&ddev->others, + "type", + TYPE_PROP, + (char *)dnode->name); if (ddev->type == NULL) { CU_DEBUG("No type"); goto err; } - ddev->access_mode = get_attr_value(dnode, "accessmode"); + ddev->access_mode = fetch_from_others(&ddev->others, + "accessmode", + TYPE_PROP, + (char *)dnode->name); - for (child = dnode->children; child != NULL; child = child->next) { - if (XSTREQ(child->name, "source")) { - ddev->source = get_attr_value(child, "dir"); - if (ddev->source == NULL) { - CU_DEBUG("No source dir"); - goto err; - } - } else if (XSTREQ(child->name, "target")) { - ddev->virtual_dev = get_attr_value(child, "dir"); - if (ddev->virtual_dev == NULL) { - CU_DEBUG("No target dir"); - goto err; - } - } else if (XSTREQ(child->name, "driver")) { - ddev->driver_type = get_attr_value(child, "type"); + if (seek_in_others(&ddev->others, + "source", + TYPE_NODE, + (char *)dnode->name)) { + ddev->source = fetch_from_others(&ddev->others, + "dir", + TYPE_PROP, + "source"); + + + if (ddev->source == NULL) { + CU_DEBUG("no source dir"); + goto err; } } - if ((ddev->source == NULL) || (ddev->virtual_dev == NULL)) { - CU_DEBUG("S: %s D: %s", ddev->source, ddev->virtual_dev); - goto err; + if (seek_in_others(&ddev->others, + "target", + TYPE_NODE, + (char *)dnode->name)) { + ddev->virtual_dev = fetch_from_others(&ddev->others, + "dir", + TYPE_PROP, + "target"); + + if (ddev->virtual_dev == NULL) { + CU_DEBUG("no target dir"); + goto err; + } + } + + if (seek_in_others(&ddev->others, + "driver", + TYPE_NODE, + (char *)dnode->name)) { + ddev->driver_type = fetch_from_others(&ddev->others, + "type", + TYPE_PROP, + "driver"); } ddev->disk_type = DISK_FS; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 133 ++++++++++++++++++++++++++++++++++---------- 1 files changed, 103 insertions(+), 30 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index d29a09a..c818368 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -552,7 +552,8 @@ static int parse_block_device(xmlNode *dnode, struct virt_device **vdevs) { struct virt_device *vdev = NULL; struct disk_device *ddev = NULL; - xmlNode * child = NULL; + + CU_DEBUG("Enter parse_block_device()."); vdev = calloc(1, sizeof(*vdev)); if (vdev == NULL) @@ -560,45 +561,117 @@ static int parse_block_device(xmlNode *dnode, struct virt_device **vdevs) ddev = &(vdev->dev.disk); - ddev->type = get_attr_value(dnode, "type"); - if (ddev->type == NULL) + ddev->others = parse_data_to_others(dnode, BAD_CAST "devices"); + if (ddev->others == NULL) { + CU_DEBUG("xml file parse failed."); + goto err; + } + + /* fetch out <disk> tag from others. It will be removed + * after others management finished. */ + fetch_from_others(&ddev->others, + "disk", + TYPE_NODE, + "devices"); + + ddev->type = fetch_from_others(&ddev->others, + "type", + TYPE_PROP, + (char *)dnode->name); + if (ddev->type == NULL) { + CU_DEBUG("no type"); goto err; + } - ddev->device = get_attr_value(dnode, "device"); - if (ddev->device == NULL) + ddev->device = fetch_from_others(&ddev->others, + "device", + TYPE_PROP, + (char *)dnode->name); + if (ddev->device == NULL) { + CU_DEBUG("no device"); goto err; + } - for (child = dnode->children; child != NULL; child = child->next) { - if (XSTREQ(child->name, "driver")) { - ddev->driver = get_attr_value(child, "name"); - if (ddev->driver == NULL) + if (seek_in_others(&ddev->others, + "driver", + TYPE_NODE, + (char *)dnode->name)) { + ddev->driver = fetch_from_others(&ddev->others, + "name", + TYPE_PROP, + "driver"); + + if (ddev->driver == NULL) { + CU_DEBUG("no driver name"); + goto err; + } + + ddev->driver_type = fetch_from_others(&ddev->others, + "type", + TYPE_PROP, + "driver"); + + ddev->cache = fetch_from_others(&ddev->others, + "cache", + TYPE_PROP, + "driver"); + } + + if (seek_in_others(&ddev->others, + "source", + TYPE_NODE, + (char *)dnode->name)) { + ddev->source = fetch_from_others(&ddev->others, + "file", + TYPE_PROP, + "source"); + if (ddev->source == NULL) { + ddev->source = fetch_from_others(&ddev->others, + "dev", + TYPE_PROP, + "source"); + + if (ddev->source == NULL) { + CU_DEBUG("no source file/dev"); goto err; - ddev->driver_type = get_attr_value(child, "type"); - ddev->cache = get_attr_value(child, "cache"); - } else if (XSTREQ(child->name, "source")) { - ddev->source = get_attr_value(child, "file"); - if (ddev->source) { - ddev->disk_type = DISK_FILE; - continue; - } - ddev->source = get_attr_value(child, "dev"); - if (ddev->source) { - ddev->disk_type = DISK_PHY; - continue; + } else { + ddev->disk_type == DISK_PHY; } + } else { + ddev->disk_type = DISK_FILE; + } + } + + if (seek_in_others(&ddev->others, + "target", + TYPE_NODE, + (char *)dnode->name)) { + ddev->virtual_dev = fetch_from_others(&ddev->others, + "dev", + TYPE_PROP, + "target"); + + if (ddev->virtual_dev == NULL) { + CU_DEBUG("no target dev"); goto err; - } else if (XSTREQ(child->name, "target")) { - ddev->virtual_dev = get_attr_value(child, "dev"); - if (ddev->virtual_dev == NULL) - goto err; - ddev->bus_type = get_attr_value(child, "bus"); - } else if (XSTREQ(child->name, "readonly")) { - ddev->readonly = true; - } else if (XSTREQ(child->name, "shareable")) { - ddev->shareable = true; } + + ddev->bus_type = fetch_from_others(&ddev->others, + "bus", + TYPE_PROP, + "target"); } + ddev->readonly = seek_in_others(&ddev->others, + "readonly", + TYPE_NODE, + (char *)dnode->name); + + ddev->shareable = seek_in_others(&ddev->others, + "shareable", + TYPE_NODE, + (char *)dnode->name); + /* handle the situation that a cdrom device have no disk in it, no ISO file */ if ((XSTREQ(ddev->device, "cdrom")) && (ddev->source == NULL)) { ddev->source = strdup(""); -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 75 ++++++++++++++++++++++++++++++------------- 1 files changed, 52 insertions(+), 23 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index c818368..05da1b4 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -709,40 +709,69 @@ static int parse_disk_device(xmlNode *dnode, struct virt_device **vdevs) } } -static int parse_vsi_device(xmlNode *dnode, struct net_device *vdevs) +static int parse_vsi_device(struct others **others, struct net_device *vdevs) { struct vsi_device *vsi_dev = NULL; - xmlNode * child = NULL; + + CU_DEBUG("Enter parse_vsi_device()."); vsi_dev = calloc(1, sizeof(*vsi_dev)); - if (vsi_dev == NULL) + if (vsi_dev == NULL) { + CU_DEBUG("calloc failed."); goto err; + } - vsi_dev->vsi_type = get_attr_value(dnode, "type"); - if (vsi_dev->vsi_type == NULL) + vsi_dev->vsi_type = fetch_from_others(others, + "type", + TYPE_PROP, + "virtualport"); + if (vsi_dev->vsi_type == NULL) { + CU_DEBUG("no vsi type"); goto err; + } - for (child = dnode->children; child != NULL; child = child->next) { - if (XSTREQ(child->name, "parameters")) { - vsi_dev->manager_id = get_attr_value(child, - "managerid"); - if (vsi_dev->manager_id == NULL) - goto err; + if (seek_in_others(others, + "parameters", + TYPE_NODE, + "virtualport")) { + vsi_dev->manager_id = fetch_from_others(others, + "managerid", + TYPE_PROP, + "parameters"); + + if (vsi_dev->manager_id == NULL) { + CU_DEBUG("no managerid"); + goto err; + } - vsi_dev->type_id = get_attr_value(child, "typeid"); - if (vsi_dev->type_id == NULL) - goto err; + vsi_dev->type_id = fetch_from_others(others, + "typeid", + TYPE_PROP, + "parameters"); + if (vsi_dev->type_id == NULL) { + CU_DEBUG("no typeid"); + goto err; + } - vsi_dev->type_id_version = - get_attr_value(child, "typeidversion"); - if (vsi_dev->type_id_version == NULL) - goto err; + vsi_dev->type_id_version = fetch_from_others(others, + "typeidversion", + TYPE_PROP, + "parameters"); + + if (vsi_dev->type_id_version == NULL) { + CU_DEBUG("no typeidversion"); + goto err; + } + + vsi_dev->instance_id = fetch_from_others(others, + "instanceid", + TYPE_PROP, + "parameters"); - vsi_dev->instance_id = get_attr_value(child, - "instanceid"); - vsi_dev->profile_id = get_attr_value(child, - "profileid"); - } + vsi_dev->profile_id = fetch_from_others(others, + "profileid", + TYPE_PROP, + "parameters"); } memcpy(&(vdevs->vsi), vsi_dev, sizeof(*vsi_dev)); -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 220 +++++++++++++++++++++++++++++++------------- 1 files changed, 155 insertions(+), 65 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 05da1b4..d93ba7b 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -817,90 +817,180 @@ static int parse_net_device(xmlNode *inode, struct virt_device **vdevs) { struct virt_device *vdev = NULL; struct net_device *ndev = NULL; - xmlNode *child = NULL; + + CU_DEBUG("Enter parse_net_device()."); vdev = calloc(1, sizeof(*vdev)); - if (vdev == NULL) + if (vdev == NULL) { + CU_DEBUG("calloc failed."); goto err; + } ndev = &(vdev->dev.net); - ndev->type = get_attr_value(inode, "type"); - if (ndev->type == NULL) + ndev->others = parse_data_to_others(inode, BAD_CAST "devices"); + if (ndev->others == NULL) { + CU_DEBUG("parse xml data to others failed."); goto err; + } + + /* fetch out <interface> tag from others. It will be removed + * after others management finished. */ + fetch_from_others(&ndev->others, + "interface", + TYPE_NODE, + "devices"); + + ndev->type = fetch_from_others(&ndev->others, + "type", + TYPE_PROP, + (char *)inode->name); + + if (ndev->type == NULL) { + CU_DEBUG("no type"); + goto err; + } + + if (seek_in_others(&ndev->others, + "mac", + TYPE_NODE, + (char *)inode->name)) { + ndev->mac = fetch_from_others(&ndev->others, + "address", + TYPE_PROP, + "mac"); + + if (ndev->mac == NULL) { + CU_DEBUG("no mac address"); + goto err; + } + } + + if (seek_in_others(&ndev->others, + "source", + TYPE_NODE, + (char *)inode->name)) { + ndev->source = fetch_from_others(&ndev->others, + "bridge", + TYPE_PROP, + "source"); + + if (ndev->source == NULL) { + ndev->source = fetch_from_others(&ndev->others, + "network", + TYPE_PROP, + "source"); - for (child = inode->children; child != NULL; child = child->next) { - if (XSTREQ(child->name, "mac")) { - ndev->mac = get_attr_value(child, "address"); - if (ndev->mac == NULL) - goto err; - } else if (XSTREQ(child->name, "source")) { - ndev->source = get_attr_value(child, "bridge"); - if (ndev->source != NULL) - continue; - ndev->source = get_attr_value(child, "network"); if (ndev->source != NULL) { - int ret = asprintf(&ndev->poolid, + int ret = asprintf(&ndev->poolid, "NetworkPool/%s", ndev->source); + if (ret == -1) { - CU_DEBUG("Failed to get network" - " poolid"); + CU_DEBUG("Failed to get network poolid"); + goto err; + } + } else { + ndev->source = fetch_from_others(&ndev->others, + "dev", + TYPE_PROP, + "source"); + + ndev->net_mode = fetch_from_others(&ndev->others, + "mode", + TYPE_PROP, + "source"); + + if ((ndev->source == NULL) || (ndev->net_mode == NULL)) { + CU_DEBUG("source %s, mode %s", ndev->source, ndev->net_mode); + goto err; } - continue; + } - ndev->source = get_attr_value(child, "dev"); - ndev->net_mode = get_attr_value(child, "mode"); - if ((ndev->source != NULL) && (ndev->net_mode != NULL)) - continue; + } + } + + if (seek_in_others(&ndev->others, + "target", + TYPE_NODE, + (char *)inode->name)) { + ndev->device = fetch_from_others(&ndev->others, + "dev", + TYPE_PROP, + "target"); + + if (ndev->device == NULL) { + CU_DEBUG("no dev in target."); goto err; - } else if (XSTREQ(child->name, "target")) { - ndev->device = get_attr_value(child, "dev"); - if (ndev->device == NULL) - goto err; - } else if (XSTREQ(child->name, "model")) { - ndev->model = get_attr_value(child, "type"); - if (ndev->model == NULL) - goto err; - } else if (XSTREQ(child->name, "filterref")) { - ndev->filter_ref = get_attr_value(child, "filter"); - } else if (XSTREQ(child->name, "virtualport")) { - parse_vsi_device(child, ndev); + } + } + + if (seek_in_others(&ndev->others, + "model", + TYPE_NODE, + (char *)inode->name)) { + ndev->model = fetch_from_others(&ndev->others, + "type", + TYPE_PROP, + "model"); + if (ndev->model == NULL) { + CU_DEBUG("no model type."); + goto err; + } + } + + if (seek_in_others(&ndev->others, + "filterref", + TYPE_NODE, + (char *)inode->name)) { + ndev->filter_ref = fetch_from_others(&ndev->others, + "filter", + TYPE_PROP, + "filterref"); + } + + if (seek_in_others(&ndev->others, "virtualport", + TYPE_NODE, (char *)inode->name)) { + parse_vsi_device(&ndev->others, ndev); + } + #if LIBVIR_VERSION_NUMBER >= 9000 - } else if (XSTREQ(child->name, "bandwidth")) { - /* Network QoS bandwidth support */ - xmlNode *grandchild = NULL; - for (grandchild = child->children; - grandchild != NULL; - grandchild = grandchild->next) { - if (XSTREQ(grandchild->name, "inbound")) { - /* Only expose inbound bandwidth */ - char *val; - - val = get_attr_value(grandchild, - "average"); - if (val != NULL) { - sscanf(val, "%" PRIu64, - &ndev->reservation); - free(val); - } else - ndev->reservation = 0; - - val = get_attr_value(grandchild, - "peak"); - if (val != NULL) { - sscanf(val, "%" PRIu64, - &ndev->limit); - free(val); - } else - ndev->limit = 0; - break; - } - } + /* Network QoS bandwidth support */ + /* Only expose inbound bandwidth */ + char *val; + if (seek_in_others(&ndev->others, + "bandwidth", + TYPE_NODE, + (char *)inode->name) && + seek_in_others(&ndev->others, + "inbound", + TYPE_NODE, + "bandwidth")) { + val = fetch_from_others(&ndev->others, + "average", + TYPE_PROP, + "inbound"); + + if (val != NULL) { + sscanf(val, "%" PRIu64, &ndev->reservation); + free(val); + } else { + ndev->reservation = 0; } -#endif + val = fetch_from_others(&ndev->others, + "peak", + TYPE_PROP, + "inbound"); + + if (val != NULL) { + sscanf(val, "%" PRIu64, &ndev->limit); + free(val); + } else { + ndev->limit = 0; + } } +#endif if (ndev->source == NULL) CU_DEBUG("No network source defined, leaving blank\n"); -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 20 +++++++++++++++----- 1 files changed, 15 insertions(+), 5 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index d93ba7b..2b3ca81 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1014,7 +1014,21 @@ static int parse_vcpu_device(xmlNode *node, struct virt_device **vdevs) char *count_str; int count; - count_str = get_node_content(node); + CU_DEBUG("Enter parse_vcpu_device()."); + + list = calloc(1, sizeof(*list)); + if (list == NULL) { + CU_DEBUG("calloc failed."); + goto err; + } + + list->dev.vcpu.others = parse_data_to_others(node, BAD_CAST "domain"); + + count_str = fetch_from_others(&list->dev.vcpu.others, + "vcpu", + TYPE_NODE, + "domain"); + if (count_str == NULL) count = 1; /* Default to 1 VCPU if non specified */ else if (sscanf(count_str, "%i", &count) != 1) @@ -1022,10 +1036,6 @@ static int parse_vcpu_device(xmlNode *node, struct virt_device **vdevs) free(count_str); - list = calloc(1, sizeof(*list)); - if (list == NULL) - goto err; - list->dev.vcpu.quantity = count; list->type = CIM_RES_TYPE_PROC; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 18 +++++++++++++++--- 1 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 2b3ca81..a6857a2 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1055,15 +1055,27 @@ static int parse_emu_device(xmlNode *node, struct virt_device **vdevs) struct virt_device *vdev = NULL; struct emu_device *edev = NULL; + CU_DEBUG("Enter parse_emu_device()."); + vdev = calloc(1, sizeof(*vdev)); - if (vdev == NULL) + if (vdev == NULL) { + CU_DEBUG("calloc failed."); goto err; + } edev = &(vdev->dev.emu); - edev->path = get_node_content(node); - if (edev->path == NULL) + edev->others = parse_data_to_others(node, BAD_CAST "devices"); + + edev->path = fetch_from_others(&edev->others, + (char *)node->name, + TYPE_NODE, + "devices"); + + if (edev->path == NULL) { + CU_DEBUG("no path"); goto err; + } vdev->type = CIM_RES_TYPE_EMU; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 27 +++++++++++++++++++++++---- 1 files changed, 23 insertions(+), 4 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index a6857a2..d41ad53 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1094,19 +1094,38 @@ static int parse_mem_device(xmlNode *node, struct virt_device **vdevs) struct virt_device *vdev = NULL; struct mem_device *mdev = NULL; char *content = NULL; + struct others *new_others = NULL; + + CU_DEBUG("Enter parse_mem_device()."); vdev = calloc(1, sizeof(*vdev)); - if (vdev == NULL) + if (vdev == NULL) { + CU_DEBUG("calloc failed."); goto err; + } mdev = &(vdev->dev.mem); - content = get_node_content(node); + new_others = parse_data_to_others(node, BAD_CAST "domain"); + mdev->others = combine_others(mdev->others, new_others); + + if (XSTREQ(node->name, "currentMemory")) { + content = fetch_from_others(&mdev->others, + "currentMemory", + TYPE_NODE, + "domain"); - if (XSTREQ(node->name, "currentMemory")) sscanf(content, "%" PRIu64, &mdev->size); - else if (XSTREQ(node->name, "memory")) + } else if (XSTREQ(node->name, "memory")) { + content = fetch_from_others(&mdev->others, + "memory", + TYPE_NODE, + "domain"); + sscanf(content, "%" PRIu64, &mdev->maxsize); + } else { + /* do nothing */ + } free(content); -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 129 +++++++++++++++++++++++++++++++++----------- 1 files changed, 98 insertions(+), 31 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index d41ad53..c4e4ef7 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1140,43 +1140,85 @@ static int parse_mem_device(xmlNode *node, struct virt_device **vdevs) return 0; } -static char *get_attr_value_default(xmlNode *node, char *attrname, - const char *default_value) -{ - char *ret = get_attr_value(node, attrname); - - if (ret == NULL && default_value != NULL) - ret = strdup(default_value); - - return ret; -} - static int parse_graphics_device(xmlNode *node, struct virt_device **vdevs) { struct virt_device *vdev = NULL; struct graphics_device *gdev = NULL; - xmlNode *child = NULL; int ret; + CU_DEBUG("Enter parse_graphics_device()."); + vdev = calloc(1, sizeof(*vdev)); - if (vdev == NULL) + if (vdev == NULL) { + CU_DEBUG("calloc failed."); goto err; + } gdev = &(vdev->dev.graphics); - gdev->type = get_attr_value(node, "type"); - if (gdev->type == NULL) + gdev->others = parse_data_to_others(node, BAD_CAST "devices"); + if (gdev->others == NULL) { + CU_DEBUG("parse data to others failed."); + goto err; + } + + /* fetch out <graphics> tag from others. It will be removed + * after others management finished. */ + fetch_from_others(&gdev->others, + "graphics", + TYPE_NODE, + "devices"); + + fetch_from_others(&gdev->others, + "console", + TYPE_NODE, + "devices"); + + fetch_from_others(&gdev->others, + "serial", + TYPE_NODE, + "devices"); + + gdev->type = fetch_from_others(&gdev->others, + "type", + TYPE_PROP, + (char *)node->name); + + if (gdev->type == NULL) { + CU_DEBUG("no type"); goto err; + } CU_DEBUG("graphics device type = %s", gdev->type); if (STREQC(gdev->type, "vnc")) { - gdev->dev.vnc.port = get_attr_value_default(node, "port", - "-1"); - gdev->dev.vnc.host = get_attr_value_default(node, "listen", - "127.0.0.1"); - gdev->dev.vnc.keymap = get_attr_value(node, "keymap"); - gdev->dev.vnc.passwd = get_attr_value(node, "passwd"); + gdev->dev.vnc.port = fetch_from_others(&gdev->others, + "port", + TYPE_PROP, + (char *)node->name); + + if (gdev->dev.vnc.port == NULL) { + gdev->dev.vnc.port = strdup("-1"); + } + + gdev->dev.vnc.host = fetch_from_others(&gdev->others, + "listen", + TYPE_PROP, + (char *)node->name); + + if (gdev->dev.vnc.host == NULL) { + gdev->dev.vnc.host = strdup("127.0.0.1"); + } + + gdev->dev.vnc.keymap = fetch_from_others(&gdev->others, + "keymap", + TYPE_PROP, + (char *)node->name); + + gdev->dev.vnc.passwd = fetch_from_others(&gdev->others, + "passwd", + TYPE_PROP, + (char *)node->name); if (gdev->dev.vnc.port == NULL || gdev->dev.vnc.host == NULL) { CU_DEBUG("Error vnc port '%p' host '%p'", @@ -1185,25 +1227,50 @@ static int parse_graphics_device(xmlNode *node, struct virt_device **vdevs) } } else if (STREQC(gdev->type, "sdl")) { - gdev->dev.sdl.display = get_attr_value(node, "display"); - gdev->dev.sdl.xauth = get_attr_value(node, "xauth"); - gdev->dev.sdl.fullscreen = get_attr_value(node, "fullscreen"); + gdev->dev.sdl.display = fetch_from_others(&gdev->others, + "display", + TYPE_PROP, + (char *)node->name); + + gdev->dev.sdl.xauth = fetch_from_others(&gdev->others, + "xauth", + TYPE_PROP, + (char *)node->name); + + gdev->dev.sdl.fullscreen = fetch_from_others(&gdev->others, + "fullscreen", + TYPE_PROP, + (char *)node->name); } else if (STREQC(gdev->type, "pty")) { - if (node->name == NULL) + if (node->name == NULL) { + CU_DEBUG("no name"); goto err; + } /* Change type to serial, console, etc. It will be converted * back in xmlgen.c */ free(gdev->type); gdev->type = strdup((char *)node->name); - for (child = node->children; child != NULL; - child = child->next) { - if (XSTREQ(child->name, "source")) - gdev->dev.vnc.host = get_attr_value(child, "path"); - else if (XSTREQ(child->name, "target")) - gdev->dev.vnc.port = get_attr_value(child, "port"); + if (seek_in_others(&gdev->others, + "source", + TYPE_NODE, + (char *)node->name)) { + gdev->dev.vnc.host = fetch_from_others(&gdev->others, + "path", + TYPE_PROP, + "source"); + } + + if (seek_in_others(&gdev->others, + "target", + TYPE_NODE, + (char *)node->name)) { + gdev->dev.vnc.port = fetch_from_others(&gdev->others, + "port", + TYPE_PROP, + "target"); } } else { -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 31 ++++++++++++++++++++++++++++--- 1 files changed, 28 insertions(+), 3 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index c4e4ef7..15f9d99 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1306,14 +1306,39 @@ static int parse_input_device(xmlNode *node, struct virt_device **vdevs) struct input_device *idev = NULL; int ret; + CU_DEBUG("Enter parse_input_device()."); + vdev = calloc(1, sizeof(*vdev)); - if (vdev == NULL) + if (vdev == NULL) { + CU_DEBUG("calloc failed."); goto err; + } idev = &(vdev->dev.input); - idev->type = get_attr_value(node, "type"); - idev->bus = get_attr_value(node, "bus"); + idev->others = parse_data_to_others(node, BAD_CAST "devices"); + + if (idev->others == NULL) { + CU_DEBUG("parse data to others failed."); + goto err; + } + + /* fetch out <input> tag from others. It will be removed + * after others management finished. */ + fetch_from_others(&idev->others, + "input", + TYPE_NODE, + "devices"); + + idev->type = fetch_from_others(&idev->others, + "type", + TYPE_PROP, + (char *)node->name); + + idev->bus = fetch_from_others(&idev->others, + "bus", + TYPE_PROP, + (char *)node->name); if ((idev->type == NULL) || (idev->bus == NULL)) goto err; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 52 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 52 insertions(+), 0 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 15f9d99..37582da 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1361,6 +1361,58 @@ static int parse_input_device(xmlNode *node, struct virt_device **vdevs) return 0; } +static int parse_unknown_device(xmlNode *node, struct virt_device **vdevs) +{ + struct virt_device *vdev = NULL; + struct unknown_device *udev = NULL; + xmlNode *child = NULL; + + CU_DEBUG("Enter parse_unknown_device()."); + + vdev = calloc(1, sizeof(*vdev)); + if (vdev == NULL) { + CU_DEBUG("calloc failed."); + goto err; + } + + udev = &(vdev->dev.unknown); + + for (child = node->children; child != NULL; child = child->next) { + /* Skip all items parsed in other parse_*() functions. + * Everything here is just to be compatible with old versions. + * Here may need some improvement in the future. + */ + if (XSTREQ(child->name, "disk") || + XSTREQ(child->name, "filesystem") || + XSTREQ(child->name, "interface") || + XSTREQ(child->name, "emulator") || + XSTREQ(child->name, "graphics") || + XSTREQ(child->name, "console") || + XSTREQ(child->name, "serial") || + XSTREQ(child->name, "input")) { + /* Just skip them and do nothing */ + } else { + udev->others = parse_data_to_others(child, BAD_CAST "devices"); + } + } + + if (udev->others == NULL) { + CU_DEBUG("no others."); + goto err; + } + + udev->name = strdup("unknown"); + + *vdevs = vdev; + + return 1; +err: + cleanup_unknown_device(udev); + free(vdev); + + return 0; +} + static bool resize_devlist(struct virt_device **list, int newsize) { struct virt_device *_list; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 37582da..b8a0c73 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -43,6 +43,7 @@ #define GRAPHICS_XPATH (xmlChar *)"/domain/devices/graphics | "\ "/domain/devices/console | /domain/devices/serial" #define INPUT_XPATH (xmlChar *)"/domain/devices/input" +#define UNKNOWN_XPATH (xmlChar *)"/domain/devices" #define DEFAULT_BRIDGE "xenbr0" #define DEFAULT_NETWORK "default" @@ -1528,6 +1529,11 @@ static int parse_devices(const char *xml, struct virt_device **_list, int type) func = &parse_input_device; break; + case CIM_RES_TYPE_UNKNOWN: + xpathstr = UNKNOWN_XPATH; + func = &parse_unknown_device; + break; + default: CU_DEBUG("Unrecognized device type. Returning."); goto err1; @@ -1932,6 +1938,10 @@ int get_dominfo_from_xml(const char *xml, struct domain **dominfo) &(*dominfo)->dev_vcpu, CIM_RES_TYPE_PROC); + (*dominfo)->dev_unknown_ct = parse_devices(xml, + &(*dominfo)->dev_unknown, + CIM_RES_TYPE_UNKNOWN); + return ret; err: -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 135 +++++++++++++++++++++++++++++++++++-------- 1 files changed, 110 insertions(+), 25 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index b8a0c73..b345db2 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1826,10 +1826,8 @@ static int parse_features(struct domain *dominfo, xmlNode *features) return 1; } -static void set_action(int *val, xmlNode *child) +static void set_action(int *val, const char *action) { - const char *action = (char *)xmlNodeGetContent(child); - if (action == NULL) *val = CIM_VSSD_RECOVERY_NONE; else if (STREQ(action, "destroy")) @@ -1846,30 +1844,117 @@ static int parse_domain(xmlNodeSet *nsv, struct domain *dominfo) { xmlNode **nodes = nsv->nodeTab; xmlNode *child; + xmlAttrPtr xmlAttr = NULL; + struct others *new_others = NULL; + char *action = NULL; + + CU_DEBUG("Enter parse_domain()"); + + /* parsing attributions of domain into others */ + xmlAttr = nodes[0]->properties; + while(xmlAttr) { + dominfo->others = add_others(dominfo->others, + nodes[0], + xmlAttr->name, + TYPE_PROP, + nodes[0]->name); + xmlAttr = xmlAttr->next; + } + + dominfo->typestr = fetch_from_others(&dominfo->others, + "type", + TYPE_PROP, + (char *)nodes[0]->name); + + /* parse every item in the field of domain and skip some will be parsed + * in other functions. The white list contains: + * <memory> (parsed in parse_mem_device()) + * <currentMemory> (parsed in parse_mem_device()) + * <vcpu> (parsed in parse_vcpu_device()) + * <devices> (parsed in other parse_*_device()) + */ + for (child = nodes[0]->children; child != NULL; child = child->next) { + if (XSTREQ(child->name, "memory") || + XSTREQ(child->name, "currentMemory") || + XSTREQ(child->name, "vcpu") || + XSTREQ(child->name, "devices")) { + continue; + } else { + new_others = parse_data_to_others(child, nodes[0]->name); + dominfo->others = combine_others(dominfo->others, + new_others); + } + } - dominfo->typestr = get_attr_value(nodes[0], "type"); + dominfo->name = fetch_from_others(&dominfo->others, + "name", + TYPE_NODE, + (char *)nodes[0]->name); - for (child = nodes[0]->children; child != NULL; child = child->next) { - if (XSTREQ(child->name, "name")) - STRPROP(dominfo, name, child); - else if (XSTREQ(child->name, "uuid")) - STRPROP(dominfo, uuid, child); - else if (XSTREQ(child->name, "bootloader")) - STRPROP(dominfo, bootloader, child); - else if (XSTREQ(child->name, "bootloader_args")) - STRPROP(dominfo, bootloader_args, child); - else if (XSTREQ(child->name, "os")) - parse_os(dominfo, child); - else if (XSTREQ(child->name, "on_poweroff")) - set_action(&dominfo->on_poweroff, child); - else if (XSTREQ(child->name, "on_reboot")) - set_action(&dominfo->on_reboot, child); - else if (XSTREQ(child->name, "on_crash")) - set_action(&dominfo->on_crash, child); - else if (XSTREQ(child->name, "clock")) - dominfo->clock = get_attr_value(child, "offset"); - else if (XSTREQ(child->name, "features")) - parse_features(dominfo, child); + dominfo->uuid = fetch_from_others(&dominfo->others, + "uuid", + TYPE_NODE, + (char *)nodes[0]->name); + + dominfo->bootloader = fetch_from_others(&dominfo->others, + "bootloader", + TYPE_NODE, + (char *)nodes[0]->name); + + dominfo->bootloader_args = fetch_from_others(&dominfo->others, + "bootloader_args", + TYPE_NODE, + (char *)nodes[0]->name); + + if (seek_in_others(&dominfo->others, + "os", + TYPE_NODE, + (char *)nodes[0]->name)) { + /* parse_os(); */ + } + + action = fetch_from_others(&dominfo->others, + "on_poweroff", + TYPE_NODE, + (char *)nodes[0]->name); + if (action) { + set_action(&dominfo->on_poweroff, action); + free(action); + } + + action = fetch_from_others(&dominfo->others, + "on_reboot", + TYPE_NODE, + (char *)nodes[0]->name); + if (action) { + set_action(&dominfo->on_reboot, action); + free(action); + } + + action = fetch_from_others(&dominfo->others, + "on_crash", + TYPE_NODE, + (char *)nodes[0]->name); + if (action) { + set_action(&dominfo->on_crash, action); + free(action); + } + + if (seek_in_others(&dominfo->others, + "clock", + TYPE_NODE, + (char *)nodes[0]->name)) { + dominfo->clock = fetch_from_others(&dominfo->others, + "offset", + TYPE_PROP, + "clock"); + } + + if (seek_in_others(&dominfo->others, + "features", + TYPE_NODE, + (char *)nodes[0]->name)) { + /* parse_features(); */ } return 1; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 87 ++++++++++++++++++++++++++++---------------- 1 files changed, 55 insertions(+), 32 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index b345db2..3412b5b 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1745,43 +1745,66 @@ int parse_fq_devid(const char *devid, char **host, char **device) return 1; } -static int parse_os(struct domain *dominfo, xmlNode *os) +static int parse_os(struct domain *dominfo) { - xmlNode *child; char **blist = NULL; unsigned bl_size = 0; - for (child = os->children; child != NULL; child = child->next) { - if (XSTREQ(child->name, "type")) - STRPROP(dominfo, os_info.pv.type, child); - else if (XSTREQ(child->name, "kernel")) - STRPROP(dominfo, os_info.pv.kernel, child); - else if (XSTREQ(child->name, "initrd")) - STRPROP(dominfo, os_info.pv.initrd, child); - else if (XSTREQ(child->name, "cmdline")) - 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")) { - char **tmp_list = NULL; - - tmp_list = (char **)realloc(blist, - (bl_size + 1) * - sizeof(char *)); - if (tmp_list == NULL) { - // Nothing you can do. Just go on. - CU_DEBUG("Could not alloc space for " - "boot device"); - continue; - } - blist = tmp_list; - - blist[bl_size] = get_attr_value(child, "dev"); - bl_size++; - } else if (XSTREQ(child->name, "init")) - STRPROP(dominfo, os_info.lxc.init, child); + CU_DEBUG("Enter parse_os()"); + + dominfo->os_info.pv.type = fetch_from_others(&dominfo->others, + "type", + TYPE_NODE, + "os"); + + dominfo->os_info.pv.kernel = fetch_from_others(&dominfo->others, + "kernel", + TYPE_NODE, + "os"); + + dominfo->os_info.pv.initrd = fetch_from_others(&dominfo->others, + "initrd", + TYPE_NODE, + "os"); + + dominfo->os_info.pv.cmdline = fetch_from_others(&dominfo->others, + "cmdline", + TYPE_NODE, + "os"); + + dominfo->os_info.fv.loader = fetch_from_others(&dominfo->others, + "loader", + TYPE_NODE, + "os"); + + if (seek_in_others(&dominfo->others, + "boot", + TYPE_NODE, + "os")) { + char **tmp_list = NULL; + + tmp_list = (char **)realloc(blist, + (bl_size + 1) * sizeof(char *)); + + if (tmp_list == NULL) { + /* Nothing you can do. Just go on. */ + CU_DEBUG("Could not alloc space for " + "boot device"); + } else { + blist = tmp_list; + blist[bl_size] = fetch_from_others(&dominfo->others, + "dev", + TYPE_PROP, + "boot"); + bl_size++; + } } + dominfo->os_info.lxc.init = fetch_from_others(&dominfo->others, + "init", + TYPE_NODE, + "os"); + if ((STREQC(dominfo->os_info.fv.type, "hvm")) && (STREQC(dominfo->typestr, "xen"))) dominfo->type = DOMAIN_XENFV; @@ -1910,7 +1933,7 @@ static int parse_domain(xmlNodeSet *nsv, struct domain *dominfo) "os", TYPE_NODE, (char *)nodes[0]->name)) { - /* parse_os(); */ + parse_os(dominfo); } action = fetch_from_others(&dominfo->others, -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 32 ++++++++++++++++++++++---------- 1 files changed, 22 insertions(+), 10 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 3412b5b..e0d11e4 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1833,17 +1833,29 @@ static int parse_os(struct domain *dominfo) return 1; } -static int parse_features(struct domain *dominfo, xmlNode *features) +static int parse_features(struct domain *dominfo) { - xmlNode *child; + CU_DEBUG("Enter parse_features()"); + + if (seek_in_others(&dominfo->others, + "acpi", + TYPE_NODE, + "features")) { + dominfo->acpi = true; + } - for (child = features->children; child != NULL; child = child->next) { - if (XSTREQ(child->name, "acpi")) - dominfo->acpi = true; - else if (XSTREQ(child->name, "apic")) - dominfo->apic = true; - else if (XSTREQ(child->name, "pae")) - dominfo->pae = true; + if (seek_in_others(&dominfo->others, + "apic", + TYPE_NODE, + "features")) { + dominfo->apic = true; + } + + if (seek_in_others(&dominfo->others, + "pae", + TYPE_NODE, + "features")) { + dominfo->pae = true; } return 1; @@ -1977,7 +1989,7 @@ static int parse_domain(xmlNodeSet *nsv, struct domain *dominfo) "features", TYPE_NODE, (char *)nodes[0]->name)) { - /* parse_features(); */ + parse_features(dominfo); } return 1; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 49 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 49 insertions(+), 0 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index e0d11e4..9eabd48 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1569,6 +1569,48 @@ static int parse_devices(const char *xml, struct virt_device **_list, int type) (d)->f = strdup((s)->f); \ } while (0); +static struct others *dup_others(struct others *others) +{ + struct others *new_node = NULL; + struct others *head = NULL; + + if (others == NULL) { + return NULL; + } + + while (others) { + new_node = calloc(1, sizeof(*new_node)); + if (new_node == NULL) { + CU_DEBUG("calloc failed."); + goto err; + } + + new_node->name = NULL; + new_node->value = NULL; + new_node->parent = NULL; + new_node->next = NULL; + + if (head == NULL) { + head = new_node; + } else { + new_node->next = head; + head = new_node; + } + + DUP_FIELD(new_node, others, name); + DUP_FIELD(new_node, others, value); + DUP_FIELD(new_node, others, parent); + new_node->type = others->type; + + others = others->next; + } + + return head; +err: + cleanup_others(head); + return NULL; +} + struct virt_device *virt_device_dup(struct virt_device *_dev) { struct virt_device *dev; @@ -1598,6 +1640,7 @@ struct virt_device *virt_device_dup(struct virt_device *_dev) DUP_FIELD(dev, _dev, dev.net.vsi.profile_id); dev->dev.net.reservation = _dev->dev.net.reservation; dev->dev.net.limit = _dev->dev.net.limit; + dev->dev.net.others = dup_others(_dev->dev.net.others); } else if (dev->type == CIM_RES_TYPE_DISK) { DUP_FIELD(dev, _dev, dev.disk.type); DUP_FIELD(dev, _dev, dev.disk.device); @@ -1611,22 +1654,28 @@ struct virt_device *virt_device_dup(struct virt_device *_dev) dev->dev.disk.disk_type = _dev->dev.disk.disk_type; dev->dev.disk.readonly = _dev->dev.disk.readonly; dev->dev.disk.shareable = _dev->dev.disk.shareable; + dev->dev.disk.others = dup_others(_dev->dev.disk.others); } else if (dev->type == CIM_RES_TYPE_MEM) { dev->dev.mem.size = _dev->dev.mem.size; dev->dev.mem.maxsize = _dev->dev.mem.maxsize; + dev->dev.mem.others = dup_others(_dev->dev.mem.others); } else if (dev->type == CIM_RES_TYPE_PROC) { dev->dev.vcpu.quantity = _dev->dev.vcpu.quantity; + dev->dev.vcpu.others = dup_others(_dev->dev.vcpu.others); } else if (dev->type == CIM_RES_TYPE_EMU) { DUP_FIELD(dev, _dev, dev.emu.path); + dev->dev.emu.others = dup_others(_dev->dev.emu.others); } else if (dev->type == CIM_RES_TYPE_GRAPHICS) { DUP_FIELD(dev, _dev, dev.graphics.type); DUP_FIELD(dev, _dev, dev.graphics.dev.vnc.host); DUP_FIELD(dev, _dev, dev.graphics.dev.vnc.port); DUP_FIELD(dev, _dev, dev.graphics.dev.vnc.keymap); DUP_FIELD(dev, _dev, dev.graphics.dev.vnc.passwd); + dev->dev.graphics.others = dup_others(_dev->dev.graphics.others); } else if (dev->type == CIM_RES_TYPE_INPUT) { DUP_FIELD(dev, _dev, dev.input.type); DUP_FIELD(dev, _dev, dev.input.bus); + dev->dev.input.others = dup_others(_dev->dev.input.others); } return dev; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- src/Virt_VirtualSystemManagementService.c | 2 +- src/svpc_types.h | 1 + 2 files changed, 2 insertions(+), 1 deletions(-) diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c index 8ced2d6..bfb1654 100644 --- a/src/Virt_VirtualSystemManagementService.c +++ b/src/Virt_VirtualSystemManagementService.c @@ -2678,7 +2678,7 @@ static CMPIStatus resource_del(struct domain *dominfo, CLASSNAME(op)); } - dev->type = CIM_RES_TYPE_UNKNOWN; + dev->type = CIM_RES_TYPE_DELETED; break; } diff --git a/src/svpc_types.h b/src/svpc_types.h index 99dd56f..fe4cc93 100644 --- a/src/svpc_types.h +++ b/src/svpc_types.h @@ -32,6 +32,7 @@ #define CIM_RES_TYPE_EMU 1 #define CIM_RES_TYPE_GRAPHICS 24 #define CIM_RES_TYPE_INPUT 13 +#define CIM_RES_TYPE_DELETED 999 #define CIM_RES_TYPE_UNKNOWN 1000 #define CIM_RES_TYPE_IMAGE 32768 -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 133 insertions(+), 0 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 4287d42..72a0904 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -42,6 +42,139 @@ typedef const char *(*devfn_t)(xmlNodePtr node, struct domain *dominfo); typedef const char *(*poolfn_t)(xmlNodePtr node, struct virt_pool *pool); typedef const char *(*resfn_t)(xmlNodePtr node, struct virt_pool_res *res); +static struct others *props_to_xml(xmlNodePtr node, + struct others *head, + const char *parent) +{ + struct others *tmp = head; + struct others *last = NULL; + struct others *del = NULL; + + if (head == NULL) { + CU_DEBUG("others is null."); + goto out; + } + + while (tmp) { + if (compare_parent(tmp->parent, parent) && + tmp->type == TYPE_PROP) { + xmlNewProp(node, BAD_CAST tmp->name, BAD_CAST tmp->value); + if (tmp == head) { + head = head->next; + } else { + last->next = tmp->next; + } + + del = tmp; + tmp = tmp->next; + cleanup_node_of_others(del); + } else { + last = tmp; + tmp = tmp->next; + } + } + +out: + return head; +} + +static struct others *others_to_xml(xmlNodePtr root, + struct others *head, + const char *parent) +{ + struct others *tmp = head; + struct others *last = NULL; + xmlNodePtr new_node = NULL; + + if (head == NULL) { + CU_DEBUG("others is null."); + goto out; + } + + /* fetch all node items from others to build structure of xml */ + while (tmp) { + if (compare_parent(tmp->parent, parent) && + tmp->type == TYPE_NODE) { + new_node = xmlNewChild(root, NULL, + BAD_CAST tmp->name, + BAD_CAST tmp->value); + + if (new_node == NULL) { + CU_DEBUG("xmlNewChild failed."); + goto out; + } + + if (tmp == head) { + head = head->next; + } else { + last->next = tmp->next; + } + + cleanup_node_of_others(tmp); + + /* find all properties of this node and build new tag in xml */ + head = props_to_xml(new_node, + head, + (char *)new_node->name); + + /* recursive build sub node of tmp */ + head = others_to_xml(new_node, + head, + (char *)new_node->name); + tmp = head; + } else { + last = tmp; + tmp = tmp->next; + } + } + +out: + return head; +} + +static struct others *add_node_to_others(struct others *head, + const char *name, + const char *value, + enum others_type type, + const char *parent) +{ + struct others *new_node = NULL; + + new_node = calloc(1, sizeof(*new_node)); + if (new_node == NULL) { + CU_DEBUG("calloc failed."); + return NULL; + } + + if (name == NULL) { + CU_DEBUG("name is null"); + return NULL; + } + new_node->name = strdup(name); + + if (value) { + new_node->value = strdup(value); + } else { + new_node->value = NULL; + } + + new_node->type = type; + + if (parent) { + new_node->parent = strdup(parent); + } else { + new_node->parent = NULL; + } + + if (head == NULL) { + new_node->next = NULL; + } else { + new_node->next = head; + } + + return new_node; +} + static char *disk_block_xml(xmlNodePtr root, struct disk_device *dev) { xmlNodePtr disk; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 141 +++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 113 insertions(+), 28 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 72a0904..60aa9c3 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -177,47 +177,132 @@ static struct others *add_node_to_others(struct others *head, static char *disk_block_xml(xmlNodePtr root, struct disk_device *dev) { - xmlNodePtr disk; - xmlNodePtr tmp; + CU_DEBUG("Enter disk_block_xml()"); - disk = xmlNewChild(root, NULL, BAD_CAST "disk", NULL); - if (disk == NULL) + dev->others = add_node_to_others(dev->others, + "disk", + NULL, + TYPE_NODE, + "devices"); + + if (dev->others == NULL) { + CU_DEBUG("Add tag <disk> failed."); return XML_ERROR; - xmlNewProp(disk, BAD_CAST "type", BAD_CAST "block"); - if (dev->device) - xmlNewProp(disk, BAD_CAST "device", BAD_CAST dev->device); + } + + dev->others = add_node_to_others(dev->others, + "type", + "block", + TYPE_PROP, + "disk"); + + if (dev->device) { + dev->others = add_node_to_others(dev->others, + "device", + dev->device, + TYPE_PROP, + "disk"); + } if (dev->driver) { - tmp = xmlNewChild(disk, NULL, BAD_CAST "driver", NULL); - if (tmp == NULL) + dev->others = add_node_to_others(dev->others, + "driver", + NULL, + TYPE_NODE, + "disk"); + + if (dev->others == NULL) { + CU_DEBUG("add tag <driver> failed."); return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "name", BAD_CAST dev->driver); - if (dev->driver_type) - xmlNewProp(tmp, BAD_CAST "type", - BAD_CAST dev->driver_type); - if (dev->cache) - xmlNewProp(tmp, BAD_CAST "cache", BAD_CAST dev->cache); + } + + dev->others = add_node_to_others(dev->others, + "name", + dev->driver, + TYPE_PROP, + "driver"); + + if (dev->driver_type) { + dev->others = add_node_to_others(dev->others, + "type", + dev->driver_type, + TYPE_PROP, + "driver"); + } + + if (dev->cache) { + dev->others = add_node_to_others(dev->others, + "cache", + dev->cache, + TYPE_PROP, + "driver"); + } } if ((dev->source != NULL) && (!XSTREQ(dev->source, "/dev/null"))) { - tmp = xmlNewChild(disk, NULL, BAD_CAST "source", NULL); - if (tmp == NULL) - return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "dev", BAD_CAST dev->source); + dev->others = add_node_to_others(dev->others, + "source", + NULL, + TYPE_NODE, + "disk"); + + if (dev->others == NULL) { + CU_DEBUG("add tag <source> failed."); + return XML_ERROR; + } + + dev->others = add_node_to_others(dev->others, + "dev", + dev->source, + TYPE_PROP, + "source"); } - tmp = xmlNewChild(disk, NULL, BAD_CAST "target", NULL); - if (tmp == NULL) + dev->others = add_node_to_others(dev->others, + "target", + NULL, + TYPE_NODE, + "disk"); + + if (dev->others == NULL) { + CU_DEBUG("add tag <target> failed."); return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "dev", BAD_CAST dev->virtual_dev); - if (dev->bus_type) - xmlNewProp(tmp, BAD_CAST "bus", BAD_CAST dev->bus_type); + } - if (dev->readonly) - xmlNewChild(disk, NULL, BAD_CAST "readonly", NULL); + dev->others = add_node_to_others(dev->others, + "dev", + dev->virtual_dev, + TYPE_PROP, + "target"); + + if (dev->bus_type) { + dev->others = add_node_to_others(dev->others, + "bus", + dev->bus_type, + TYPE_PROP, + "target"); + } - if (dev->shareable) - xmlNewChild(disk, NULL, BAD_CAST "shareable", NULL); + if (dev->readonly) { + dev->others = add_node_to_others(dev->others, + "readonly", + NULL, + TYPE_NODE, + "disk"); + } + + if (dev->shareable) { + dev->others = add_node_to_others(dev->others, + "shareable", + NULL, + TYPE_NODE, + "disk"); + } + + dev->others = others_to_xml(root, dev->others, "devices"); + if (dev->others) { + CU_DEBUG("others_to_xml error."); + } return NULL; } -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 137 +++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 110 insertions(+), 27 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 60aa9c3..5c151d3 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -309,26 +309,66 @@ static char *disk_block_xml(xmlNodePtr root, struct disk_device *dev) static const char *disk_file_xml(xmlNodePtr root, struct disk_device *dev) { - xmlNodePtr disk; - xmlNodePtr tmp; + CU_DEBUG("Enter disk_file_xml()"); - disk = xmlNewChild(root, NULL, BAD_CAST "disk", NULL); - if (disk == NULL) + dev->others = add_node_to_others(dev->others, + "disk", + NULL, + TYPE_NODE, + "devices"); + + if (dev->others == NULL) { + CU_DEBUG("add tag <disk> failed."); return XML_ERROR; - xmlNewProp(disk, BAD_CAST "type", BAD_CAST "file"); - if (dev->device) - xmlNewProp(disk, BAD_CAST "device", BAD_CAST dev->device); + } + + dev->others = add_node_to_others(dev->others, + "type", + "file", + TYPE_PROP, + "disk"); + + if (dev->device) { + dev->others = add_node_to_others(dev->others, + "device", + dev->device, + TYPE_PROP, + "disk"); + } if (dev->driver) { - tmp = xmlNewChild(disk, NULL, BAD_CAST "driver", NULL); - if (tmp == NULL) + dev->others = add_node_to_others(dev->others, + "driver", + NULL, + TYPE_NODE, + "disk"); + + if (dev->others == NULL) { + CU_DEBUG("add node <driver> failed."); return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "name", BAD_CAST dev->driver); - if (dev->driver_type) - xmlNewProp(tmp, BAD_CAST "type", - BAD_CAST dev->driver_type); - if (dev->cache) - xmlNewProp(tmp, BAD_CAST "cache", BAD_CAST dev->cache); + } + + dev->others = add_node_to_others(dev->others, + "name", + dev->driver, + TYPE_PROP, + "driver"); + + if (dev->driver_type) { + dev->others = add_node_to_others(dev->others, + "type", + dev->driver_type, + TYPE_PROP, + "driver"); + } + + if (dev->cache) { + dev->others = add_node_to_others(dev->others, + "cache", + dev->cache, + TYPE_PROP, + "driver"); + } } if (dev->device != NULL && XSTREQ(dev->device, "cdrom") && @@ -338,26 +378,69 @@ static const char *disk_file_xml(xmlNodePtr root, struct disk_device *dev) xml defination for libvirt should not have this defined in this situation. */ } else { - tmp = xmlNewChild(disk, NULL, BAD_CAST "source", NULL); - if (tmp == NULL) + dev->others = add_node_to_others(dev->others, + "source", + NULL, + TYPE_NODE, + "disk"); + + if (dev->others == NULL) { + CU_DEBUG("add node <source> failed."); return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "file", BAD_CAST dev->source); + } + + dev->others = add_node_to_others(dev->others, + "file", + dev->source, + TYPE_PROP, + "source"); } - tmp = xmlNewChild(disk, NULL, BAD_CAST "target", NULL); - if (tmp == NULL) + dev->others = add_node_to_others(dev->others, + "target", + NULL, + TYPE_NODE, + "disk"); + + if (dev->others == NULL) { + CU_DEBUG("add node <target> failed."); return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "dev", BAD_CAST dev->virtual_dev); - if (dev->bus_type) - xmlNewProp(tmp, BAD_CAST "bus", BAD_CAST dev->bus_type); + } + + dev->others = add_node_to_others(dev->others, + "dev", + dev->virtual_dev, + TYPE_PROP, + "target"); + if (dev->bus_type) { + dev->others = add_node_to_others(dev->others, + "bus", + dev->bus_type, + TYPE_PROP, + "target"); + } - if (dev->readonly) - xmlNewChild(disk, NULL, BAD_CAST "readonly", NULL); + if (dev->readonly) { + dev->others = add_node_to_others(dev->others, + "readonly", + NULL, + TYPE_NODE, + "disk"); + } - if (dev->shareable) - xmlNewChild(disk, NULL, BAD_CAST "shareable", NULL); + if (dev->shareable) { + dev->others = add_node_to_others(dev->others, + "shareable", + NULL, + TYPE_NODE, + "disk"); + } + dev->others = others_to_xml(root, dev->others, "devices"); + if (dev->others) { + CU_DEBUG("others_to_xml error."); + } return NULL; } -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 79 +++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 66 insertions(+), 13 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 5c151d3..c621b72 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -447,12 +447,18 @@ static const char *disk_file_xml(xmlNodePtr root, struct disk_device *dev) static const char *disk_fs_xml(xmlNodePtr root, struct disk_device *dev) { - xmlNodePtr fs; - xmlNodePtr tmp; + CU_DEBUG("Enter disk_fs_xml()"); - fs = xmlNewChild(root, NULL, BAD_CAST "filesystem", NULL); - if (fs == NULL) + dev->others = add_node_to_others(dev->others, + "filesystem", + NULL, + TYPE_NODE, + "devices"); + + if (dev->others == NULL) { + CU_DEBUG("add node <filesystem> failed."); return XML_ERROR; + } /* filesystem prop 'type' not needed to be generated, as it defaults to 'mount' in libvirt, the only supported value for now. */ @@ -461,23 +467,70 @@ static const char *disk_fs_xml(xmlNodePtr root, struct disk_device *dev) So generate here if specified by user, else leave it to libvirt. */ if (dev->access_mode) { - xmlNewProp(fs, BAD_CAST "accessmode", BAD_CAST dev->access_mode); + dev->others = add_node_to_others(dev->others, + "accessmode", + dev->access_mode, + TYPE_PROP, + "filesystem"); } if(dev->driver_type) { - tmp = xmlNewChild(fs, NULL, BAD_CAST "driver", NULL); - xmlNewProp(tmp, BAD_CAST "type", BAD_CAST dev->driver_type); + dev->others = add_node_to_others(dev->others, + "driver", + NULL, + TYPE_NODE, + "filesystem"); + + if (dev->others == NULL) { + CU_DEBUG("add node <driver> failed."); + return XML_ERROR; + } + + dev->others = add_node_to_others(dev->others, + "type", + dev->driver_type, + TYPE_PROP, + "driver"); } - tmp = xmlNewChild(fs, NULL, BAD_CAST "source", NULL); - if (tmp == NULL) + dev->others = add_node_to_others(dev->others, + "source", + NULL, + TYPE_NODE, + "filesystem"); + + if (dev->others == NULL) { + CU_DEBUG("add node <source> failed."); return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "dir", BAD_CAST dev->source); + } - tmp = xmlNewChild(fs, NULL, BAD_CAST "target", NULL); - if (tmp == NULL) + dev->others = add_node_to_others(dev->others, + "dir", + dev->source, + TYPE_PROP, + "source"); + + dev->others = add_node_to_others(dev->others, + "target", + NULL, + TYPE_NODE, + "filesystem"); + + if (dev->others == NULL) { + CU_DEBUG("add node <target> failed."); return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "dir", BAD_CAST dev->virtual_dev); + } + + dev->others = add_node_to_others(dev->others, + "dir", + dev->virtual_dev, + TYPE_PROP, + "target"); + + dev->others = others_to_xml(root, dev->others, "devices"); + if (dev->others) { + CU_DEBUG("others_to_xml failed."); + } return NULL; } -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 89 +++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 67 insertions(+), 22 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index c621b72..ad158ee 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -565,35 +565,80 @@ static const char *disk_xml(xmlNodePtr root, struct domain *dominfo) return msg; } -static const char *set_net_vsi(xmlNodePtr nic, struct vsi_device *dev) +static const char *set_net_vsi(const char *root, + struct vsi_device *dev, + struct others **others) { - xmlNodePtr tmp; + CU_DEBUG("Enter set_net_vsi()"); - tmp = xmlNewChild(nic, NULL, BAD_CAST "virtualport", NULL); - if (tmp == NULL) + *others = add_node_to_others(*others, + "virtualport", + NULL, + TYPE_NODE, + root); + + if (*others == NULL) { + CU_DEBUG("add node <virtualport> failed."); return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "type", BAD_CAST dev->vsi_type); + } - tmp = xmlNewChild(tmp, NULL, BAD_CAST "parameters", NULL); - if (tmp == NULL) + *others = add_node_to_others(*others, + "type", + dev->vsi_type, + TYPE_PROP, + "virtualport"); + + *others = add_node_to_others(*others, + "parameters", + NULL, + TYPE_NODE, + "virtualport"); + + if (*others == NULL) { + CU_DEBUG("add node <parameters> failed."); return XML_ERROR; + } + if (STREQ(dev->vsi_type, "802.1Qbh")) { - if (dev->profile_id != NULL) - xmlNewProp(tmp, BAD_CAST "profileid", - BAD_CAST dev->profile_id); + if (dev->profile_id != NULL) { + *others = add_node_to_others(*others, + "profileid", + dev->profile_id, + TYPE_PROP, + "parameters"); + } } else { - if (dev->manager_id != NULL) - xmlNewProp(tmp, BAD_CAST "managerid", - BAD_CAST dev->manager_id); - if (dev->type_id != NULL) - xmlNewProp(tmp, BAD_CAST "typeid", - BAD_CAST dev->type_id); - if (dev->type_id_version != NULL) - xmlNewProp(tmp, BAD_CAST "typeidversion", - BAD_CAST dev->type_id_version); - if (dev->instance_id != NULL) - xmlNewProp(tmp, BAD_CAST "instanceid", - BAD_CAST dev->instance_id); + if (dev->manager_id != NULL) { + *others = add_node_to_others(*others, + "managerid", + dev->manager_id, + TYPE_PROP, + "parameters"); + } + + if (dev->type_id != NULL) { + *others = add_node_to_others(*others, + "typeid", + dev->type_id, + TYPE_PROP, + "parameters"); + } + + if (dev->type_id_version != NULL) { + *others = add_node_to_others(*others, + "typeidversion", + dev->type_id_version, + TYPE_PROP, + "parameters"); + } + + if (dev->instance_id != NULL) { + *others = add_node_to_others(*others, + "instanceid", + dev->instance_id, + TYPE_PROP, + "parameters"); + } } return NULL; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 49 ++++++++++++++++++++++++++++++++++++------------- 1 files changed, 36 insertions(+), 13 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index ad158ee..859cc21 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -644,26 +644,49 @@ static const char *set_net_vsi(const char *root, return NULL; } -static const char *set_net_source(xmlNodePtr nic, +static const char *set_net_source(const char *root, struct net_device *dev, - const char *src_type) + const char *src_type, + struct others **others) { - xmlNodePtr tmp; + CU_DEBUG("Enter set_net_source()"); if (dev->source != NULL) { - tmp = xmlNewChild(nic, NULL, BAD_CAST "source", NULL); - if (tmp == NULL) + *others = add_node_to_others(*others, + "source", + NULL, + TYPE_NODE, + root); + + if (*others == NULL) { + CU_DEBUG("add node <source> failed."); return XML_ERROR; + } + if (STREQ(src_type, "direct")) { - xmlNewProp(tmp, BAD_CAST "dev", BAD_CAST dev->source); - if (dev->net_mode != NULL) - xmlNewProp(tmp, BAD_CAST "mode", - BAD_CAST dev->net_mode); - } else - xmlNewProp(tmp, BAD_CAST src_type, - BAD_CAST dev->source); - } else + *others = add_node_to_others(*others, + "dev", + dev->source, + TYPE_PROP, + "source"); + + if (dev->net_mode != NULL) { + *others = add_node_to_others(*others, + "mode", + dev->net_mode, + TYPE_PROP, + "source"); + } + } else { + *others = add_node_to_others(*others, + src_type, + dev->source, + TYPE_PROP, + "source"); + } + } else { return XML_ERROR; + } return NULL; } -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 26 +++++++++++++++++++------- 1 files changed, 19 insertions(+), 7 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 859cc21..592e67d 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -692,24 +692,36 @@ static const char *set_net_source(const char *root, } -static const char *bridge_net_to_xml(xmlNodePtr nic, struct net_device *dev, - int domtype) +static const char *bridge_net_to_xml(const char *root, struct net_device *dev, + int domtype, struct others **others) { const char *script = "vif-bridge"; - xmlNodePtr tmp; const char *msg = NULL; + CU_DEBUG("Enter bridge_net_to_xml()"); + /* Scripts only supported on Xen guests see 'libvirt' * commit id 1734cdb99 (since 0.9.10) */ if (domtype == DOMAIN_XENPV || domtype == DOMAIN_XENFV) { - tmp = xmlNewChild(nic, NULL, BAD_CAST "script", NULL); - if (tmp == NULL) { + *others = add_node_to_others(*others, + "script", + NULL, + TYPE_NODE, + root); + + if (*others == NULL) { + CU_DEBUG("add node <script> failed."); return XML_ERROR; } - xmlNewProp(tmp, BAD_CAST "path", BAD_CAST script); + + *others = add_node_to_others(*others, + "path", + script, + TYPE_PROP, + "script"); } - msg = set_net_source(nic, dev, "bridge"); + msg = set_net_source(root, dev, "bridge", others); return msg; } -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 157 ++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 121 insertions(+), 36 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 592e67d..4d5ff28 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -730,8 +730,8 @@ static const char *net_xml(xmlNodePtr root, struct domain *dominfo) { int i; const char *msg = NULL; - xmlNodePtr nic; - xmlNodePtr tmp; + + CU_DEBUG("Enter net_xml()"); for (i = 0; (i < dominfo->dev_net_ct) && (msg == NULL); i++) { struct virt_device *dev = &dominfo->dev_net[i]; @@ -740,40 +740,98 @@ static const char *net_xml(xmlNodePtr root, struct domain *dominfo) struct net_device *net = &dev->dev.net; - nic = xmlNewChild(root, NULL, BAD_CAST "interface", NULL); - if (nic == NULL) + net->others = add_node_to_others(net->others, + "interface", + NULL, + TYPE_NODE, + "devices"); + + if (net->others == NULL) { + CU_DEBUG("add node <interface> failed."); return XML_ERROR; - xmlNewProp(nic, BAD_CAST "type", BAD_CAST net->type); + } + + net->others = add_node_to_others(net->others, + "type", + net->type, + TYPE_PROP, + "interface"); if (net->mac != NULL) { - tmp = xmlNewChild(nic, NULL, BAD_CAST "mac", NULL); - if (tmp == NULL) + net->others = add_node_to_others(net->others, + "mac", + NULL, + TYPE_NODE, + "interface"); + + if (net->others == NULL) { + CU_DEBUG("add node <mac> failed."); return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "address", BAD_CAST net->mac); + } + + net->others = add_node_to_others(net->others, + "address", + net->mac, + TYPE_PROP, + "mac"); } if (net->device != NULL) { - tmp = xmlNewChild(nic, NULL, BAD_CAST "target", NULL); - if (tmp == NULL) + net->others = add_node_to_others(net->others, + "target", + NULL, + TYPE_NODE, + "interface"); + + if (net->others == NULL) { + CU_DEBUG("add node <target> failed."); return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "dev", BAD_CAST net->device); + } + + net->others = add_node_to_others(net->others, + "dev", + net->device, + TYPE_PROP, + "target"); } if (net->model != NULL) { - tmp = xmlNewChild(nic, NULL, BAD_CAST "model", NULL); - if (tmp == NULL) + net->others = add_node_to_others(net->others, + "model", + NULL, + TYPE_NODE, + "interface"); + + if (net->others == NULL) { + CU_DEBUG("add node <model> failed."); return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "type", BAD_CAST net->model); + } + + net->others = add_node_to_others(net->others, + "type", + net->model, + TYPE_PROP, + "model"); } if (net->filter_ref != NULL) { - tmp = xmlNewChild(nic, NULL, - BAD_CAST "filterref", NULL); - if (tmp == NULL) + net->others = add_node_to_others(net->others, + "filterref", + NULL, + TYPE_NODE, + "interface"); + + if (net->others == NULL) { + CU_DEBUG("add node <filterref> failed."); return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "filter", - BAD_CAST net->filter_ref); + } + + net->others = add_node_to_others(net->others, + "filter", + net->filter_ref, + TYPE_PROP, + "filterref"); } #if LIBVIR_VERSION_NUMBER >= 9000 @@ -782,24 +840,41 @@ static const char *net_xml(xmlNodePtr root, struct domain *dominfo) int ret; char *string = NULL; - tmp = xmlNewChild(nic, NULL, - BAD_CAST "bandwidth", NULL); - if (tmp == NULL) - return XML_ERROR; + net->others = add_node_to_others(net->others, + "bandwidth", + NULL, + TYPE_NODE, + "interface"); + + if (net->others == NULL) { + CU_DEBUG("add node <bandwidth> failed."); + return XML_ERROR; + } /* Set inbound bandwidth from Reservation & Limit */ - tmp = xmlNewChild(tmp, NULL, - BAD_CAST "inbound", NULL); - if (tmp == NULL) - return XML_ERROR; + net->others = add_node_to_others(net->others, + "inbound", + NULL, + TYPE_NODE, + "bandwidth"); + + if (net->others == NULL) { + CU_DEBUG("add node <inbound> failed."); + return XML_ERROR; + } if (net->reservation) { ret = asprintf(&string, "%" PRIu64, net->reservation); if (ret == -1) return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "average", - BAD_CAST string); + + net->others = add_node_to_others(net->others, + "average", + string, + TYPE_PROP, + "inbound"); + free(string); } @@ -808,28 +883,38 @@ static const char *net_xml(xmlNodePtr root, struct domain *dominfo) net->limit); if (ret == -1) return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "peak", - BAD_CAST string); + + net->others = add_node_to_others(net->others, + "peak", + string, + TYPE_PROP, + "inbound"); + free(string); } } #endif if (STREQ(dev->dev.net.type, "network")) { - msg = set_net_source(nic, net, "network"); + msg = set_net_source("interface", net, "network", &net->others); } else if (STREQ(dev->dev.net.type, "bridge")) { - msg = bridge_net_to_xml(nic, net, dominfo->type); + msg = bridge_net_to_xml("interface", net, dominfo->type, &net->others); } else if (STREQ(dev->dev.net.type, "user")) { - continue; + /* do nothing */ } else if (STREQ(dev->dev.net.type, "direct")) { - msg = set_net_source(nic, net, "direct"); + msg = set_net_source("interface", net, "direct", &net->others); if (net->vsi.vsi_type != NULL) { struct vsi_device *vsi = &dev->dev.net.vsi; - msg = set_net_vsi(nic, vsi); + msg = set_net_vsi("interface", vsi, &net->others); } } else msg = "Unknown interface type"; + + net->others = others_to_xml(root, net->others, "devices"); + if (net->others) { + CU_DEBUG("others_to_xml failed."); + } } return msg; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 20 +++++++++++++++----- 1 files changed, 15 insertions(+), 5 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 4d5ff28..b17ea51 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -923,10 +923,11 @@ static const char *net_xml(xmlNodePtr root, struct domain *dominfo) static const char *vcpu_xml(xmlNodePtr root, struct domain *dominfo) { struct vcpu_device *vcpu; - xmlNodePtr tmp; int ret; char *string = NULL; + CU_DEBUG("Enter vcpu_xml()"); + if (dominfo->dev_vcpu == NULL) return NULL; @@ -936,13 +937,22 @@ static const char *vcpu_xml(xmlNodePtr root, struct domain *dominfo) if (ret == -1) return XML_ERROR; - tmp = xmlNewChild(root, NULL, BAD_CAST "vcpu", BAD_CAST string); + vcpu->others = add_node_to_others(vcpu->others, + "vcpu", + string, + TYPE_NODE, + "domain"); + free(string); - if (tmp == NULL) + if (vcpu->others == NULL) { return XML_ERROR; - else - return NULL; + } + + dominfo->others = combine_others(dominfo->others, vcpu->others); + vcpu->others = NULL; + + return NULL; } #if LIBVIR_VERSION_NUMBER >= 9000 -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 34 ++++++++++++++++++++++++---------- 1 files changed, 24 insertions(+), 10 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index b17ea51..ed00386 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -959,19 +959,27 @@ static const char *vcpu_xml(xmlNodePtr root, struct domain *dominfo) static const char *cputune_xml(xmlNodePtr root, struct domain *dominfo) { struct vcpu_device *vcpu; - xmlNodePtr cputune, tmp; int ret; char *string = NULL; + CU_DEBUG("Enter cputune_xml()"); + if (dominfo->dev_vcpu == NULL) return NULL; vcpu = &dominfo->dev_vcpu[0].dev.vcpu; /* CPU cgroup setting saved by libvirt under <cputune> XML section */ - cputune = xmlNewChild(root, NULL, BAD_CAST "cputune", NULL); - if (cputune == NULL) + vcpu->others = add_node_to_others(vcpu->others, + "cputune", + NULL, + TYPE_NODE, + "domain"); + + if (vcpu->others == NULL) { + CU_DEBUG("add node <cputune> failed."); return XML_ERROR; + } /* Get the CPU cgroup setting from the VCPU RASD.Weight property */ ret = asprintf(&string, @@ -980,16 +988,22 @@ static const char *cputune_xml(xmlNodePtr root, struct domain *dominfo) if (ret == -1) return XML_ERROR; - tmp = xmlNewChild(cputune, - NULL, - BAD_CAST "shares", - BAD_CAST string); + vcpu->others = add_node_to_others(vcpu->others, + "shares", + string, + TYPE_NODE, + "cputune"); free(string); - if (tmp == NULL) + if (vcpu->others == NULL) { + CU_DEBUG("add node <shares> failed."); return XML_ERROR; - else - return NULL; + } + + dominfo->others = combine_others(dominfo->others, vcpu->others); + vcpu->others = NULL; + + return NULL; } #endif -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 39 ++++++++++++++++++++++++--------------- 1 files changed, 24 insertions(+), 15 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index ed00386..6ab697b 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1010,10 +1010,11 @@ static const char *cputune_xml(xmlNodePtr root, struct domain *dominfo) static const char *mem_xml(xmlNodePtr root, struct domain *dominfo) { struct mem_device *mem; - xmlNodePtr tmp = NULL; int ret; char *string = NULL; + CU_DEBUG("Enter mem_xml()"); + if (dominfo->dev_mem == NULL) return NULL; @@ -1022,30 +1023,38 @@ static const char *mem_xml(xmlNodePtr root, struct domain *dominfo) ret = asprintf(&string, "%" PRIu64, mem->size); if (ret == -1) goto out; - tmp = xmlNewChild(root, - NULL, - BAD_CAST "currentMemory", - BAD_CAST string); - if (tmp == NULL) + + mem->others = add_node_to_others(mem->others, + "currentMemory", + string, + TYPE_NODE, + "domain"); + + if (mem->others == NULL) { + CU_DEBUG("add node <currentMemory> failed."); return XML_ERROR; + } free(string); - tmp = NULL; ret = asprintf(&string, "%" PRIu64, mem->maxsize); if (ret == -1) goto out; - tmp = xmlNewChild(root, - NULL, - BAD_CAST "memory", - BAD_CAST string); + + mem->others = add_node_to_others(mem->others, + "memory", + string, + TYPE_NODE, + "domain"); free(string); + + dominfo->others = combine_others(dominfo->others, mem->others); + mem->others = NULL; + + return NULL; out: - if (tmp == NULL) - return XML_ERROR; - else - return NULL; + return XML_ERROR; } static const char *emu_xml(xmlNodePtr root, struct domain *dominfo) -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 20 +++++++++++++++++--- 1 files changed, 17 insertions(+), 3 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 6ab697b..a4094d8 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1060,15 +1060,29 @@ static const char *mem_xml(xmlNodePtr root, struct domain *dominfo) static const char *emu_xml(xmlNodePtr root, struct domain *dominfo) { struct emu_device *emu; - xmlNodePtr tmp; + + CU_DEBUG("Enter emu_xml()"); if (dominfo->dev_emu == NULL) return NULL; emu = &dominfo->dev_emu->dev.emu; - tmp = xmlNewChild(root, NULL, BAD_CAST "emulator", BAD_CAST emu->path); - if (tmp == NULL) + + emu->others = add_node_to_others(emu->others, + "emulator", + emu->path, + TYPE_NODE, + "devices"); + + if (emu->others == NULL) { + CU_DEBUG("add node <emulator> failed."); return XML_ERROR; + } + + emu->others = others_to_xml(root, emu->others, "devices"); + if (emu->others) { + CU_DEBUG("others_to_xml failed."); + } return NULL; } -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 104 +++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 83 insertions(+), 21 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index a4094d8..5bfdc81 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1090,46 +1090,108 @@ static const char *emu_xml(xmlNodePtr root, struct domain *dominfo) static const char *graphics_vnc_xml(xmlNodePtr root, struct graphics_device *dev) { - xmlNodePtr tmp = NULL; + CU_DEBUG("Enter graphics_vnc_xml()"); - tmp = xmlNewChild(root, NULL, BAD_CAST "graphics", NULL); - if (tmp == NULL) + dev->others = add_node_to_others(dev->others, + "graphics", + NULL, + TYPE_NODE, + "devices"); + + if (dev->others == NULL) { + CU_DEBUG("add node <graphics> failed."); return XML_ERROR; + } - xmlNewProp(tmp, BAD_CAST "type", BAD_CAST dev->type); + dev->others = add_node_to_others(dev->others, + "type", + dev->type, + TYPE_PROP, + "graphics"); if (STREQC(dev->type, "sdl")) { if (dev->dev.sdl.display) { - xmlNewProp(tmp, BAD_CAST "display", - BAD_CAST dev->dev.sdl.display); + dev->others = add_node_to_others(dev->others, + "display", + dev->dev.sdl.display, + TYPE_PROP, + "graphics"); } if (dev->dev.sdl.xauth) { - xmlNewProp(tmp, BAD_CAST "xauth", - BAD_CAST dev->dev.sdl.xauth); + dev->others = add_node_to_others(dev->others, + "xauth", + dev->dev.sdl.xauth, + TYPE_PROP, + "graphics"); } if (dev->dev.sdl.fullscreen) { - xmlNewProp(tmp, BAD_CAST "fullscreen", - BAD_CAST dev->dev.sdl.fullscreen); + dev->others = add_node_to_others(dev->others, + "fullscreen", + dev->dev.sdl.fullscreen, + TYPE_PROP, + "graphics"); } return NULL; } if (dev->dev.vnc.port) { - xmlNewProp(tmp, BAD_CAST "port", BAD_CAST dev->dev.vnc.port); - if (STREQC(dev->dev.vnc.port, "-1")) - xmlNewProp(tmp, BAD_CAST "autoport", BAD_CAST "yes"); - else - xmlNewProp(tmp, BAD_CAST "autoport", BAD_CAST "no"); + dev->others = add_node_to_others(dev->others, + "port", + dev->dev.vnc.port, + TYPE_PROP, + "graphics"); + /* Just fetch autoport from others or the following code + * would add the attribution twice. These function calling + * would removed after the feature about others tags + * management finished. */ + fetch_from_others(&dev->others, + "autoport", + TYPE_PROP, + "graphics"); + + if (STREQC(dev->dev.vnc.port, "-1")) { + dev->others = add_node_to_others(dev->others, + "autoport", + "yes", + TYPE_PROP, + "graphics"); + } else { + dev->others = add_node_to_others(dev->others, + "autoport", + "no", + TYPE_PROP, + "graphics"); + } } - if (dev->dev.vnc.host) - xmlNewProp(tmp, BAD_CAST "listen", BAD_CAST dev->dev.vnc.host); + if (dev->dev.vnc.host) { + dev->others = add_node_to_others(dev->others, + "listen", + dev->dev.vnc.host, + TYPE_PROP, + "graphics"); + } - if (dev->dev.vnc.passwd) - xmlNewProp(tmp, BAD_CAST "passwd", BAD_CAST dev->dev.vnc.passwd); + if (dev->dev.vnc.passwd) { + dev->others = add_node_to_others(dev->others, + "passwd", + dev->dev.vnc.passwd, + TYPE_PROP, + "graphics"); + } + + if (dev->dev.vnc.keymap) { + dev->others = add_node_to_others(dev->others, + "keymap", + dev->dev.vnc.keymap, + TYPE_PROP, + "graphics"); + } - if (dev->dev.vnc.keymap) - xmlNewProp(tmp, BAD_CAST "keymap", BAD_CAST dev->dev.vnc.keymap); + dev->others = others_to_xml(root, dev->others, "devices"); + if (dev->others) { + CU_DEBUG("others_to_xml failed."); + } return NULL; } -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 65 +++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 52 insertions(+), 13 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 5bfdc81..6b07b00 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1199,28 +1199,67 @@ static const char *graphics_vnc_xml(xmlNodePtr root, static const char *graphics_pty_xml(xmlNodePtr root, struct graphics_device *dev) { - xmlNodePtr pty = NULL; - xmlNodePtr tmp = NULL; + CU_DEBUG("Enter graphics_pty_xml()"); + + dev->others = add_node_to_others(dev->others, + dev->type, + NULL, + TYPE_NODE, + "devices"); - pty = xmlNewChild(root, NULL, BAD_CAST dev->type, NULL); - if (pty == NULL) + if (dev->others == NULL) { + CU_DEBUG("add node <%s> failed.", dev->type); return XML_ERROR; + } - xmlNewProp(pty, BAD_CAST "type", BAD_CAST "pty"); + dev->others = add_node_to_others(dev->others, + "type", + "pty", + TYPE_PROP, + dev->type); - tmp = xmlNewChild(pty, NULL, BAD_CAST "source", NULL); - if (tmp == NULL) + dev->others = add_node_to_others(dev->others, + "source", + NULL, + TYPE_NODE, + dev->type); + + if (dev->others == NULL) { + CU_DEBUG("add node <source> failed."); return XML_ERROR; + } + + if(dev->dev.vnc.host) { + dev->others = add_node_to_others(dev->others, + "path", + dev->dev.vnc.host, + TYPE_PROP, + "source"); + } - if(dev->dev.vnc.host) - xmlNewProp(tmp, BAD_CAST "path", BAD_CAST dev->dev.vnc.host); + dev->others = add_node_to_others(dev->others, + "target", + NULL, + TYPE_NODE, + dev->type); - tmp = xmlNewChild(pty, NULL, BAD_CAST "target", NULL); - if (tmp == NULL) + if (dev->others == NULL) { + CU_DEBUG("add node <target> failed."); return XML_ERROR; + } - if(dev->dev.vnc.port) - xmlNewProp(tmp, BAD_CAST "port", BAD_CAST dev->dev.vnc.port); + if(dev->dev.vnc.port) { + dev->others = add_node_to_others(dev->others, + "port", + dev->dev.vnc.port, + TYPE_PROP, + "target"); + } + + dev->others = others_to_xml(root, dev->others, "devices"); + if (dev->others) { + CU_DEBUG("others_to_xml failed."); + } return NULL; } -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 32 +++++++++++++++++++++++++++----- 1 files changed, 27 insertions(+), 5 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 6b07b00..dbf60bd 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1295,20 +1295,42 @@ static const char *input_xml(xmlNodePtr root, struct domain *dominfo) { int i; + CU_DEBUG("Enter input_xml()"); + for (i = 0; i < dominfo->dev_input_ct; i++) { - xmlNodePtr tmp; struct virt_device *_dev = &dominfo->dev_input[i]; if (_dev->type == CIM_RES_TYPE_UNKNOWN) continue; struct input_device *dev = &_dev->dev.input; - tmp = xmlNewChild(root, NULL, BAD_CAST "input", NULL); - if (tmp == NULL) + dev->others = add_node_to_others(dev->others, + "input", + NULL, + TYPE_NODE, + "devices"); + + if (dev->others == NULL) { + CU_DEBUG("add node <input> failed."); return XML_ERROR; + } - xmlNewProp(tmp, BAD_CAST "type", BAD_CAST dev->type); - xmlNewProp(tmp, BAD_CAST "bus", BAD_CAST dev->bus); + dev->others = add_node_to_others(dev->others, + "type", + dev->type, + TYPE_PROP, + "input"); + + dev->others = add_node_to_others(dev->others, + "bus", + dev->bus, + TYPE_PROP, + "input"); + + dev->others = others_to_xml(root, dev->others, "devices"); + if (dev->others) { + CU_DEBUG("others_to_xml failed."); + } } return NULL; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 102 ++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 71 insertions(+), 31 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index dbf60bd..3dff548 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1338,56 +1338,96 @@ static const char *input_xml(xmlNodePtr root, struct domain *dominfo) static char *system_xml(xmlNodePtr root, struct domain *domain) { - xmlNodePtr tmp; + CU_DEBUG("Enter system_xml()"); - tmp = xmlNewChild(root, NULL, BAD_CAST "name", BAD_CAST domain->name); - if (tmp == NULL) + domain->others = add_node_to_others(domain->others, + "name", + domain->name, + TYPE_NODE, + "domain"); + + if (domain->others == NULL) { + CU_DEBUG("add node <name> failed."); return XML_ERROR; + } if (domain->bootloader) { - tmp = xmlNewChild(root, - NULL, - BAD_CAST "bootloader", - BAD_CAST domain->bootloader); - if (tmp == NULL) + domain->others = add_node_to_others(domain->others, + "bootloader", + domain->bootloader, + TYPE_NODE, + "domain"); + + if (domain->others == NULL) { + CU_DEBUG("add node <bootloader> failed."); return XML_ERROR; + } } if (domain->bootloader_args) { - tmp = xmlNewChild(root, - NULL, - BAD_CAST "bootloader_args", - BAD_CAST domain->bootloader_args); - if (tmp == NULL) + domain->others = add_node_to_others(domain->others, + "bootloader_args", + domain->bootloader_args, + TYPE_NODE, + "domain"); + + if (domain->others == NULL) { + CU_DEBUG("add node <bootloader_args> failed."); return XML_ERROR; + } } - tmp = xmlNewChild(root, - NULL, - BAD_CAST "on_poweroff", - BAD_CAST vssd_recovery_action_str(domain->on_poweroff)); - if (tmp == NULL) + domain->others = add_node_to_others(domain->others, + "on_poweroff", + vssd_recovery_action_str(domain->on_poweroff), + TYPE_NODE, + "domain"); + + if (domain->others == NULL) { + CU_DEBUG("add node <on_poweroff> failed."); return XML_ERROR; + } - tmp = xmlNewChild(root, - NULL, - BAD_CAST "on_crash", - BAD_CAST vssd_recovery_action_str(domain->on_crash)); - if (tmp == NULL) + domain->others = add_node_to_others(domain->others, + "on_crash", + vssd_recovery_action_str(domain->on_crash), + TYPE_NODE, + "domain"); + + if (domain->others == NULL) { + CU_DEBUG("add node <on_crash> failed."); return XML_ERROR; + } - tmp = xmlNewChild(root, - NULL, - BAD_CAST "uuid", - BAD_CAST domain->uuid); - if (tmp == NULL) + domain->others = add_node_to_others(domain->others, + "uuid", + domain->uuid, + TYPE_NODE, + "domain"); + + if (domain->others == NULL) { + CU_DEBUG("add node <uuid> failed."); return XML_ERROR; + } + if (domain->clock != NULL) { - tmp = xmlNewChild(root, NULL, BAD_CAST "clock", NULL); - if (tmp == NULL) + domain->others = add_node_to_others(domain->others, + "clock", + NULL, + TYPE_NODE, + "domain"); + + if (domain->others == NULL) { + CU_DEBUG("add node <clock> failed."); return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "offset", BAD_CAST domain->clock); + } + + domain->others = add_node_to_others(domain->others, + "offset", + domain->clock, + TYPE_PROP, + "clock"); } return NULL; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 39 insertions(+), 10 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 3dff548..f6d83a6 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1433,10 +1433,11 @@ static char *system_xml(xmlNodePtr root, struct domain *domain) return NULL; } -static char *_xenpv_os_xml(xmlNodePtr root, struct domain *domain) +static char *_xenpv_os_xml(const char *root, struct domain *domain) { struct pv_os_info *os = &domain->os_info.pv; - xmlNodePtr tmp; + + CU_DEBUG("Enter _xenpv_os_xml()"); if (os->type == NULL) os->type = strdup("linux"); @@ -1444,21 +1445,49 @@ static char *_xenpv_os_xml(xmlNodePtr root, struct domain *domain) if (os->kernel == NULL) os->kernel = strdup("/dev/null"); - tmp = xmlNewChild(root, NULL, BAD_CAST "type", BAD_CAST os->type); - if (tmp == NULL) + domain->others = add_node_to_others(domain->others, + "type", + os->type, + TYPE_NODE, + root); + + if (domain->others == NULL) { + CU_DEBUG("add node <type> failed."); return XML_ERROR; + } - tmp = xmlNewChild(root, NULL, BAD_CAST "kernel", BAD_CAST os->kernel); - if (tmp == NULL) + domain->others = add_node_to_others(domain->others, + "kernel", + os->kernel, + TYPE_NODE, + root); + + if (domain->others == NULL) { + CU_DEBUG("add node <kernel> failed."); return XML_ERROR; + } - tmp = xmlNewChild(root, NULL, BAD_CAST "initrd", BAD_CAST os->initrd); - if (tmp == NULL) + domain->others = add_node_to_others(domain->others, + "initrd", + os->initrd, + TYPE_NODE, + root); + + if (domain->others == NULL) { + CU_DEBUG("add node <initrd> failed."); return XML_ERROR; + } - tmp = xmlNewChild(root, NULL, BAD_CAST "cmdline", BAD_CAST os->cmdline); - if (tmp == NULL) + domain->others = add_node_to_others(domain->others, + "cmdline", + os->cmdline, + TYPE_NODE, + root); + + if (domain->others == NULL) { + CU_DEBUG("add node <cmdline> failed."); return XML_ERROR; + } return NULL; } -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 23 ++++++++++++++++++----- 1 files changed, 18 insertions(+), 5 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index f6d83a6..bd53118 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1492,17 +1492,30 @@ static char *_xenpv_os_xml(const char *root, struct domain *domain) return NULL; } -static int _fv_bootlist_xml(xmlNodePtr root, struct fv_os_info *os) +static int _fv_bootlist_xml(const char *root, struct domain *domain) { unsigned i; - xmlNodePtr tmp; + struct fv_os_info *os = &domain->os_info.fv; + + CU_DEBUG("Enter _fv_bootlist_xml()"); for (i = 0; i < os->bootlist_ct; i++) { - tmp = xmlNewChild(root, NULL, BAD_CAST "boot", NULL); - if (tmp == NULL) + domain->others = add_node_to_others(domain->others, + "boot", + NULL, + TYPE_NODE, + root); + + if (domain->others == NULL) { + CU_DEBUG("add node <boot> failed."); return 0; + } - xmlNewProp(tmp, BAD_CAST "dev", BAD_CAST os->bootlist[i]); + domain->others = add_node_to_others(domain->others, + "dev", + os->bootlist[i], + TYPE_PROP, + "boot"); } return 1; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 33 ++++++++++++++++++++++++--------- 1 files changed, 24 insertions(+), 9 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index bd53118..cbf6a9f 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1521,12 +1521,13 @@ static int _fv_bootlist_xml(const char *root, struct domain *domain) return 1; } -static char *_xenfv_os_xml(xmlNodePtr root, struct domain *domain) +static char *_xenfv_os_xml(const char *root, struct domain *domain) { struct fv_os_info *os = &domain->os_info.fv; - xmlNodePtr tmp; unsigned ret; + CU_DEBUG("Enter _xenfv_os_xml()"); + if (os->type == NULL) os->type = strdup("hvm"); @@ -1539,15 +1540,29 @@ static char *_xenfv_os_xml(xmlNodePtr root, struct domain *domain) os->bootlist[0] = strdup("hd"); } - tmp = xmlNewChild(root, NULL, BAD_CAST "type", BAD_CAST os->type); - if (tmp == NULL) - return XML_ERROR; + domain->others = add_node_to_others(domain->others, + "type", + os->type, + TYPE_NODE, + root); - tmp = xmlNewChild(root, NULL, BAD_CAST "loader", BAD_CAST os->loader); - if (tmp == NULL) - return XML_ERROR; + if (domain->others == NULL) { + CU_DEBUG("add node <type> failed."); + return 0; + } - ret = _fv_bootlist_xml(root, os); + domain->others = add_node_to_others(domain->others, + "loader", + os->loader, + TYPE_NODE, + root); + + if (domain->others == NULL) { + CU_DEBUG("add node <loader> failed."); + return 0; + } + + ret = _fv_bootlist_xml(root, domain); if (ret == 0) return XML_ERROR; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 18 +++++++++++++----- 1 files changed, 13 insertions(+), 5 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index cbf6a9f..fcd701c 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1569,12 +1569,13 @@ static char *_xenfv_os_xml(const char *root, struct domain *domain) return NULL; } -static char *_kvm_os_xml(xmlNodePtr root, struct domain *domain) +static char *_kvm_os_xml(const char *root, struct domain *domain) { struct fv_os_info *os = &domain->os_info.fv; - xmlNodePtr tmp; unsigned ret; + CU_DEBUG("Enter _kvm_os_xml()"); + if (os->type == NULL) os->type = strdup("hvm"); @@ -1584,11 +1585,18 @@ static char *_kvm_os_xml(xmlNodePtr root, struct domain *domain) os->bootlist[0] = strdup("hd"); } - tmp = xmlNewChild(root, NULL, BAD_CAST "type", BAD_CAST os->type); - if (tmp == NULL) + domain->others = add_node_to_others(domain->others, + "type", + os->type, + TYPE_NODE, + root); + + if (domain->others == NULL) { + CU_DEBUG("add node <type> failed."); return XML_ERROR; + } - ret = _fv_bootlist_xml(root, os); + ret = _fv_bootlist_xml(root, domain); if (ret == 0) return XML_ERROR; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 27 +++++++++++++++++++++------ 1 files changed, 21 insertions(+), 6 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index fcd701c..36593d4 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1603,21 +1603,36 @@ static char *_kvm_os_xml(const char *root, struct domain *domain) return NULL; } -static char *_lxc_os_xml(xmlNodePtr root, struct domain *domain) +static char *_lxc_os_xml(const char *root, struct domain *domain) { struct lxc_os_info *os = &domain->os_info.lxc; - xmlNodePtr tmp; + + CU_DEBUG("Enter _lxc_os_xml()"); if (os->type == NULL) os->type = strdup("exe"); - tmp = xmlNewChild(root, NULL, BAD_CAST "init", BAD_CAST os->init); - if (tmp == NULL) + domain->others = add_node_to_others(domain->others, + "init", + os->init, + TYPE_NODE, + root); + + if (domain->others == NULL) { + CU_DEBUG("add node <init> failed."); return XML_ERROR; + } - tmp = xmlNewChild(root, NULL, BAD_CAST "type", BAD_CAST os->type); - if (tmp == NULL) + domain->others = add_node_to_others(domain->others, + "type", + os->type, + TYPE_NODE, + root); + + if (domain->others == NULL) { + CU_DEBUG("add node <type> failed."); return XML_ERROR; + } return NULL; } -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 16 ++++++++++++---- 1 files changed, 12 insertions(+), 4 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 36593d4..2f9ab5a 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1639,11 +1639,19 @@ static char *_lxc_os_xml(const char *root, struct domain *domain) static char *os_xml(xmlNodePtr root, struct domain *domain) { - xmlNodePtr os; + const char *os = "os"; - os = xmlNewChild(root, NULL, BAD_CAST "os", NULL); - if (os == NULL) - return "Failed to allocate XML memory"; + CU_DEBUG("Enter os_xml()"); + + domain->others = add_node_to_others(domain->others, + "os", + NULL, + TYPE_NODE, + "domain"); + + if (domain->others == NULL) { + return "add node <os> failed."; + } if (domain->type == DOMAIN_XENPV) return _xenpv_os_xml(os, domain); -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 36 ++++++++++++++++++++++++++---------- 1 files changed, 26 insertions(+), 10 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 2f9ab5a..dab4bcd 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1667,20 +1667,36 @@ static char *os_xml(xmlNodePtr root, struct domain *domain) static char *features_xml(xmlNodePtr root, struct domain *domain) { - xmlNodePtr features; + CU_DEBUG("Enter features_xml()"); - features = xmlNewChild(root, NULL, BAD_CAST "features", NULL); - if (features == NULL) - return "Failed to allocate XML memory"; + domain->others = add_node_to_others(domain->others, + "features", + NULL, + TYPE_NODE, + "domain"); - if (domain->acpi) - xmlNewChild(features, NULL, BAD_CAST "acpi", NULL); + if (domain->others == NULL) { + CU_DEBUG("add node <features> failed."); + return XML_ERROR; + } - if (domain->apic) - xmlNewChild(features, NULL, BAD_CAST "apic", NULL); + domain->others = add_node_to_others(domain->others, + "acpi", + NULL, + TYPE_NODE, + "features"); + + domain->others = add_node_to_others(domain->others, + "apic", + NULL, + TYPE_NODE, + "features"); - if (domain->pae) - xmlNewChild(features, NULL, BAD_CAST "pae", NULL); + domain->others = add_node_to_others(domain->others, + "pae", + NULL, + TYPE_NODE, + "features"); return NULL; } -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 23 +++++++++++++++++++++++ 1 files changed, 23 insertions(+), 0 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index dab4bcd..292717d 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1741,6 +1741,24 @@ static char *tree_to_xml(xmlNodePtr root) return xml; } +static const char *unknown_xml(xmlNodePtr root, struct domain *dominfo) +{ + int i; + + CU_DEBUG("Enter unknown_xml()"); + + for (i = 0; i < dominfo->dev_unknown_ct; i++) { + struct virt_device *_dev = &dominfo->dev_unknown[i]; + struct unknown_device *dev = &_dev->dev.unknown; + if (others_to_xml(root, dev->others, NULL) != NULL) { + CU_DEBUG("others_to_xml failed."); + } + + } + + return NULL; +} + char *device_to_xml(struct virt_device *_dev) { char *xml = NULL; @@ -1800,6 +1818,11 @@ char *device_to_xml(struct virt_device *_dev) dominfo->dev_input_ct = 1; dominfo->dev_input = dev; break; + case CIM_RES_TYPE_UNKNOWN: + func = unknown_xml; + dominfo->dev_unknown_ct = 1; + dominfo->dev_unknown = dev; + break; default: cleanup_virt_devices(&dev, 1); goto out; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 18 +++++++++++++++--- 1 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 292717d..c59b172 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1860,9 +1860,12 @@ char *system_to_xml(struct domain *dominfo) &input_xml, &graphics_xml, &emu_xml, + &unknown_xml, NULL }; + CU_DEBUG("Enter system_to_xml()"); + if ((dominfo->type == DOMAIN_XENPV) || (dominfo->type == DOMAIN_XENFV)) domtype = "xen"; else if (dominfo->type == DOMAIN_KVM) @@ -1890,15 +1893,18 @@ char *system_to_xml(struct domain *dominfo) if (xmlNewProp(root, BAD_CAST "type", BAD_CAST domtype) == NULL) goto out; - msg = system_xml(root, dominfo); + /* Parse all tags into others field of domain and generate xml in + * others_to_xml(). + */ + msg = os_xml(root, dominfo); if (msg != NULL) goto out; - msg = os_xml(root, dominfo); + msg = features_xml(root, dominfo); if (msg != NULL) goto out; - msg = features_xml(root, dominfo); + msg = system_xml(root, dominfo); if (msg != NULL) goto out; @@ -1917,6 +1923,12 @@ char *system_to_xml(struct domain *dominfo) goto out; #endif + dominfo->others = others_to_xml(root, dominfo->others, "domain"); + if (dominfo->others) { + CU_DEBUG("others_to_xml failed."); + } + + /* Parse <devices> field. */ devices = xmlNewChild(root, NULL, BAD_CAST "devices", NULL); if (devices == NULL) { msg = XML_ERROR; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- src/Virt_VirtualSystemManagementService.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c index bfb1654..4e747f7 100644 --- a/src/Virt_VirtualSystemManagementService.c +++ b/src/Virt_VirtualSystemManagementService.c @@ -581,6 +581,7 @@ static bool default_graphics_device(struct domain *domain) domain->dev_graphics->dev.graphics.dev.vnc.host = strdup("127.0.0.1"); domain->dev_graphics->dev.graphics.dev.vnc.keymap = strdup("en-us"); domain->dev_graphics->dev.graphics.dev.vnc.passwd = NULL; + domain->dev_graphics->dev.graphics.others = NULL; domain->dev_graphics_ct = 1; return true; @@ -606,6 +607,8 @@ static bool default_input_device(struct domain *domain) domain->dev_input->dev.input.bus = strdup("ps2"); } + domain->dev_input->dev.input.others = NULL; + domain->dev_input_ct = 1; return true; @@ -981,6 +984,9 @@ static const char *net_rasd_to_vdev(CMPIInstance *inst, &dev->dev.net.limit) != CMPI_RC_OK) dev->dev.net.limit = 0; + cleanup_others(dev->dev.net.others); + dev->dev.net.others = NULL; + out: free(network); return msg; @@ -1102,6 +1108,9 @@ static const char *disk_rasd_to_vdev(CMPIInstance *inst, free(dev->id); dev->id = strdup(dev->dev.disk.virtual_dev); + cleanup_others(dev->dev.disk.others); + dev->dev.disk.others = NULL; + return NULL; } @@ -1126,6 +1135,9 @@ static const char *lxc_disk_rasd_to_vdev(CMPIInstance *inst, free(dev->id); dev->id = strdup(dev->dev.disk.virtual_dev); + cleanup_others(dev->dev.disk.others); + dev->dev.disk.others = NULL; + return NULL; } @@ -1466,6 +1478,9 @@ static const char *graphics_rasd_to_vdev(CMPIInstance *inst, goto out; } + cleanup_others(dev->dev.graphics.others); + dev->dev.graphics.others = NULL; + CU_DEBUG("graphics = %s", dev->id); out: @@ -1495,6 +1510,9 @@ static const char *input_rasd_to_vdev(CMPIInstance *inst, } else dev->dev.input.bus = strdup(val); + cleanup_others(dev->dev.input.others); + dev->dev.input.others = NULL; + out: return NULL; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 9eabd48..1680b37 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1686,6 +1686,7 @@ static int _get_mem_device(const char *xml, struct virt_device **list) struct virt_device *mdevs = NULL; struct virt_device *mdev = NULL; int ret; + struct others *tmp = NULL; ret = parse_devices(xml, &mdevs, CIM_RES_TYPE_MEM); if (ret <= 0) @@ -1705,10 +1706,16 @@ static int _get_mem_device(const char *xml, struct virt_device **list) mdevs[1].dev.mem.size); mdev->dev.mem.maxsize = MAX(mdevs[0].dev.mem.maxsize, mdevs[1].dev.mem.maxsize); + mdev->dev.mem.others = dup_others(mdevs[0].dev.mem.others); + tmp = dup_others(mdevs[1].dev.mem.others); + mdev->dev.mem.others = combine_others(mdev->dev.mem.others, + tmp); + } 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->dev.mem.others = dup_others(mdevs[0].dev.mem.others); } mdev->type = CIM_RES_TYPE_MEM; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 1680b37..f2b9ec3 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1744,6 +1744,7 @@ static int _get_proc_device(const char *xml, struct virt_device **list) proc_dev->type = CIM_RES_TYPE_PROC; proc_dev->id = strdup("proc"); proc_dev->dev.vcpu.quantity = proc_devs[0].dev.vcpu.quantity; + proc_dev->dev.vcpu.others = dup_others(proc_devs[0].dev.vcpu.others); *list = proc_dev; cleanup_virt_devices(&proc_devs, ret); -- 1.7.1

On 10/08/2013 08:13 AM, Xu Wang wrote:
These patches are based on commit 04bfeb825e5e155ffa72119253de608ccf3bd72b. So I may need more work on rebasing.
Most of bugs reported recently are about some tags libvirt-cim doesn't support will be dropped after resource updated. So a new member was added into every virt_device and domain structure. And a new structure named unknown device was added to save those tags new added.
The original implementaion is reading every member of virt_device structure from xml and save it. But the defect of this is some tags were not a member of virt_device were dropped. After resource updated, every data in the virt_device will be used to regenerate new xml. Hence the tags unsupported above, disappeared.
So I added a member into every virt_device and domain structure, 'others'. It's a link list and used to save all data read from xml. Another new structure 'unknown_device' was added to save data except libvirt-cim could recognize.
The new implementation is, firstly parse_*_device() could read all nodes and properties from xml and save them into 'others' link list. Then every member of virt_device will fetch data from others link list and save it. So that nodes in the 'others' link list could be saved until they are used to re- generate xml.
After resource updating finished, libvirt-cim will call *_xml() to generate xml. The new process of generating xml like this, firstly all data in the members of virt_device will be restored into 'others' link list, then a function (others_to_xml) will use this link list to generate xml.
Some points I have updated, 1. 'others' link list has to be processed in _get_proc_device() and _get_mem_device(). They should be copied into new data structure. 2. If resource updating happened, others field should be cleared because this device has been changed and they are useless.
Besides above some logic may be a little strange or boring. Implemention like that is just to be compatible with upper layer functions (to make changes as less as possible). After keep a balance I decided to devide the whole xml into several parts: <domain>------------------------others in domain to save unsupported sub-nodes of domain -some fields (devices, mem, vcpu...) will be skiped because -they have their own parsing functions. <name>xxx</name> <uuid>xxx</uuid> <vcpu>xxx</vcpu> <mem>xxx</mem> <devices> <disk>xxx</disk>------- others in virt_device to save unsupported tags of this device <emulator>xxx</emulator> ...----------- unknown_device to save unsupported device except like <disk>,<emu>,etc. </devices> </domain>
Hence, all nodes read from xml will be restored after xml generation.
Short notification, Boris or I will do a detail review (hopefully) by the end of next week (both being pretty busy right now) as this is touching some of the areas we're working on for s390 enablement. But in general I think it's a good idea and like the overall approach. -- Mit freundlichen Grüßen/Kind Regards Viktor Mihajlovski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martina Köderitz Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294
participants (4)
-
Boris Fiuczynski
-
John Ferlan
-
Viktor Mihajlovski
-
Xu Wang