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

What's new in V2: 1. Rebase commit to the current upstream. 2. Update console device support. 3. Add id and parent_id to handle there are more than two sub-node but with the same issue. 4. Add status (ACTIVE/INACTIVE) to identify if a node was fetched. 5. Adjust the original designing plan. Now after fetched a node from link list just change its status from ACTIVE to INACTIVE instead of delete it. Purpose of this update is to make link list keep the structure of xml and regenerate xml easily. 6. Necessary comments added. 7. Add function (compare_param_int/compare_param_str) to adjust the result of comparation (if any parameter is NULL/-1 the comparation result is TRUE instead of FALSE. 8. Bugs fixing. Such as attribute 'arch' under <type> of <os>, <dev> of <target> parsing, etc. -------------------------------------------------------------------------- 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 (48): 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_console_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 console_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 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 | 1959 ++++++++++++++++++++++----- libxkutil/device_parsing.h | 64 + libxkutil/xmlgen.c | 2103 +++++++++++++++++++++++------ src/Virt_VirtualSystemManagementService.c | 20 +- src/svpc_types.h | 1 + 5 files changed, 3445 insertions(+), 702 deletions(-)

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 43 insertions(+), 0 deletions(-) diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h index 2803d6a..147551a 100644 --- a/libxkutil/device_parsing.h +++ b/libxkutil/device_parsing.h @@ -33,6 +33,33 @@ #include "../src/svpc_types.h" +/* The structure for saving unknown tag in the xml */ +enum others_type { + TYPE_PROP, + TYPE_NODE +}; + +struct others { + /* To identify the different tags with same name */ + int id; + char *name; + int parent_id; + char *parent_name; + enum others_type type; + char *value; + struct others *next; + enum status { + ACTIVE, + INACTIVE + }; +}; + +/* 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 +83,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,6 +98,7 @@ struct net_device { uint64_t reservation; uint64_t limit; struct vsi_device vsi; + struct others *others; }; struct mem_device { @@ -78,16 +107,19 @@ struct mem_device { enum { MEM_DUMP_CORE_NOT_SET, MEM_DUMP_CORE_ON, MEM_DUMP_CORE_OFF } dumpCore; + 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 { @@ -95,12 +127,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 { @@ -109,6 +143,7 @@ struct graphics_device { struct vnc_device vnc; struct sdl_device sdl; } dev; + struct others *others; }; struct path_device { @@ -146,11 +181,13 @@ struct console_device { struct udp_device udp; } source_dev; char *target_type; + struct others *others; }; struct input_device { char *type; char *bus; + struct others *others; }; struct virt_device { @@ -164,6 +201,7 @@ struct virt_device { struct graphics_device graphics; struct console_device console; struct input_device input; + struct unknown_device unknown; } dev; char *id; }; @@ -239,6 +277,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

On 10/27/2013 10:45 PM, Xu Wang wrote:
Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 43 insertions(+), 0 deletions(-)
I am going to try to take these one at a time. Run them through cimtest singly to see if I can flesh out errors. I didn't get very far - 2/48 causes some failures in cimtest ...
diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h index 2803d6a..147551a 100644 --- a/libxkutil/device_parsing.h +++ b/libxkutil/device_parsing.h @@ -33,6 +33,33 @@
#include "../src/svpc_types.h"
+/* The structure for saving unknown tag in the xml */ +enum others_type { + TYPE_PROP, + TYPE_NODE +}; + +struct others {
There's an extra space after the { which git am complains about
+ /* To identify the different tags with same name */ + int id; + char *name; + int parent_id; + char *parent_name; + enum others_type type; + char *value; + struct others *next; + enum status { + ACTIVE, + INACTIVE + };
Older compiler complains: ../libxkutil/device_parsing.h:54: warning: declaration does not declare anything New compiler where I don't ignore warnings stops: In file included from device_parsing.c:33:0: device_parsing.h:54:10: error: declaration does not declare anything [-Werror] }; ^ cc1: all warnings being treated as errors I'll have to see more to determine whether I like this pointer to pointer within structures... There's usually some assumption somewhere which causes a failure... John
+}; + +/* 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 +83,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,6 +98,7 @@ struct net_device { uint64_t reservation; uint64_t limit; struct vsi_device vsi; + struct others *others; };
struct mem_device { @@ -78,16 +107,19 @@ struct mem_device { enum { MEM_DUMP_CORE_NOT_SET, MEM_DUMP_CORE_ON, MEM_DUMP_CORE_OFF } dumpCore; + 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 { @@ -95,12 +127,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 { @@ -109,6 +143,7 @@ struct graphics_device { struct vnc_device vnc; struct sdl_device sdl; } dev; + struct others *others; };
struct path_device { @@ -146,11 +181,13 @@ struct console_device { struct udp_device udp; } source_dev; char *target_type; + struct others *others; };
struct input_device { char *type; char *bus; + struct others *others; };
struct virt_device { @@ -164,6 +201,7 @@ struct virt_device { struct graphics_device graphics; struct console_device console; struct input_device input; + struct unknown_device unknown; } dev; char *id; }; @@ -239,6 +277,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);

On 10/27/2013 10:45 PM, Xu Wang wrote:
Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 43 insertions(+), 0 deletions(-)
I am going to try to take these one at a time. Run them through cimtest singly to see if I can flesh out errors.
I didn't get very far - 2/48 causes some failures in cimtest
...
diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h index 2803d6a..147551a 100644 --- a/libxkutil/device_parsing.h +++ b/libxkutil/device_parsing.h @@ -33,6 +33,33 @@
#include "../src/svpc_types.h"
+/* The structure for saving unknown tag in the xml */ +enum others_type { + TYPE_PROP, + TYPE_NODE +}; + +struct others { There's an extra space after the { which git am complains about
+ /* To identify the different tags with same name */ + int id; + char *name; + int parent_id; + char *parent_name; + enum others_type type; + char *value; + struct others *next; + enum status { + ACTIVE, + INACTIVE + }; Older compiler complains:
../libxkutil/device_parsing.h:54: warning: declaration does not declare anything
New compiler where I don't ignore warnings stops:
In file included from device_parsing.c:33:0: device_parsing.h:54:10: error: declaration does not declare anything [-Werror] }; ^ cc1: all warnings being treated as errors
I'll have to see more to determine whether I like this pointer to pointer within structures... There's usually some assumption somewhere which causes a failure...
John Dear John, My idea is, using a data structure (a link list) to keep the elements left after all kinds of virtual devices fetched tags they needed from xml. And if I just mark a node of others with status instead of delete it, the whole structure of xml could be saved as well. The introduction of 'id' in 'others' structure is to identify several <tags> with the same name. The console device support new introduced and some tags in 'unknown_device' have to use 'id' to identify elements. It maybe a little coarse now so I need any suggestion from you to make it works better. If you have any better idea to solve
于 2013/11/13 8:59, John Ferlan 写道: the unsupported tags missing issue please share with me :-) Because so many patches about it merged and there will be more in the future. These 48 patches just the first part in my designing. After that I want to build the management about all data (even in 'others' member). And all of these updates are compatitable with older version libvirt-cim. So the upper layer need little change and keep the original feature but could make libvirt-cim becomes more powerful. XFAIL about hotplug disappeared after updated. About the warning you mentioned above I'll check and fix it in the new version. Thanks, Xu Wang
+}; + +/* 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 +83,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,6 +98,7 @@ struct net_device { uint64_t reservation; uint64_t limit; struct vsi_device vsi; + struct others *others; };
struct mem_device { @@ -78,16 +107,19 @@ struct mem_device { enum { MEM_DUMP_CORE_NOT_SET, MEM_DUMP_CORE_ON, MEM_DUMP_CORE_OFF } dumpCore; + 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 { @@ -95,12 +127,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 { @@ -109,6 +143,7 @@ struct graphics_device { struct vnc_device vnc; struct sdl_device sdl; } dev; + struct others *others; };
struct path_device { @@ -146,11 +181,13 @@ struct console_device { struct udp_device udp; } source_dev; char *target_type; + struct others *others; };
struct input_device { char *type; char *bus; + struct others *others; };
struct virt_device { @@ -164,6 +201,7 @@ struct virt_device { struct graphics_device graphics; struct console_device console; struct input_device input; + struct unknown_device unknown; } dev; char *id; }; @@ -239,6 +277,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);

On 11/12/2013 10:27 PM, Xu Wang wrote:
于 2013/11/13 8:59, John Ferlan 写道: Dear John, My idea is, using a data structure (a link list) to keep the elements left after all kinds of virtual devices fetched tags they needed from xml. And if I just mark a node of others with status instead of delete it, the whole structure of xml could be saved as well. The introduction of 'id' in 'others' structure is to identify several <tags> with the same name. The console device support new introduced and some tags in 'unknown_device' have to use 'id' to identify elements. It maybe a little coarse now so I need any suggestion from you to make it works better. If you have any better idea to solve the unsupported tags missing issue please share with me :-) Because so many patches about it merged and there will be more in the future. These 48 patches just the first part in my designing. After that I want to build the management about all data (even in 'others' member). And all of these updates are compatitable with older version libvirt-cim. So the upper layer need little change and keep the original feature but could make libvirt-cim becomes more powerful. XFAIL about hotplug disappeared after updated. About the warning you mentioned above I'll check and fix it in the new version.
Thanks, Xu Wang
I don't have any thoughts on better ideas - it's just not my focus. There's a lot of changes being made in this series which I suppose in hindsight would have been nice to have been broken up a bit more to make it manageable to review, understand, and test. I've started with the first 3 patches as it seems all they do is create infrastructure and "for the most part" no one should be calling them. I started with patch 1... got to patch 2 and had issues. I ran patch 2 through coverity and it complained about the memset() in cleanup_virt_device(). A recent patch changed that from "memset(&dev->dev, 0, sizeof(dev->dev));" to "memset(dev, 0, sizeof(*dev));". Coverity complained about the path from "classify_resources()" for CIM_RES_TYPE_DISK into the rasd_to_vdev() call, then into _sysvirt_rasd_to_vdev(), disk_rasd_to_vdev(), and finally cleanup_virt_device(). It seems the change to device_parsing.h, inclusion by Virt_VirtualSystemManagementService.c, and usage of virt_device as a static structure caused the "issue" as a "clean" build fixed things. Although it took a while for me to figure it out. I suppose that's more a build/Makefile issue than anything else... The second issue I've run into is that by only applying the first two patches, I can get a test to cause cimprovagt to fail: -------------------------------------------------------------------- VirtualSystemManagementService - 16_removeresource.py: FAIL ERROR - (1, u'CIM_ERR_FAILED: Lost connection with cimprovagt "libvirt-cim".') InvokeMethod(RemoveResourceSettings): CIM_ERR_FAILED: Lost connection with cimprovagt "libvirt-cim". -------------------------------------------------------------------- This one's really frustrating as I'm really perplexed why a possible fix could work. It seems if I don't call cleanup_others() from cleanup_unknown_device(), then I don't get that core. I have no idea why though. Is it possibly related to the static usage of virt_device? I see this even after a clean build. Maybe this "cleanup_unknown_device()" and it's counter-part "dev_unknown" should have been added after the others work. It seems there are two things being done at once - creating an 'others' list to store the read xml and creating a list of unknown devices. You've done a lot of work and it seems promising as a way handle new tags. Of course I ask myself why is it so important to go through this exercise. Are the libvirt API's deficient? I would think libvirt should be the only thing handling XML format and the applications that use libvirt would have API's to create, define, get, set, start, stop, etc VM's. Having to store the XML is "dangerous" insomuch as we've already found it can change and libvirt-cim cannot keep up. Anyway, as an exercise for me to learn and because I pushed a number of changes which conflict with what you've already done... I will try to help with the effort to compact each patch series into manageable parts. FWIW: I pushed the other patches because they were posted first - I just went in order. John

Since I started to work on libvirt-cim almost every bug is about new tags support. My first patch is about <shareable> in the <disk>. The second one is <dumpCore> in the <memory>. And other one coming soon is <model> in <cpu>, and endless like this. So I got a mission that is designing/implementing a long term solution to solve this category of bug. So I have a dream, even re-write all content of libxutil/device_parsing.c and libxutil/xmlgen.c to reach that goal. I'll continue to work on the issues you found. And update the design unsuitable. I'll make a new version after finished. Just rebasing work is a little boring. Thank you for taking so much time to review and test them. Thanks, Xu Wang 于 2013/11/14 7:08, John Ferlan 写道:
On 11/12/2013 10:27 PM, Xu Wang wrote:
于 2013/11/13 8:59, John Ferlan 写道: Dear John, My idea is, using a data structure (a link list) to keep the elements left after all kinds of virtual devices fetched tags they needed from xml. And if I just mark a node of others with status instead of delete it, the whole structure of xml could be saved as well. The introduction of 'id' in 'others' structure is to identify several <tags> with the same name. The console device support new introduced and some tags in 'unknown_device' have to use 'id' to identify elements. It maybe a little coarse now so I need any suggestion from you to make it works better. If you have any better idea to solve the unsupported tags missing issue please share with me :-) Because so many patches about it merged and there will be more in the future. These 48 patches just the first part in my designing. After that I want to build the management about all data (even in 'others' member). And all of these updates are compatitable with older version libvirt-cim. So the upper layer need little change and keep the original feature but could make libvirt-cim becomes more powerful. XFAIL about hotplug disappeared after updated. About the warning you mentioned above I'll check and fix it in the new version.
Thanks, Xu Wang I don't have any thoughts on better ideas - it's just not my focus. There's a lot of changes being made in this series which I suppose in hindsight would have been nice to have been broken up a bit more to make it manageable to review, understand, and test. I've started with the first 3 patches as it seems all they do is create infrastructure and "for the most part" no one should be calling them.
I started with patch 1... got to patch 2 and had issues. I ran patch 2 through coverity and it complained about the memset() in cleanup_virt_device().
A recent patch changed that from "memset(&dev->dev, 0, sizeof(dev->dev));" to "memset(dev, 0, sizeof(*dev));". Coverity complained about the path from "classify_resources()" for CIM_RES_TYPE_DISK into the rasd_to_vdev() call, then into _sysvirt_rasd_to_vdev(), disk_rasd_to_vdev(), and finally cleanup_virt_device().
It seems the change to device_parsing.h, inclusion by Virt_VirtualSystemManagementService.c, and usage of virt_device as a static structure caused the "issue" as a "clean" build fixed things. Although it took a while for me to figure it out. I suppose that's more a build/Makefile issue than anything else...
The second issue I've run into is that by only applying the first two patches, I can get a test to cause cimprovagt to fail:
-------------------------------------------------------------------- VirtualSystemManagementService - 16_removeresource.py: FAIL ERROR - (1, u'CIM_ERR_FAILED: Lost connection with cimprovagt "libvirt-cim".') InvokeMethod(RemoveResourceSettings): CIM_ERR_FAILED: Lost connection with cimprovagt "libvirt-cim". --------------------------------------------------------------------
This one's really frustrating as I'm really perplexed why a possible fix could work. It seems if I don't call cleanup_others() from cleanup_unknown_device(), then I don't get that core. I have no idea why though. Is it possibly related to the static usage of virt_device? I see this even after a clean build.
Maybe this "cleanup_unknown_device()" and it's counter-part "dev_unknown" should have been added after the others work. It seems there are two things being done at once - creating an 'others' list to store the read xml and creating a list of unknown devices.
You've done a lot of work and it seems promising as a way handle new tags. Of course I ask myself why is it so important to go through this exercise. Are the libvirt API's deficient? I would think libvirt should be the only thing handling XML format and the applications that use libvirt would have API's to create, define, get, set, start, stop, etc VM's. Having to store the XML is "dangerous" insomuch as we've already found it can change and libvirt-cim cannot keep up.
Anyway, as an exercise for me to learn and because I pushed a number of changes which conflict with what you've already done... I will try to help with the effort to compact each patch series into manageable parts. FWIW: I pushed the other patches because they were posted first - I just went in order.
John

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 54 insertions(+), 0 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index aecca4c..f1da880 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -63,6 +63,49 @@ /* Device parse function */ typedef int (*dev_parse_func_t)(xmlNode *, struct virt_device **); +void cleanup_node_of_others(struct others *others) +{ + if (others == NULL) { + return; + } + + if (others->name) { + free(others->name); + } + + if (others->parent_name) { + free(others->parent_name); + } + + if (others->value) { + free(others->value); + } + + free(others); +} + +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) @@ -77,6 +120,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) @@ -107,6 +151,7 @@ static void cleanup_net_device(struct net_device *dev) free(dev->filter_ref); free(dev->poolid); cleanup_vsi_device(&dev->vsi); + cleanup_others(dev->others); } static void cleanup_emu_device(struct emu_device *dev) @@ -115,6 +160,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) @@ -123,6 +169,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) @@ -130,6 +177,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) @@ -143,6 +191,7 @@ static void cleanup_graphics_device(struct graphics_device *dev) cleanup_vnc_device(dev); free(dev->type); + cleanup_others(dev->others); } static void cleanup_path_device(struct path_device *dev) @@ -228,6 +277,7 @@ static void cleanup_console_device(struct console_device *dev) dev->source_type = 0; free(dev->target_type); memset(&dev->source_dev, 0, sizeof(dev->source_dev)); + cleanup_others(dev->others); }; static void console_device_dup(struct console_device *t, @@ -286,6 +336,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) @@ -305,6 +356,8 @@ void cleanup_virt_device(struct virt_device *dev) cleanup_input_device(&dev->dev.input); else if (dev->type == CIM_RES_TYPE_CONSOLE) cleanup_console_device(&dev->dev.console); + else if (dev->type == CIM_RES_TYPE_UNKNOWN) + cleanup_unknown_device(&dev->dev.unknown); free(dev->id); @@ -1693,6 +1746,7 @@ void cleanup_dominfo(struct domain **dominfo) 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_console, dom->dev_console_ct); + cleanup_virt_devices(&dom->dev_unknown, dom->dev_unknown_ct); free(dom); -- 1.7.1

On 10/27/2013 10:45 PM, Xu Wang wrote:
Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 54 insertions(+), 0 deletions(-)
If I apply the cimtest patches from Viktor, I get cimtest failures after applying this patch. That's about as far as I've had time to dig. It seems cimprovagt cores and for some reason the abrt isn't saving things... The failures are in: -------------------------------------------------------------------- RASDIndications - 02_guest_add_mod_rem_rasd_ind.py: FAIL ERROR - Exception details :(1, u'CIM_ERR_FAILED: Lost connection with cimprovagt "libvirt-cim".') ERROR - Exception: Unable to generate indication InvokeMethod(RemoveResourceSettings): CIM_ERR_FAILED: Lost connection with cimprovagt "libvirt-cim". -------------------------------------------------------------------- SettingsDefine - 01_forward.py: FAIL ERROR - 6 device insts != 7 RASD insts -------------------------------------------------------------------- SettingsDefine - 02_reverse.py: FAIL ERROR - u'KVM_ConsoleDisplayController' -------------------------------------------------------------------- VirtualSystemManagementService - 16_removeresource.py: FAIL ERROR - (1, u'CIM_ERR_FAILED: Lost connection with cimprovagt "libvirt-cim".') InvokeMethod(RemoveResourceSettings): CIM_ERR_FAILED: Lost connection with cimprovagt "libvirt-cim". -------------------------------------------------------------------- I'll investigate more in my morning.. FWIW: This is on a RHEL6.5 host that I'm borrowing...
diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index aecca4c..f1da880 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -63,6 +63,49 @@ /* Device parse function */ typedef int (*dev_parse_func_t)(xmlNode *, struct virt_device **);
+void cleanup_node_of_others(struct others *others)
static void
+{ + if (others == NULL) { + return; + } + + if (others->name) { + free(others->name); + } + + if (others->parent_name) { + free(others->parent_name); + } + + if (others->value) { + free(others->value); + } + + free(others); +} + +void cleanup_others(struct others *others)
static void
+{ + struct others *head = others; + + if (others == NULL) + return;
Since we'd only enter the while loop if head (or others) were non NULL the above isn't really necessary
+ + while (head) { + head = others->next; + cleanup_node_of_others(others); + others = head; + }
while (others) { next = others->next; cleanup_node_of_others(others); others = next; } Have to figure out why cimprovagt dies, I'm assuming it's in this logic somewhere... John
+} + +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) @@ -77,6 +120,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) @@ -107,6 +151,7 @@ static void cleanup_net_device(struct net_device *dev) free(dev->filter_ref); free(dev->poolid); cleanup_vsi_device(&dev->vsi); + cleanup_others(dev->others); }
static void cleanup_emu_device(struct emu_device *dev) @@ -115,6 +160,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) @@ -123,6 +169,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) @@ -130,6 +177,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) @@ -143,6 +191,7 @@ static void cleanup_graphics_device(struct graphics_device *dev) cleanup_vnc_device(dev);
free(dev->type); + cleanup_others(dev->others); }
static void cleanup_path_device(struct path_device *dev) @@ -228,6 +277,7 @@ static void cleanup_console_device(struct console_device *dev) dev->source_type = 0; free(dev->target_type); memset(&dev->source_dev, 0, sizeof(dev->source_dev)); + cleanup_others(dev->others); };
static void console_device_dup(struct console_device *t, @@ -286,6 +336,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) @@ -305,6 +356,8 @@ void cleanup_virt_device(struct virt_device *dev) cleanup_input_device(&dev->dev.input); else if (dev->type == CIM_RES_TYPE_CONSOLE) cleanup_console_device(&dev->dev.console); + else if (dev->type == CIM_RES_TYPE_UNKNOWN) + cleanup_unknown_device(&dev->dev.unknown);
free(dev->id);
@@ -1693,6 +1746,7 @@ void cleanup_dominfo(struct domain **dominfo) 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_console, dom->dev_console_ct); + cleanup_virt_devices(&dom->dev_unknown, dom->dev_unknown_ct);
free(dom);

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 297 ++++++++++++++++++++++++++++++++++++++++++++ libxkutil/device_parsing.h | 25 ++++- 2 files changed, 320 insertions(+), 2 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index f1da880..e95b0a9 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -404,6 +404,303 @@ char *get_node_content(xmlNode *node) return buf; } +/* + * This function is just used for debugging. If you found something wrong + * please call this function and check the result of output in the logs. + */ +void print_others(struct others *head) +{ + CU_DEBUG("**************************************************"); + while (head) { + CU_DEBUG("---------------------------"); + CU_DEBUG("- others id: %d", head->id); + 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_id: %d", head->parent_id); + CU_DEBUG("- others parent_name: %s", head->parent_name); + if (head->status == ACTIVE) { + CU_DEBUG("- others status: ACTIVE"); + } else { + CU_DEBUG("- others status: INACTIVE"); + } + CU_DEBUG("---------------------------"); + head = head->next; + } + CU_DEBUG("**************************************************"); +} + +/* + * Add one node into head link list. All items are set as parameters. + * + * @head: The link list head pointer to be added. + * @node: Where the value of node come from. + * @name: Name of this link list node (maybe a node or an attribute in xml). + * @type: TYPE_NODE: Stands for the value from a xml node. + * TYPE_PROP: Means that this value is an attribute of a node. + * @parent_id: The id of parent node. + * @parent_name: Name of parent node. + */ +static struct others *add_others(struct others *head, + xmlNode *node, + const xmlChar *name, + enum others_type type, + int parent_id, + const xmlChar *parent_name) +{ + struct others *new = NULL; + struct others *end = head; + + new = calloc(1, sizeof(*new)); + if (new == NULL) { + CU_DEBUG("calloc space failed."); + return NULL; + } + + new->id = 0; + new->name = strdup((char *)name); + new->parent_id = parent_id; + if (parent_name) { + new->parent_name = strdup((char *)parent_name); + } + 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 { + /* Seek to the end of link list and calculate conflicts */ + while (end) { + if (STREQ(end->name, (char *)name) && + end->type == type) { + /* id conflict, +1 */ + new->id++; + } + if (end->next) { + end = end->next; + } else { + break; + } + } + end->next = new; + } + new->status = ACTIVE; + + return head; +} + +bool compare_param_int(int a, int b) +{ + if (a == -1 || b == -1) { + return true; + } else if (a == b) { + return true; + } else { + return false; + } +} + +bool compare_param_str(const char *a, const char *b) +{ + if (a == NULL || b == NULL) { + return true; + } else if (STREQ(a, b)) { + return true; + } else { + return false; + } +} + +/* + * This function is the main operation for members of virtual device structure. + * The whole data of xml is saved in the others link list. By calling this + * function each variable of virtual device could get the value it wanted. + * After value was fetched, the node in the others link list to be INACTIVE + * status. + * + * @head: The link list saved all data needed. + * @id: Id of name, to identify different nodes but with same name. + * @name: Name of node the caller want to get value. + * @type: TYPE_NODE: Caller want to get a value of node. + * TYPE_PROP: Caller want to get a value of attribute. + * @parent_id: The id of parent node caller want. + * @parent_name: The name of parent node caller want. + * + * If caller doesn't want to point @id, @parent_id or @parent_name, + * @id could be set as -1, @parent_id and @parent_name should be + * set as NULL. + */ +char *fetch_from_others(struct others **head, + int id, + char *name, + enum others_type type, + int parent_id, + char *parent_name) +{ + struct others *tmp = *head; + char *value = NULL; + + while (tmp) { + if (compare_param_int(tmp->id, id) && + STREQ(tmp->name, name) && + compare_param_int(tmp->parent_id, parent_id) && + compare_param_str(tmp->parent_name, parent_name) && + tmp->type == type && + tmp->status == ACTIVE) { + value = strdup(tmp->value); + tmp->status = INACTIVE; + return value; + } + tmp = tmp->next; + } + + return NULL; +} + +/* + * This function seeks in the others link list and return the result of + * seeking. If success the node seeked will to be INACTIVE status. + * + * @head: The link list head pointer to be seeked. + * @id: Id of node to be seeked. + * @name: Name of node to be seeked. + * @type: TYPE_NODE: The node to be seeked is a node of xml. + * TYPE_PROP: The node to be seeked is a attribute of a node. + * @parent_id: Id of parent node which to be seeked. + * @parent_name: Name of parent node which to be seeked. + * + * If the caller doesn't point @id, @parent_id or @parent_name, they should + * be set as -1, -1 or NULL. Other parameters is mandantory. + */ +static bool seek_in_others(struct others **head, + int id, + char *name, + enum others_type type, + int parent_id, + char *parent_name) +{ + struct others *tmp = *head; + + while (tmp) { + if (compare_param_int(tmp->id, id) && + STREQ(tmp->name, name) && + compare_param_int(tmp->parent_id, parent_id) && + compare_param_str(tmp->parent_name, parent_name) && + tmp->type == type && + tmp->status == ACTIVE) { + tmp->status = INACTIVE; + return true; + } + 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 *seek_to_tail(struct others *others) +{ + if (others == NULL) { + return NULL; + } + + while (others->next) { + others = others->next; + } + + return others; +} + +/* + * Parse all data from xml and build a link list to save it. + * + * @head: Where data from xml to save. + * @node: The root node of xml to be parsed. + * @parent_id: Parent node id of root node, usually zero. + * @parent_name: Parent node name of root node. + */ +static struct others *parse_data_to_others(struct others *head, + xmlNode *node, + int parent_id, + const xmlChar *parent_name) +{ + xmlNode *child = NULL; + xmlAttrPtr attrPtr = NULL; + struct others *tail = NULL; + int tail_id = 0; + + /* If name of node is "text", all operations will skip */ + if (XSTREQ(node->name, "text")) { + return head; + } + + head = add_others(head, + node, + node->name, + TYPE_NODE, + parent_id, + parent_name); + + if (head == NULL) { + goto err; + } + + /* tail is the node we added above */ + tail = seek_to_tail(head); + if (tail == NULL) { + tail_id = 0; + } else { + tail_id = tail->id; + } + + /* Get properties of node */ + attrPtr = node->properties; + while (attrPtr) { + head = add_others(head, + node, + attrPtr->name, + TYPE_PROP, + tail_id, + 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 */ + head = parse_data_to_others(head, child, tail_id, node->name); + } + + 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 147551a..ee9b515 100644 --- a/libxkutil/device_parsing.h +++ b/libxkutil/device_parsing.h @@ -48,10 +48,10 @@ struct others { enum others_type type; char *value; struct others *next; - enum status { + enum { ACTIVE, INACTIVE - }; + } status; }; /* The structure for saving unknown device */ @@ -310,6 +310,27 @@ int attach_device(virDomainPtr dom, struct virt_device *dev); int detach_device(virDomainPtr dom, struct virt_device *dev); int change_device(virDomainPtr dom, struct virt_device *dev); +char *fetch_from_others(struct others **head, + int id, + char *name, + enum others_type type, + int parent_id, + char *parent_name); + +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); + +bool compare_param_int(int a, int b); + +bool compare_param_str(const char *a, const char *b); + #define XSTREQ(x, y) (STREQ((char *)x, y)) #define STRPROP(d, p, n) (d->p = get_node_content(n)) -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 101 ++++++++++++++++++++++++++++++++++--------- 1 files changed, 80 insertions(+), 21 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index e95b0a9..adb3146 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -705,7 +705,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) @@ -713,35 +714,93 @@ 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(ddev->others, + dnode, + 0, + 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, + -1, + "filesystem", + TYPE_NODE, + -1, + "devices"); + + ddev->type = fetch_from_others(&ddev->others, + -1, + "type", + TYPE_PROP, + -1, + (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, + -1, + "accessmode", + TYPE_PROP, + -1, + (char *)dnode->name); + + if (seek_in_others(&ddev->others, + -1, + "source", + TYPE_NODE, + -1, + (char *)dnode->name)) { + ddev->source = fetch_from_others(&ddev->others, + -1, + "dir", + TYPE_PROP, + -1, + "source"); + + + if (ddev->source == NULL) { + CU_DEBUG("no source dir"); + goto err; + } + } - 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, + -1, + "target", + TYPE_NODE, + -1, + (char *)dnode->name)) { + ddev->virtual_dev = fetch_from_others(&ddev->others, + -1, + "dir", + TYPE_PROP, + -1, + "target"); + + if (ddev->virtual_dev == NULL) { + CU_DEBUG("no target 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, + -1, + "driver", + TYPE_NODE, + -1, + (char *)dnode->name)) { + ddev->driver_type = fetch_from_others(&ddev->others, + -1, + "type", + TYPE_PROP, + -1, + "driver"); } ddev->disk_type = DISK_FS; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 168 ++++++++++++++++++++++++++++++++++++-------- 1 files changed, 137 insertions(+), 31 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index adb3146..6ab8131 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -824,7 +824,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) @@ -832,45 +833,150 @@ 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(ddev->others, + dnode, + 0, + 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, + -1, + "disk", + TYPE_NODE, + -1, + "devices"); + + ddev->type = fetch_from_others(&ddev->others, + -1, + "type", + TYPE_PROP, + -1, + (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, + -1, + "device", + TYPE_PROP, + -1, + (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) - 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; - } + if (seek_in_others(&ddev->others, + -1, + "driver", + TYPE_NODE, + -1, + (char *)dnode->name)) { + ddev->driver = fetch_from_others(&ddev->others, + -1, + "name", + TYPE_PROP, + -1, + "driver"); + + if (ddev->driver == NULL) { + CU_DEBUG("no driver name"); goto err; - } else if (XSTREQ(child->name, "target")) { - ddev->virtual_dev = get_attr_value(child, "dev"); - if (ddev->virtual_dev == NULL) + } + + ddev->driver_type = fetch_from_others(&ddev->others, + -1, + "type", + TYPE_PROP, + -1, + "driver"); + + ddev->cache = fetch_from_others(&ddev->others, + -1, + "cache", + TYPE_PROP, + -1, + "driver"); + } + + if (seek_in_others(&ddev->others, + -1, + "source", + TYPE_NODE, + -1, + (char *)dnode->name)) { + ddev->source = fetch_from_others(&ddev->others, + -1, + "file", + TYPE_PROP, + -1, + "source"); + if (ddev->source == NULL) { + ddev->source = fetch_from_others(&ddev->others, + -1, + "dev", + TYPE_PROP, + -1, + "source"); + + if (ddev->source == NULL) { + CU_DEBUG("no source file/dev"); 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; + } else { + ddev->disk_type == DISK_PHY; + } + } else { + ddev->disk_type = DISK_FILE; } } + if (seek_in_others(&ddev->others, + -1, + "target", + TYPE_NODE, + -1, + (char *)dnode->name)) { + ddev->virtual_dev = fetch_from_others(&ddev->others, + -1, + "dev", + TYPE_PROP, + -1, + "target"); + + if (ddev->virtual_dev == NULL) { + CU_DEBUG("no target dev"); + goto err; + } + + ddev->bus_type = fetch_from_others(&ddev->others, + -1, + "bus", + TYPE_PROP, + -1, + "target"); + } + + ddev->readonly = seek_in_others(&ddev->others, + -1, + "readonly", + TYPE_NODE, + -1, + (char *)dnode->name); + + ddev->shareable = seek_in_others(&ddev->others, + -1, + "shareable", + TYPE_NODE, + -1, + (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 | 89 ++++++++++++++++++++++++++++++++----------- 1 files changed, 66 insertions(+), 23 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 6ab8131..bc6c649 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1014,40 +1014,83 @@ 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, + -1, + "type", + TYPE_PROP, + -1, + "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, + -1, + "parameters", + TYPE_NODE, + -1, + "virtualport")) { + vsi_dev->manager_id = fetch_from_others(others, + -1, + "managerid", + TYPE_PROP, + -1, + "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, + -1, + "typeid", + TYPE_PROP, + -1, + "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, + -1, + "typeidversion", + TYPE_PROP, + -1, + "parameters"); - vsi_dev->instance_id = get_attr_value(child, - "instanceid"); - vsi_dev->profile_id = get_attr_value(child, - "profileid"); - } + if (vsi_dev->type_id_version == NULL) { + CU_DEBUG("no typeidversion"); + goto err; + } + + vsi_dev->instance_id = fetch_from_others(others, + -1, + "instanceid", + TYPE_PROP, + -1, + "parameters"); + + vsi_dev->profile_id = fetch_from_others(others, + -1, + "profileid", + TYPE_PROP, + -1, + "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 | 261 +++++++++++++++++++++++++++++++++----------- 1 files changed, 196 insertions(+), 65 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index bc6c649..4f52bbf 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1107,90 +1107,221 @@ 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(ndev->others, + inode, + 0, + 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, + -1, + "interface", + TYPE_NODE, + -1, + "devices"); + + ndev->type = fetch_from_others(&ndev->others, + -1, + "type", + TYPE_PROP, + -1, + (char *)inode->name); + + if (ndev->type == NULL) { + CU_DEBUG("no type"); + goto err; + } + + if (seek_in_others(&ndev->others, + -1, + "mac", + TYPE_NODE, + -1, + (char *)inode->name)) { + ndev->mac = fetch_from_others(&ndev->others, + -1, + "address", + TYPE_PROP, + -1, + "mac"); + + if (ndev->mac == NULL) { + CU_DEBUG("no mac address"); + goto err; + } + } + + if (seek_in_others(&ndev->others, + -1, + "source", + TYPE_NODE, + -1, + (char *)inode->name)) { + ndev->source = fetch_from_others(&ndev->others, + -1, + "bridge", + TYPE_PROP, + -1, + "source"); + + if (ndev->source == NULL) { + ndev->source = fetch_from_others(&ndev->others, + -1, + "network", + TYPE_PROP, + -1, + "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, + -1, + "dev", + TYPE_PROP, + -1, + "source"); + + ndev->net_mode = fetch_from_others(&ndev->others, + -1, + "mode", + TYPE_PROP, + -1, + "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, + -1, + "target", + TYPE_NODE, + -1, + (char *)inode->name)) { + ndev->device = fetch_from_others(&ndev->others, + -1, + "dev", + TYPE_PROP, + -1, + "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, + -1, + "model", + TYPE_NODE, + -1, + (char *)inode->name)) { + ndev->model = fetch_from_others(&ndev->others, + -1, + "type", + TYPE_PROP, + -1, + "model"); + if (ndev->model == NULL) { + CU_DEBUG("no model type."); + goto err; + } + } + + if (seek_in_others(&ndev->others, + -1, + "filterref", + TYPE_NODE, + -1, + (char *)inode->name)) { + ndev->filter_ref = fetch_from_others(&ndev->others, + -1, + "filter", + TYPE_PROP, + -1, + "filterref"); + } + + if (seek_in_others(&ndev->others, -1, "virtualport", + TYPE_NODE, -1, (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, + -1, + "bandwidth", + TYPE_NODE, + -1, + (char *)inode->name) && + seek_in_others(&ndev->others, + -1, + "inbound", + TYPE_NODE, + -1, + "bandwidth")) { + val = fetch_from_others(&ndev->others, + -1, + "average", + TYPE_PROP, + -1, + "inbound"); + + if (val != NULL) { + sscanf(val, "%" PRIu64, &ndev->reservation); + free(val); + } else { + ndev->reservation = 0; } -#endif + val = fetch_from_others(&ndev->others, + -1, + "peak", + TYPE_PROP, + -1, + "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 | 25 ++++++++++++++++++++----- 1 files changed, 20 insertions(+), 5 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 4f52bbf..4ef3bd1 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1345,7 +1345,26 @@ 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(list->dev.vcpu.others, + node, + 0, + BAD_CAST "domain"); + + count_str = fetch_from_others(&list->dev.vcpu.others, + -1, + "vcpu", + TYPE_NODE, + -1, + "domain"); + if (count_str == NULL) count = 1; /* Default to 1 VCPU if non specified */ else if (sscanf(count_str, "%i", &count) != 1) @@ -1353,10 +1372,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 | 23 ++++++++++++++++++++--- 1 files changed, 20 insertions(+), 3 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 4ef3bd1..6d91198 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1391,15 +1391,32 @@ 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(edev->others, + node, + 0, + BAD_CAST "devices"); + + edev->path = fetch_from_others(&edev->others, + -1, + (char *)node->name, + TYPE_NODE, + -1, + "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 | 42 +++++++++++++++++++++++++++++++++++++----- 1 files changed, 37 insertions(+), 5 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 6d91198..0323fb5 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1437,20 +1437,50 @@ static int parse_mem_device(xmlNode *node, struct virt_device **vdevs) char *content = NULL; char *tmpval = NULL; int ret = 0; + 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(new_others, + node, + 0, + BAD_CAST "domain"); + mdev->others = combine_others(mdev->others, new_others); + + if (XSTREQ(node->name, "currentMemory")) { + content = fetch_from_others(&mdev->others, + -1, + "currentMemory", + TYPE_NODE, + -1, + "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, + -1, + "memory", + TYPE_NODE, + -1, + "domain"); + sscanf(content, "%" PRIu64, &mdev->maxsize); - tmpval = get_attr_value(node, "dumpCore"); + + tmpval = fetch_from_others(&mdev->others, + -1, + "dumpCore", + TYPE_PROP, + -1, + "memory"); + if (tmpval && XSTREQ(tmpval, "on")) { mdev->dumpCore = MEM_DUMP_CORE_ON; } else if (tmpval && XSTREQ(content, "off")) { @@ -1458,6 +1488,8 @@ static int parse_mem_device(xmlNode *node, struct virt_device **vdevs) } else { mdev->dumpCore = MEM_DUMP_CORE_NOT_SET; } + } else { + /* do nothing */ } *vdevs = vdev; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 273 +++++++++++++++++++++++++++++++++----------- 1 files changed, 206 insertions(+), 67 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 0323fb5..b8fcc7b 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1522,18 +1522,38 @@ static int parse_console_device(xmlNode *node, struct virt_device **vdevs) char *source_type_str = NULL; char *target_port_ID = NULL; char *udp_source_mode = NULL; + int id; - xmlNode *child = NULL; + CU_DEBUG("Enter parse_graphics_device()."); vdev = calloc(1, sizeof(*vdev)); - if (vdev == NULL) + if (vdev == NULL) { + CU_DEBUG("calloc failed."); goto err; + } cdev = &(vdev->dev.console); - source_type_str = get_attr_value(node, "type"); - if (source_type_str == NULL) + cdev->others = parse_data_to_others(cdev->others, + node, + 0, + BAD_CAST "devices"); + if (cdev->others == NULL) { + CU_DEBUG("parse data to others failed."); + goto err; + } + + source_type_str = fetch_from_others(&cdev->others, + -1, + "type", + TYPE_PROP, + -1, + (char *)node->name); + + if (source_type_str == NULL) { + CU_DEBUG("no type"); goto err; + } CU_DEBUG("console device type = %s", source_type_str ? : "NULL"); cdev->source_type = chardev_source_type_StrToID(source_type_str); @@ -1542,85 +1562,204 @@ static int parse_console_device(xmlNode *node, struct virt_device **vdevs) CU_DEBUG("console device type ID = %d", cdev->source_type); - for (child = node->children; child != NULL; child = child->next) { - if (XSTREQ(child->name, "target")) { - cdev->target_type = get_attr_value(child, "type"); - CU_DEBUG("Console device target type = '%s'", - cdev->target_type ? : "NULL"); - target_port_ID = get_attr_value(child, "port"); - if (target_port_ID == NULL) - goto err; - } + if (seek_in_others(&cdev->others, + -1, + "target", + TYPE_NODE, + -1, + (char *)node->name)) { + cdev->target_type = fetch_from_others(&cdev->others, + -1, + "type", + TYPE_PROP, + -1, + "target"); + CU_DEBUG("Console device target type = '%s'", + cdev->target_type ? : "NULL"); - if (XSTREQ(child->name, "source")) { - switch (cdev->source_type) - { - case CIM_CHARDEV_SOURCE_TYPE_PTY: - cdev->source_dev.pty.path = - get_attr_value(child, "path"); - break; - case CIM_CHARDEV_SOURCE_TYPE_DEV: - cdev->source_dev.dev.path = - get_attr_value(child, "path"); - break; - case CIM_CHARDEV_SOURCE_TYPE_FILE: - cdev->source_dev.file.path = - get_attr_value(child, "path"); - break; - case CIM_CHARDEV_SOURCE_TYPE_PIPE: - cdev->source_dev.pipe.path = - get_attr_value(child, "path"); - break; - case CIM_CHARDEV_SOURCE_TYPE_UNIXSOCK: - cdev->source_dev.unixsock.mode = - get_attr_value(child, "mode"); - cdev->source_dev.unixsock.path = - get_attr_value(child, "path"); - break; - case CIM_CHARDEV_SOURCE_TYPE_UDP: - udp_source_mode = get_attr_value(child, "mode"); + target_port_ID = fetch_from_others(&cdev->others, + -1, + "port", + TYPE_PROP, + -1, + "target"); + if (target_port_ID == NULL) + goto err; + } + + if (seek_in_others(&cdev->others, + 0, + "source", + TYPE_NODE, + -1, + (char *)node->name)) { + switch (cdev->source_type) + { + case CIM_CHARDEV_SOURCE_TYPE_PTY: + cdev->source_dev.pty.path = + fetch_from_others(&cdev->others, + -1, + "path", + TYPE_PROP, + -1, + "source"); + break; + case CIM_CHARDEV_SOURCE_TYPE_DEV: + cdev->source_dev.dev.path = + fetch_from_others(&cdev->others, + -1, + "path", + TYPE_PROP, + -1, + "source"); + break; + case CIM_CHARDEV_SOURCE_TYPE_FILE: + cdev->source_dev.file.path = + fetch_from_others(&cdev->others, + -1, + "path", + TYPE_PROP, + -1, + "source"); + break; + case CIM_CHARDEV_SOURCE_TYPE_PIPE: + cdev->source_dev.pipe.path = + fetch_from_others(&cdev->others, + -1, + "path", + TYPE_PROP, + -1, + "source"); + break; + case CIM_CHARDEV_SOURCE_TYPE_UNIXSOCK: + cdev->source_dev.unixsock.mode = + fetch_from_others(&cdev->others, + -1, + "mode", + TYPE_PROP, + -1, + "source"); + cdev->source_dev.unixsock.path = + fetch_from_others(&cdev->others, + -1, + "path", + TYPE_PROP, + -1, + "source"); + break; + case CIM_CHARDEV_SOURCE_TYPE_UDP: + /* Something different from other cases. It has two + * <source> tags with mode="bind" and "connect" value. + * Hence here id MUST NOT be ignored. + */ + + /* Just fetch out another <source> tag but we need to do + * nothing with it. + */ + fetch_from_others(&cdev->others, + 1, + "source", + TYPE_NODE, + -1, + "console"); + + for (id = 0; id < 2; id++) { + udp_source_mode = + fetch_from_others(&cdev->others, + -1, + "mode", + TYPE_PROP, + id, + "source"); if (udp_source_mode == NULL) goto err; + if (STREQC(udp_source_mode, "bind")) { cdev->source_dev.udp.bind_host = - get_attr_value(child, "host"); + fetch_from_others(&cdev->others, + -1, + "host", + TYPE_PROP, + id, + "source"); cdev->source_dev.udp.bind_service = - get_attr_value(child, "service"); + fetch_from_others(&cdev->others, + -1, + "service", + TYPE_PROP, + id, + "source"); } else if (STREQC(udp_source_mode, "connect")) { cdev->source_dev.udp.connect_host = - get_attr_value(child, "host"); + fetch_from_others(&cdev->others, + -1, + "host", + TYPE_PROP, + id, + "source"); cdev->source_dev.udp.connect_service = - get_attr_value(child, "service"); + fetch_from_others(&cdev->others, + -1, + "service", + TYPE_PROP, + id, + "source"); } else { CU_DEBUG("unknown udp mode: %s", udp_source_mode ? : "NULL"); goto err; } - break; - case CIM_CHARDEV_SOURCE_TYPE_TCP: - cdev->source_dev.tcp.mode = - get_attr_value(child, "mode"); - cdev->source_dev.tcp.host = - get_attr_value(child, "host"); - cdev->source_dev.tcp.service = - get_attr_value(child, "service"); - break; - - default: - /* Nothing to do for : - CIM_CHARDEV_SOURCE_TYPE_STDIO - CIM_CHARDEV_SOURCE_TYPE_NULL - CIM_CHARDEV_SOURCE_TYPE_VC - CIM_CHARDEV_SOURCE_TYPE_SPICEVMC - */ - break; } + break; + case CIM_CHARDEV_SOURCE_TYPE_TCP: + cdev->source_dev.tcp.mode = + fetch_from_others(&cdev->others, + -1, + "mode", + TYPE_PROP, + -1, + "source"); + cdev->source_dev.tcp.host = + fetch_from_others(&cdev->others, + -1, + "host", + TYPE_PROP, + -1, + "source"); + cdev->source_dev.tcp.service = + fetch_from_others(&cdev->others, + -1, + "service", + TYPE_PROP, + -1, + "source"); + break; + + default: + /* Nothing to do for : + CIM_CHARDEV_SOURCE_TYPE_STDIO + CIM_CHARDEV_SOURCE_TYPE_NULL + CIM_CHARDEV_SOURCE_TYPE_VC + CIM_CHARDEV_SOURCE_TYPE_SPICEVMC + */ + break; } - if ((cdev->source_type == CIM_CHARDEV_SOURCE_TYPE_TCP) - && XSTREQ(child->name, "protocol")) { - cdev->source_dev.tcp.protocol = - get_attr_value(child, "type"); - } + } + + if ((cdev->source_type == CIM_CHARDEV_SOURCE_TYPE_TCP) + && seek_in_others(&cdev->others, + -1, + "protocol", + TYPE_NODE, + -1, + (char *)node->name)) { + cdev->source_dev.tcp.protocol = + fetch_from_others(&cdev->others, + -1, + "type", + TYPE_PROP, + -1, + "protocol"); } vdev->type = CIM_RES_TYPE_CONSOLE; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 152 ++++++++++++++++++++++++++++++++++--------- 1 files changed, 120 insertions(+), 32 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index b8fcc7b..4225153 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1504,17 +1504,6 @@ static int parse_mem_device(xmlNode *node, struct virt_device **vdevs) return ret; } -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_console_device(xmlNode *node, struct virt_device **vdevs) { struct virt_device *vdev = NULL; @@ -1790,28 +1779,92 @@ 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(gdev->others, + node, + 0, + 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, + -1, + "graphics", + TYPE_NODE, + -1, + "devices"); + fetch_from_others(&gdev->others, + -1, + "serial", + TYPE_NODE, + -1, + "devices"); + + gdev->type = fetch_from_others(&gdev->others, + -1, + "type", + TYPE_PROP, + -1, + (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, + -1, + "port", + TYPE_PROP, + -1, + (char *)node->name); + + if (gdev->dev.vnc.port == NULL) { + gdev->dev.vnc.port = strdup("-1"); + } + + gdev->dev.vnc.host = fetch_from_others(&gdev->others, + -1, + "listen", + TYPE_PROP, + -1, + (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, + -1, + "keymap", + TYPE_PROP, + -1, + (char *)node->name); + + gdev->dev.vnc.passwd = fetch_from_others(&gdev->others, + -1, + "passwd", + TYPE_PROP, + -1, + (char *)node->name); if (gdev->dev.vnc.port == NULL || gdev->dev.vnc.host == NULL) { CU_DEBUG("Error vnc port '%p' host '%p'", @@ -1820,9 +1873,26 @@ 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, + -1, + "display", + TYPE_PROP, + -1, + (char *)node->name); + + gdev->dev.sdl.xauth = fetch_from_others(&gdev->others, + -1, + "xauth", + TYPE_PROP, + -1, + (char *)node->name); + + gdev->dev.sdl.fullscreen = fetch_from_others(&gdev->others, + -1, + "fullscreen", + TYPE_PROP, + -1, + (char *)node->name); } else if (STREQC(gdev->type, "pty")) { if (node->name == NULL) @@ -1833,14 +1903,32 @@ static int parse_graphics_device(xmlNode *node, struct virt_device **vdevs) 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, + -1, + "source", + TYPE_NODE, + -1, + (char *)node->name)) { + gdev->dev.vnc.host = fetch_from_others(&gdev->others, + -1, + "path", + TYPE_PROP, + -1, + "source"); + } + + if (seek_in_others(&gdev->others, + -1, + "target", + TYPE_NODE, + -1, + (char *)node->name)) { + gdev->dev.vnc.port = fetch_from_others(&gdev->others, + -1, + "port", + TYPE_PROP, + -1, + "target"); } } else { -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 files changed, 37 insertions(+), 3 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 4225153..bb92241 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1964,14 +1964,48 @@ 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(idev->others, + node, + 0, + 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, + -1, + "input", + TYPE_NODE, + -1, + "devices"); + + idev->type = fetch_from_others(&idev->others, + -1, + "type", + TYPE_PROP, + -1, + (char *)node->name); + + idev->bus = fetch_from_others(&idev->others, + -1, + "bus", + TYPE_PROP, + -1, + (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 | 55 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 55 insertions(+), 0 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index bb92241..5e9ecb4 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -2028,6 +2028,61 @@ 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(udev->others, + child, + 0, + 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 | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 5e9ecb4..8f1a46c 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -49,6 +49,7 @@ #define GRAPHICS_XPATH (xmlChar *)"/domain/devices/graphics | "\ "/domain/devices/console" #define INPUT_XPATH (xmlChar *)"/domain/devices/input" +#define UNKNOWN_XPATH (xmlChar *)"/domain/devices" #define DEFAULT_BRIDGE "xenbr0" #define DEFAULT_NETWORK "default" @@ -2206,6 +2207,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; @@ -2674,6 +2680,9 @@ int get_dominfo_from_xml(const char *xml, struct domain **dominfo) (*dominfo)->dev_vcpu_ct = parse_devices(xml, &(*dominfo)->dev_vcpu, CIM_RES_TYPE_PROC); + (*dominfo)->dev_unknown_ct = parse_devices(xml, + &(*dominfo)->dev_unknown, + CIM_RES_TYPE_UNKNOWN); return ret; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 162 ++++++++++++++++++++++++++++++++++++------- 1 files changed, 135 insertions(+), 27 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 8f1a46c..0bd3cfa 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -2564,10 +2564,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) { - char *action = (char *)xmlNodeGetContent(child); - if (action == NULL) *val = CIM_VSSD_RECOVERY_NONE; else if (STREQ(action, "destroy")) @@ -2578,38 +2576,148 @@ static void set_action(int *val, xmlNode *child) *val = CIM_VSSD_RECOVERY_RESTART; else *val = CIM_VSSD_RECOVERY_NONE; - - xmlFree(action); } static int parse_domain(xmlNodeSet *nsv, struct domain *dominfo) { xmlNode **nodes = nsv->nodeTab; xmlNode *child; + xmlAttrPtr xmlAttr = 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, + 0, + nodes[0]->name); + xmlAttr = xmlAttr->next; + } + + dominfo->typestr = fetch_from_others(&dominfo->others, + -1, + "type", + TYPE_PROP, + -1, + (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 { + dominfo->others = parse_data_to_others(dominfo->others, + child, + 0, + nodes[0]->name); + } + } - dominfo->typestr = get_attr_value(nodes[0], "type"); + dominfo->name = fetch_from_others(&dominfo->others, + -1, + "name", + TYPE_NODE, + -1, + (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, + -1, + "uuid", + TYPE_NODE, + -1, + (char *)nodes[0]->name); + + dominfo->bootloader = fetch_from_others(&dominfo->others, + -1, + "bootloader", + TYPE_NODE, + -1, + (char *)nodes[0]->name); + + dominfo->bootloader_args = fetch_from_others(&dominfo->others, + -1, + "bootloader_args", + TYPE_NODE, + -1, + (char *)nodes[0]->name); + + if (seek_in_others(&dominfo->others, + -1, + "os", + TYPE_NODE, + -1, + (char *)nodes[0]->name)) { + /* parse_os(); */ + } + + action = fetch_from_others(&dominfo->others, + -1, + "on_poweroff", + TYPE_NODE, + -1, + (char *)nodes[0]->name); + if (action) { + set_action(&dominfo->on_poweroff, action); + free(action); + } + + action = fetch_from_others(&dominfo->others, + -1, + "on_reboot", + TYPE_NODE, + -1, + (char *)nodes[0]->name); + if (action) { + set_action(&dominfo->on_reboot, action); + free(action); + } + + action = fetch_from_others(&dominfo->others, + -1, + "on_crash", + TYPE_NODE, + -1, + (char *)nodes[0]->name); + if (action) { + set_action(&dominfo->on_crash, action); + free(action); + } + + if (seek_in_others(&dominfo->others, + -1, + "clock", + TYPE_NODE, + -1, + (char *)nodes[0]->name)) { + dominfo->clock = fetch_from_others(&dominfo->others, + -1, + "offset", + TYPE_PROP, + -1, + "clock"); + } + + if (seek_in_others(&dominfo->others, + -1, + "features", + TYPE_NODE, + -1, + (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 | 117 ++++++++++++++++++++++++++++++++------------ 1 files changed, 85 insertions(+), 32 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 0bd3cfa..ced167f 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -2445,9 +2445,8 @@ static void cleanup_bootlist(char **blist, unsigned blist_ct) free(blist); } -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; char *arch = NULL; @@ -2459,39 +2458,93 @@ static int parse_os(struct domain *dominfo, xmlNode *os) char *boot = NULL; char *init = NULL; - for (child = os->children; child != NULL; child = child->next) { - if (XSTREQ(child->name, "type")) { - STRPROP(dominfo, os_info.pv.type, child); - arch = get_attr_value(child, "arch"); - machine = get_attr_value(child, "machine"); - } else if (XSTREQ(child->name, "kernel")) - kernel = get_node_content(child); - else if (XSTREQ(child->name, "initrd")) - initrd = get_node_content(child); - else if (XSTREQ(child->name, "cmdline")) - cmdline = get_node_content(child); - else if (XSTREQ(child->name, "loader")) - loader = get_node_content(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; + CU_DEBUG("Enter parse_os()"); + + dominfo->os_info.pv.type = fetch_from_others(&dominfo->others, + 0, + "type", + TYPE_NODE, + 0, + "os"); + if (dominfo->os_info.pv.type) { + arch = fetch_from_others(&dominfo->others, + -1, + "arch", + TYPE_PROP, + -1, + "type"); + + machine = fetch_from_others(&dominfo->others, + -1, + "machine", + TYPE_PROP, + -1, + "type"); + } + + dominfo->os_info.pv.kernel = fetch_from_others(&dominfo->others, + -1, + "kernel", + TYPE_NODE, + -1, + "os"); + + dominfo->os_info.pv.initrd = fetch_from_others(&dominfo->others, + -1, + "initrd", + TYPE_NODE, + -1, + "os"); + + dominfo->os_info.pv.cmdline = fetch_from_others(&dominfo->others, + -1, + "cmdline", + TYPE_NODE, + -1, + "os"); + + dominfo->os_info.fv.loader = fetch_from_others(&dominfo->others, + -1, + "loader", + TYPE_NODE, + -1, + "os"); + + if (seek_in_others(&dominfo->others, + -1, + "boot", + TYPE_NODE, + -1, + "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] = get_attr_value(child, "dev"); + blist[bl_size] = fetch_from_others(&dominfo->others, + -1, + "dev", + TYPE_PROP, + -1, + "boot"); bl_size++; - } else if (XSTREQ(child->name, "init")) - init = get_node_content(child); + } } + dominfo->os_info.lxc.init = fetch_from_others(&dominfo->others, + -1, + "init", + TYPE_NODE, + -1, + "os"); + if ((STREQC(dominfo->os_info.fv.type, "hvm")) && (STREQC(dominfo->typestr, "xen"))) dominfo->type = DOMAIN_XENFV; @@ -2661,7 +2714,7 @@ static int parse_domain(xmlNodeSet *nsv, struct domain *dominfo) TYPE_NODE, -1, (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 | 38 ++++++++++++++++++++++++++++---------- 1 files changed, 28 insertions(+), 10 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index ced167f..21d2ef3 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -2601,17 +2601,35 @@ 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()"); - 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, + -1, + "acpi", + TYPE_NODE, + -1, + "features")) { + dominfo->acpi = true; + } + + if (seek_in_others(&dominfo->others, + -1, + "apic", + TYPE_NODE, + -1, + "features")) { + dominfo->apic = true; + } + + if (seek_in_others(&dominfo->others, + -1, + "pae", + TYPE_NODE, + -1, + "features")) { + dominfo->pae = true; } return 1; @@ -2770,7 +2788,7 @@ static int parse_domain(xmlNodeSet *nsv, struct domain *dominfo) TYPE_NODE, -1, (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 | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 51 insertions(+), 0 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 21d2ef3..2b713de 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -2242,6 +2242,49 @@ static int parse_devices(const char *xml, struct virt_device **_list, int type) return count; } +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_name = NULL; + new_node->next = NULL; + + if (head == NULL) { + head = new_node; + } else { + new_node->next = head; + head = new_node; + } + + new_node->id = others->id; + DUP_FIELD(new_node, others, name); + DUP_FIELD(new_node, others, value); + new_node->parent_id = others->parent_id; + DUP_FIELD(new_node, others, parent_name); + 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; @@ -2271,6 +2314,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); @@ -2284,25 +2328,32 @@ 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); } else if (dev->type == CIM_RES_TYPE_CONSOLE) { console_device_dup(&dev->dev.console, &_dev->dev.console); + dev->dev.console.others = dup_others(_dev->dev.console.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 d51f230..70ca1b7 100644 --- a/src/Virt_VirtualSystemManagementService.c +++ b/src/Virt_VirtualSystemManagementService.c @@ -3001,7 +3001,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 0f46a86..5c1f6eb 100644 --- a/src/svpc_types.h +++ b/src/svpc_types.h @@ -33,6 +33,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 #define CIM_RES_TYPE_CONSOLE 32769 -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 231 insertions(+), 0 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 7e8801d..d1e1c94 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -42,6 +42,237 @@ 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); +/* + * Parse all attributes of node into xml. + * + * @node: The root node. + * @head: The link list saved all data to be parsed. + * @parent_id: Node id of attributes. + * @parent_name: Node name of attributes. + * + * If @parent_id or @parent_name is not as a condition, plese set them into + * -1 or NULL. + */ +static struct others *props_to_xml(xmlNodePtr node, + struct others *head, + int parent_id, + const char *parent_name) +{ + struct others *tmp = head; + + if (head == NULL) { + CU_DEBUG("others is null."); + goto out; + } + + while (tmp) { + if (compare_param_int(tmp->parent_id, parent_id) && + compare_param_str(tmp->parent_name, parent_name) && + tmp->type == TYPE_PROP && + tmp->status == ACTIVE) { + xmlNewProp(node, BAD_CAST tmp->name, BAD_CAST tmp->value); + tmp->status = INACTIVE; + } + tmp = tmp->next; + } + +out: + return head; +} + +/* + * Parse all data in others link list to a xml data structure. + * The link list returned after operation. + * + * @root: The root node of xml to be built. + * @head: The link list saved all data needed. + * @parent_id: Parent node id of root node. + * @parent_name: Parent node name of root node. + * + * @parent_id/@parent_name is not mandatory (please set them + * as -1/NULL) but others not. + */ +static struct others *others_to_xml(xmlNodePtr root, + struct others *head, + int parent_id, + const char *parent_name) +{ + struct others *tmp = head; + 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_param_int(tmp->parent_id, parent_id) && + compare_param_str(tmp->parent_name, parent_name) && + tmp->type == TYPE_NODE && + tmp->status == ACTIVE) { + new_node = xmlNewChild(root, NULL, + BAD_CAST tmp->name, + BAD_CAST tmp->value); + + if (new_node == NULL) { + CU_DEBUG("xmlNewChild failed."); + goto out; + } + + tmp->status = INACTIVE; + + /* find all properties of this node and build new tag in xml */ + head = props_to_xml(new_node, + head, + tmp->id, + (char *)new_node->name); + + /* recursive build sub node of tmp */ + head = others_to_xml(new_node, + head, + tmp->id, + (char *)new_node->name); + + } + tmp = tmp->next; + } + +out: + return head; +} + +/* + * Restore data in the member of virtual device structure back to others link + * list. The new link list would be returned after operation finished. + * + * @head: The link list data to be added into. + * @id: Id of new node to be added. + * @name: Name of new node to be added. + * @value: Value of new node to be added. + * @type: Type of new node to be added. + * TYPE_NODE: The value is from a node of xml. + * TYPE_PROP: The value is from a attribute of a node. + * @parent_id: Parent node id of new node to be added. + * @parent_name: Parent node name of new node to be added. + * + * Among parameters above @id/@parent_id/@parent_name is not + * mandatory. They should be set as -1/-1/NULL if caller needn't + * set them. + */ +static struct others *add_node_to_others(struct others *head, + int id, + const char *name, + const char *value, + enum others_type type, + int parent_id, + const char *parent_name) +{ + struct others *tmp = head; + struct others *new_node = NULL; + + /* Check if there is such a node with INACTIVE status in others */ + while (tmp) { + if (compare_param_int(tmp->id, id) && + STREQ(tmp->name, name) && + tmp->type == type && + compare_param_int(tmp->parent_id, parent_id) && + compare_param_str(tmp->parent_name, parent_name) && + tmp->status == INACTIVE) { + if (tmp->value) { + free(tmp->value); + } + if (value) { + tmp->value = strdup(value); + } else { + tmp->value = NULL; + } + tmp->status = ACTIVE; + + return head; + } + tmp = tmp->next; + } + + /* Create a new node */ + new_node = calloc(1, sizeof(*new_node)); + if (new_node == NULL) { + CU_DEBUG("calloc failed."); + return NULL; + } + + new_node->id = id; + + 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; + + new_node->parent_id = parent_id; + + if (parent_name) { + new_node->parent_name = strdup(parent_name); + } else { + new_node->parent_name = NULL; + } + + if (head == NULL) { + new_node->next = NULL; + } else { + new_node->next = head; + } + + return new_node; +} + +static int get_id_of_others(struct others *others, + const char *name, + const char *value, + enum others_type type, + int parent_id, + const char *parent_name) +{ + struct others *tmp = others; + + while (tmp) { + if (STREQ(tmp->name, name) && + compare_param_str(tmp->value, value) && + tmp->type == type && + compare_param_int(tmp->parent_id, parent_id) && + compare_param_str(tmp->parent_name, parent_name)) { + return tmp->id; + } + tmp = tmp->next; + } + + return -1; +} + +/* + * Check if there is node(s) with ACTIVE status. If such node(s) exists + * means operation failed. Some node of xml missed. + */ +static const char *check_others_active(struct others *others) +{ + while (others) { + if (others->status == ACTIVE) { + return "There are active nodes in others."; + } + others = others->next; + } + + return NULL; +} + static const char *console_xml(xmlNodePtr root, struct domain *dominfo) { int i; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 334 ++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 261 insertions(+), 73 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index d1e1c94..f5fe4a4 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -276,8 +276,9 @@ static const char *check_others_active(struct others *others) static const char *console_xml(xmlNodePtr root, struct domain *dominfo) { int i; - xmlNodePtr console; - xmlNodePtr tmp; + int mode_id; + + CU_DEBUG("Enter disk_block_xml()"); for (i = 0; i < dominfo->dev_console_ct; i++) { struct virt_device *_dev = &dominfo->dev_console[i]; @@ -286,108 +287,279 @@ static const char *console_xml(xmlNodePtr root, struct domain *dominfo) struct console_device *cdev = &_dev->dev.console; - console = xmlNewChild(root, NULL, BAD_CAST "console", NULL); - if (console == NULL) + cdev->others = add_node_to_others(cdev->others, + 0, + "console", + NULL, + TYPE_NODE, + 0, + "devices"); + + if (cdev->others == NULL) { + CU_DEBUG("Add tag <disk> failed."); return XML_ERROR; + } - xmlNewProp(console, BAD_CAST "type", - BAD_CAST - chardev_source_type_IDToStr(cdev->source_type)); + cdev->others = add_node_to_others(cdev->others, + 0, + "type", + chardev_source_type_IDToStr( + cdev->source_type), + TYPE_PROP, + 0, + "console"); switch (cdev->source_type) { case CIM_CHARDEV_SOURCE_TYPE_PTY: /* The path property is not mandatory */ if (cdev->source_dev.pty.path) { - tmp = xmlNewChild(console, NULL, - BAD_CAST "source", NULL); - if (tmp == NULL) + cdev->others = add_node_to_others(cdev->others, + 0, + "source", + NULL, + TYPE_NODE, + 0, + "console"); + if (cdev->others == NULL) return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "path", - BAD_CAST cdev->source_dev.pty.path); + + cdev->others = add_node_to_others(cdev->others, + 0, + "path", + cdev->source_dev.pty.path, + TYPE_PROP, + 0, + "source"); } break; case CIM_CHARDEV_SOURCE_TYPE_DEV: - tmp = xmlNewChild(console, NULL, - BAD_CAST "source", NULL); - if (tmp == NULL) + cdev->others = add_node_to_others(cdev->others, + 0, + "source", + NULL, + TYPE_NODE, + 0, + "console"); + if (cdev->others == NULL) return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "path", - BAD_CAST cdev->source_dev.dev.path); + + cdev->others = add_node_to_others(cdev->others, + 0, + "path", + cdev->source_dev.dev.path, + TYPE_PROP, + 0, + "source"); break; case CIM_CHARDEV_SOURCE_TYPE_FILE: - tmp = xmlNewChild(console, NULL, - BAD_CAST "source", NULL); - if (tmp == NULL) + cdev->others = add_node_to_others(cdev->others, + 0, + "source", + NULL, + TYPE_NODE, + 0, + "console"); + if (cdev->others == NULL) return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "path", - BAD_CAST cdev->source_dev.file.path); + + cdev->others = add_node_to_others(cdev->others, + 0, + "path", + cdev->source_dev.file.path, + TYPE_PROP, + 0, + "source"); break; case CIM_CHARDEV_SOURCE_TYPE_PIPE: - tmp = xmlNewChild(console, NULL, - BAD_CAST "source", NULL); - if (tmp == NULL) + cdev->others = add_node_to_others(cdev->others, + 0, + "source", + NULL, + TYPE_NODE, + 0, + "console"); + if (cdev->others == NULL) return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "path", - BAD_CAST cdev->source_dev.pipe.path); + + cdev->others = add_node_to_others(cdev->others, + 0, + "path", + cdev->source_dev.pipe.path, + TYPE_PROP, + 0, + "source"); break; case CIM_CHARDEV_SOURCE_TYPE_UNIXSOCK: - tmp = xmlNewChild(console, NULL, - BAD_CAST "source", NULL); - if (tmp == NULL) + cdev->others = add_node_to_others(cdev->others, + 0, + "source", + NULL, + TYPE_NODE, + 0, + "console"); + if (cdev->others == NULL) return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "mode", - BAD_CAST cdev->source_dev.unixsock.mode); - xmlNewProp(tmp, BAD_CAST "path", - BAD_CAST cdev->source_dev.unixsock.path); + + cdev->others = add_node_to_others(cdev->others, + 0, + "mode", + cdev->source_dev.unixsock.mode, + TYPE_PROP, + 0, + "source"); + + cdev->others = add_node_to_others(cdev->others, + 0, + "path", + cdev->source_dev.unixsock.path, + TYPE_PROP, + 0, + "source"); break; case CIM_CHARDEV_SOURCE_TYPE_UDP: - tmp = xmlNewChild(console, NULL, - BAD_CAST "source", NULL); - if (tmp == NULL) + mode_id = get_id_of_others(cdev->others, + "mode", + "bind", + TYPE_PROP, + 0, + "source"); + if (mode_id == -1) { + CU_DEBUG("get id of mode failed"); + return NULL; + } + + cdev->others = add_node_to_others(cdev->others, + mode_id, + "source", + NULL, + TYPE_NODE, + 0, + "console"); + if (cdev->others == NULL) return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "mode", BAD_CAST "bind"); - xmlNewProp(tmp, BAD_CAST "host", - BAD_CAST cdev->source_dev.udp.bind_host); + + cdev->others = add_node_to_others(cdev->others, + 0, + "mode", + "bind", + TYPE_PROP, + mode_id, + "source"); + + cdev->others = add_node_to_others(cdev->others, + 0, + "host", + cdev->source_dev.udp.bind_host, + TYPE_PROP, + mode_id, + "source"); + /* The service property is not mandatory */ if (cdev->source_dev.udp.bind_service) - xmlNewProp(tmp, BAD_CAST "service", - BAD_CAST - cdev->source_dev.udp.bind_service); - - tmp = xmlNewChild(console, NULL, - BAD_CAST "source", NULL); - if (tmp == NULL) + cdev->others = + add_node_to_others(cdev->others, + 0, + "service", + cdev->source_dev.udp.bind_service, + TYPE_PROP, + mode_id, + "source"); + + cdev->others = add_node_to_others(cdev->others, + 1 - mode_id, + "source", + NULL, + TYPE_NODE, + 0, + "console"); + if (cdev->others == NULL) return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "mode", BAD_CAST "connect"); - xmlNewProp(tmp, BAD_CAST "host", - BAD_CAST cdev->source_dev.udp.connect_host); + + cdev->others = add_node_to_others(cdev->others, + 0, + "mode", + "connect", + TYPE_PROP, + 1 - mode_id, + "source"); + + cdev->others = add_node_to_others(cdev->others, + 0, + "host", + cdev->source_dev.udp.connect_host, + TYPE_PROP, + 1 - mode_id, + "source"); + /* The service property is not mandatory */ if (cdev->source_dev.udp.connect_service) - xmlNewProp(tmp, BAD_CAST "service", - BAD_CAST - cdev->source_dev.udp.connect_service); + cdev->others = + add_node_to_others(cdev->others, + 0, + "service", + cdev->source_dev.udp.connect_service, + TYPE_PROP, + 1 - mode_id, + "source"); break; case CIM_CHARDEV_SOURCE_TYPE_TCP: - tmp = xmlNewChild(console, NULL, - BAD_CAST "source", NULL); - if (tmp == NULL) + cdev->others = add_node_to_others(cdev->others, + 0, + "source", + NULL, + TYPE_NODE, + 0, + "console"); + if (cdev->others == NULL) return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "mode", - BAD_CAST cdev->source_dev.tcp.mode); - xmlNewProp(tmp, BAD_CAST "host", - BAD_CAST cdev->source_dev.tcp.host); + + cdev->others = add_node_to_others(cdev->others, + 0, + "mode", + cdev->source_dev.tcp.mode, + TYPE_PROP, + 0, + "source"); + + cdev->others = add_node_to_others(cdev->others, + 0, + "host", + cdev->source_dev.tcp.host, + TYPE_PROP, + 0, + "source"); + if (cdev->source_dev.tcp.service) - xmlNewProp(tmp, BAD_CAST "service", - BAD_CAST - cdev->source_dev.tcp.service); + cdev->others = + add_node_to_others(cdev->others, + 0, + "service", + cdev->source_dev.tcp.service, + TYPE_PROP, + 0, + "source"); + if (cdev->source_dev.tcp.protocol) { - tmp = xmlNewChild(console, NULL, - BAD_CAST "protocol", NULL); - if (tmp == NULL) + cdev->others = + add_node_to_others(cdev->others, + 0, + "protocol", + NULL, + TYPE_NODE, + 0, + "console"); + + if (cdev->others == NULL) return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "type", - BAD_CAST cdev->source_dev.tcp.protocol); + cdev->others = + add_node_to_others(cdev->others, + 0, + "type", + cdev->source_dev.tcp.protocol, + TYPE_PROP, + 0, + "protocol"); } break; default: @@ -401,14 +573,30 @@ static const char *console_xml(xmlNodePtr root, struct domain *dominfo) } if (cdev->target_type) { - tmp = xmlNewChild(console, NULL, - BAD_CAST "target", NULL); - if (tmp == NULL) + cdev->others = add_node_to_others(cdev->others, + 0, + "target", + NULL, + TYPE_NODE, + 0, + "console"); + if (cdev->others == NULL) return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "type", - BAD_CAST cdev->target_type); + cdev->others = add_node_to_others(cdev->others, + 0, + "type", + cdev->target_type, + TYPE_PROP, + 0, + "target"); + } + + cdev->others = others_to_xml(root, cdev->others, 0, "devices"); + if (check_others_active(cdev->others)) { + return "xml generation failed."; } } + return NULL; } -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 172 +++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 143 insertions(+), 29 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index f5fe4a4..c7dbefb 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -602,49 +602,163 @@ static const char *console_xml(xmlNodePtr root, struct domain *dominfo) 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, + 0, + "disk", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "type", + "block", + TYPE_PROP, + 0, + "disk"); + + if (dev->device) { + dev->others = add_node_to_others(dev->others, + 0, + "device", + dev->device, + TYPE_PROP, + 0, + "disk"); + } if (dev->driver) { - tmp = xmlNewChild(disk, NULL, BAD_CAST "driver", NULL); - if (tmp == NULL) + dev->others = add_node_to_others(dev->others, + 0, + "driver", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "name", + dev->driver, + TYPE_PROP, + 0, + "driver"); + + if (dev->driver_type) { + dev->others = add_node_to_others(dev->others, + 0, + "type", + dev->driver_type, + TYPE_PROP, + 0, + "driver"); + } + + if (dev->cache) { + dev->others = add_node_to_others(dev->others, + 0, + "cache", + dev->cache, + TYPE_PROP, + 0, + "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, + 0, + "source", + NULL, + TYPE_NODE, + 0, + "disk"); + + if (dev->others == NULL) { + CU_DEBUG("add tag <source> failed."); + return XML_ERROR; + } - tmp = xmlNewChild(disk, NULL, BAD_CAST "target", NULL); - if (tmp == NULL) + dev->others = add_node_to_others(dev->others, + 0, + "dev", + dev->source, + TYPE_PROP, + 0, + "source"); + } + + dev->others = add_node_to_others(dev->others, + 0, + "target", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "dev", + dev->virtual_dev, + TYPE_PROP, + 0, + "target"); - if (dev->shareable) - xmlNewChild(disk, NULL, BAD_CAST "shareable", NULL); + if (dev->bus_type) { + dev->others = add_node_to_others(dev->others, + 0, + "bus", + dev->bus_type, + TYPE_PROP, + 0, + "target"); + } - return NULL; + if (dev->readonly) { + dev->others = add_node_to_others(dev->others, + 0, + "readonly", + NULL, + TYPE_NODE, + 0, + "disk"); + } + + if (dev->shareable) { + dev->others = add_node_to_others(dev->others, + 0, + "shareable", + NULL, + TYPE_NODE, + 0, + "disk"); + } + + dev->others = others_to_xml(root, dev->others, 0, "devices"); + + if (check_others_active(dev->others)) { + return XML_ERROR; + } else { + return NULL; + } } static const char *disk_file_xml(xmlNodePtr root, struct disk_device *dev) -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 164 +++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 136 insertions(+), 28 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index c7dbefb..f721ac7 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -763,26 +763,80 @@ 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, + 0, + "disk", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "type", + "file", + TYPE_PROP, + 0, + "disk"); + + if (dev->device) { + dev->others = add_node_to_others(dev->others, + 0, + "device", + dev->device, + TYPE_PROP, + 0, + "disk"); + } if (dev->driver) { - tmp = xmlNewChild(disk, NULL, BAD_CAST "driver", NULL); - if (tmp == NULL) + dev->others = add_node_to_others(dev->others, + 0, + "driver", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "name", + dev->driver, + TYPE_PROP, + 0, + "driver"); + + if (dev->driver_type) { + dev->others = add_node_to_others(dev->others, + 0, + "type", + dev->driver_type, + TYPE_PROP, + 0, + "driver"); + } + + if (dev->cache) { + dev->others = add_node_to_others(dev->others, + 0, + "cache", + dev->cache, + TYPE_PROP, + 0, + "driver"); + } } if (dev->device != NULL && XSTREQ(dev->device, "cdrom") && @@ -792,28 +846,82 @@ 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, + 0, + "source", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "file", + dev->source, + TYPE_PROP, + 0, + "source"); } - tmp = xmlNewChild(disk, NULL, BAD_CAST "target", NULL); - if (tmp == NULL) + dev->others = add_node_to_others(dev->others, + 0, + "target", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "dev", + dev->virtual_dev, + TYPE_PROP, + 0, + "target"); - if (dev->readonly) - xmlNewChild(disk, NULL, BAD_CAST "readonly", NULL); + if (dev->bus_type) { + dev->others = add_node_to_others(dev->others, + 0, + "bus", + dev->bus_type, + TYPE_PROP, + 0, + "target"); + } - if (dev->shareable) - xmlNewChild(disk, NULL, BAD_CAST "shareable", NULL); + if (dev->readonly) { + dev->others = add_node_to_others(dev->others, + 0, + "readonly", + NULL, + TYPE_NODE, + 0, + "disk"); + } + + if (dev->shareable) { + dev->others = add_node_to_others(dev->others, + 0, + "shareable", + NULL, + TYPE_NODE, + 0, + "disk"); + } + dev->others = others_to_xml(root, dev->others, 0, "devices"); - return NULL; + return check_others_active(dev->others); } static const char *disk_fs_xml(xmlNodePtr root, struct disk_device *dev) -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 94 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 80 insertions(+), 14 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index f721ac7..3350e80 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -926,12 +926,20 @@ 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, + 0, + "filesystem", + NULL, + TYPE_NODE, + 0, + "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. */ @@ -940,25 +948,83 @@ 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, + 0, + "accessmode", + dev->access_mode, + TYPE_PROP, + 0, + "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, + 0, + "driver", + NULL, + TYPE_NODE, + 0, + "filesystem"); + + if (dev->others == NULL) { + CU_DEBUG("add node <driver> failed."); + return XML_ERROR; + } + + dev->others = add_node_to_others(dev->others, + 0, + "type", + dev->driver_type, + TYPE_PROP, + 0, + "driver"); } - tmp = xmlNewChild(fs, NULL, BAD_CAST "source", NULL); - if (tmp == NULL) + dev->others = add_node_to_others(dev->others, + 0, + "source", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "dir", + dev->source, + TYPE_PROP, + 0, + "source"); + + dev->others = add_node_to_others(dev->others, + 0, + "target", + NULL, + TYPE_NODE, + 0, + "filesystem"); + + if (dev->others == NULL) { + CU_DEBUG("add node <target> failed."); return XML_ERROR; - xmlNewProp(tmp, BAD_CAST "dir", BAD_CAST dev->virtual_dev); + } - return NULL; + dev->others = add_node_to_others(dev->others, + 0, + "dir", + dev->virtual_dev, + TYPE_PROP, + 0, + "target"); + + dev->others = others_to_xml(root, dev->others, 0, "devices"); + + return check_others_active(dev->others); } static const char *disk_xml(xmlNodePtr root, struct domain *dominfo) -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 107 ++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 84 insertions(+), 23 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 3350e80..a963ca3 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1057,35 +1057,96 @@ 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; - - tmp = xmlNewChild(nic, NULL, BAD_CAST "virtualport", NULL); - if (tmp == NULL) + CU_DEBUG("Enter set_net_vsi()"); + + *others = add_node_to_others(*others, + 0, + "virtualport", + NULL, + TYPE_NODE, + 0, + 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, + 0, + "type", + dev->vsi_type, + TYPE_PROP, + 0, + "virtualport"); + + *others = add_node_to_others(*others, + 0, + "parameters", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "profileid", + dev->profile_id, + TYPE_PROP, + 0, + "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, + 0, + "managerid", + dev->manager_id, + TYPE_PROP, + 0, + "parameters"); + } + + if (dev->type_id != NULL) { + *others = add_node_to_others(*others, + 0, + "typeid", + dev->type_id, + TYPE_PROP, + 0, + "parameters"); + } + + if (dev->type_id_version != NULL) { + *others = add_node_to_others(*others, + 0, + "typeidversion", + dev->type_id_version, + TYPE_PROP, + 0, + "parameters"); + } + + if (dev->instance_id != NULL) { + *others = add_node_to_others(*others, + 0, + "instanceid", + dev->instance_id, + TYPE_PROP, + 0, + "parameters"); + } } return NULL; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 57 ++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 44 insertions(+), 13 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index a963ca3..3658d02 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1152,26 +1152,57 @@ 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, + 0, + "source", + NULL, + TYPE_NODE, + 0, + 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, + 0, + "dev", + dev->source, + TYPE_PROP, + 0, + "source"); + + if (dev->net_mode != NULL) { + *others = add_node_to_others(*others, + 0, + "mode", + dev->net_mode, + TYPE_PROP, + 0, + "source"); + } + } else { + *others = add_node_to_others(*others, + 0, + src_type, + dev->source, + TYPE_PROP, + 0, + "source"); + } + } else { return XML_ERROR; + } return NULL; } -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 30 +++++++++++++++++++++++------- 1 files changed, 23 insertions(+), 7 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 3658d02..74b4a0d 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1208,24 +1208,40 @@ 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, + 0, + "script", + NULL, + TYPE_NODE, + 0, + 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, + 0, + "path", + script, + TYPE_PROP, + 0, + "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 | 185 ++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 149 insertions(+), 36 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 74b4a0d..097a5c8 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1250,8 +1250,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]; @@ -1260,40 +1260,118 @@ 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, + 0, + "interface", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "type", + net->type, + TYPE_PROP, + 0, + "interface"); if (net->mac != NULL) { - tmp = xmlNewChild(nic, NULL, BAD_CAST "mac", NULL); - if (tmp == NULL) + net->others = add_node_to_others(net->others, + 0, + "mac", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "address", + net->mac, + TYPE_PROP, + 0, + "mac"); } if (net->device != NULL) { - tmp = xmlNewChild(nic, NULL, BAD_CAST "target", NULL); - if (tmp == NULL) + net->others = add_node_to_others(net->others, + 0, + "target", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "dev", + net->device, + TYPE_PROP, + 0, + "target"); } if (net->model != NULL) { - tmp = xmlNewChild(nic, NULL, BAD_CAST "model", NULL); - if (tmp == NULL) + net->others = add_node_to_others(net->others, + 0, + "model", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "type", + net->model, + TYPE_PROP, + 0, + "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, + 0, + "filterref", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "filter", + net->filter_ref, + TYPE_PROP, + 0, + "filterref"); } #if LIBVIR_VERSION_NUMBER >= 9000 @@ -1302,24 +1380,47 @@ 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, + 0, + "bandwidth", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "inbound", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "average", + string, + TYPE_PROP, + 0, + "inbound"); + free(string); } @@ -1328,28 +1429,40 @@ 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, + 0, + "peak", + string, + TYPE_PROP, + 0, + "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, 0, "devices"); + if (check_others_active(net->others)) { + return "xml generation failed."; + } } return msg; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 22 +++++++++++++++++----- 1 files changed, 17 insertions(+), 5 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 097a5c8..46bd8f4 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1471,10 +1471,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; @@ -1484,13 +1485,24 @@ 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, + 0, + "vcpu", + string, + TYPE_NODE, + 0, + "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 | 38 ++++++++++++++++++++++++++++---------- 1 files changed, 28 insertions(+), 10 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 46bd8f4..8e793f9 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1509,19 +1509,29 @@ 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, + 0, + "cputune", + NULL, + TYPE_NODE, + 0, + "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, @@ -1530,16 +1540,24 @@ 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, + 0, + "shares", + string, + TYPE_NODE, + 0, + "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 | 60 +++++++++++++++++++++++++++++++++++---------------- 1 files changed, 41 insertions(+), 19 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 8e793f9..cbc69be 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1564,10 +1564,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; @@ -1576,39 +1577,60 @@ 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, + 0, + "currentMemory", + string, + TYPE_NODE, + 0, + "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, + 0, + "memory", + string, + TYPE_NODE, + 0, + "domain"); free(string); - if (tmp == NULL) - return XML_ERROR; if (mem->dumpCore == MEM_DUMP_CORE_ON) { - xmlNewProp(tmp, BAD_CAST "dumpCore", BAD_CAST "on"); + mem->others = add_node_to_others(mem->others, + 0, + "dumpCore", + "on", + TYPE_PROP, + 0, + "memory"); } else if (mem->dumpCore == MEM_DUMP_CORE_OFF) { - xmlNewProp(tmp, BAD_CAST "dumpCore", BAD_CAST "off"); + mem->others = add_node_to_others(mem->others, + 0, + "dumpCore", + "off", + TYPE_PROP, + 0, + "memory"); } + 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 | 21 +++++++++++++++++---- 1 files changed, 17 insertions(+), 4 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index cbc69be..3855443 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1636,17 +1636,30 @@ 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, + 0, + "emulator", + emu->path, + TYPE_NODE, + 0, + "devices"); + + if (emu->others == NULL) { + CU_DEBUG("add node <emulator> failed."); return XML_ERROR; + } - return NULL; + emu->others = others_to_xml(root, emu->others, 0, "devices"); + + return check_others_active(emu->others); } static const char *graphics_vnc_xml(xmlNodePtr root, -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 127 +++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 105 insertions(+), 22 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 3855443..5979e96 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1665,48 +1665,131 @@ 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, + 0, + "graphics", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "type", + dev->type, + TYPE_PROP, + 0, + "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, + 0, + "display", + dev->dev.sdl.display, + TYPE_PROP, + 0, + "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, + 0, + "xauth", + dev->dev.sdl.xauth, + TYPE_PROP, + 0, + "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, + 0, + "fullscreen", + dev->dev.sdl.fullscreen, + TYPE_PROP, + 0, + "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, + 0, + "port", + dev->dev.vnc.port, + TYPE_PROP, + 0, + "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, + 0, + "autoport", + TYPE_PROP, + 0, + "graphics"); + + if (STREQC(dev->dev.vnc.port, "-1")) { + dev->others = add_node_to_others(dev->others, + 0, + "autoport", + "yes", + TYPE_PROP, + 0, + "graphics"); + } else { + dev->others = add_node_to_others(dev->others, + 0, + "autoport", + "no", + TYPE_PROP, + 0, + "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, + 0, + "listen", + dev->dev.vnc.host, + TYPE_PROP, + 0, + "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, + 0, + "passwd", + dev->dev.vnc.passwd, + TYPE_PROP, + 0, + "graphics"); + } - if (dev->dev.vnc.keymap) - xmlNewProp(tmp, BAD_CAST "keymap", BAD_CAST dev->dev.vnc.keymap); + if (dev->dev.vnc.keymap) { + dev->others = add_node_to_others(dev->others, + 0, + "keymap", + dev->dev.vnc.keymap, + TYPE_PROP, + 0, + "graphics"); + } - return NULL; + dev->others = others_to_xml(root, dev->others, 0, "devices"); + + return check_others_active(dev->others); } static const char *graphics_xml(xmlNodePtr root, struct domain *dominfo) -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 38 +++++++++++++++++++++++++++++++++----- 1 files changed, 33 insertions(+), 5 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 5979e96..6c4b832 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1820,20 +1820,48 @@ 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, + 0, + "input", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "type", + dev->type, + TYPE_PROP, + 0, + "input"); + + dev->others = add_node_to_others(dev->others, + 0, + "bus", + dev->bus, + TYPE_PROP, + 0, + "input"); + + dev->others = others_to_xml(root, dev->others, 0, "devices"); + if (check_others_active(dev->others)) { + return "xml generation failed."; + } } return NULL; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 120 ++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 88 insertions(+), 32 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 6c4b832..91ac44a 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1869,56 +1869,112 @@ static const char *input_xml(xmlNodePtr root, struct domain *dominfo) static char *system_xml(xmlNodePtr root, struct domain *domain) { - xmlNodePtr tmp; - - tmp = xmlNewChild(root, NULL, BAD_CAST "name", BAD_CAST domain->name); - if (tmp == NULL) + CU_DEBUG("Enter system_xml()"); + + domain->others = add_node_to_others(domain->others, + 0, + "name", + domain->name, + TYPE_NODE, + 0, + "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, + 0, + "bootloader", + domain->bootloader, + TYPE_NODE, + 0, + "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, + 0, + "bootloader_args", + domain->bootloader_args, + TYPE_NODE, + 0, + "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, + 0, + "on_poweroff", + vssd_recovery_action_str(domain->on_poweroff), + TYPE_NODE, + 0, + "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, + 0, + "on_crash", + vssd_recovery_action_str(domain->on_crash), + TYPE_NODE, + 0, + "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, + 0, + "uuid", + domain->uuid, + TYPE_NODE, + 0, + "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, + 0, + "clock", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "offset", + domain->clock, + TYPE_PROP, + 0, + "clock"); } return NULL; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 57 ++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 47 insertions(+), 10 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 91ac44a..b09ee02 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -1980,10 +1980,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"); @@ -1991,21 +1992,57 @@ 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, + 0, + "type", + os->type, + TYPE_NODE, + 0, + 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, + 0, + "kernel", + os->kernel, + TYPE_NODE, + 0, + 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, + 0, + "initrd", + os->initrd, + TYPE_NODE, + 0, + 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, + 0, + "cmdline", + os->cmdline, + TYPE_NODE, + 0, + 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 | 27 ++++++++++++++++++++++----- 1 files changed, 22 insertions(+), 5 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index b09ee02..3c4fd30 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -2047,17 +2047,34 @@ 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, + 0, + "boot", + NULL, + TYPE_NODE, + 0, + 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, + 0, + "dev", + os->bootlist[i], + TYPE_PROP, + 0, + "boot"); } return 1; -- 1.7.1

Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/xmlgen.c | 37 ++++++++++++++++++++++++++++--------- 1 files changed, 28 insertions(+), 9 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 3c4fd30..4c5f731 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -2080,12 +2080,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"); @@ -2098,15 +2099,33 @@ 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, + 0, + "type", + os->type, + TYPE_NODE, + 0, + 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, + 0, + "loader", + os->loader, + TYPE_NODE, + 0, + 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 | 38 ++++++++++++++++++++++++++++++-------- 1 files changed, 30 insertions(+), 8 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 4c5f731..7678503 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -2132,12 +2132,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"); @@ -2147,17 +2148,38 @@ 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) - return XML_ERROR; + domain->others = add_node_to_others(domain->others, + 0, + "type", + os->type, + TYPE_NODE, + 0, + root); + + if (domain->others == NULL) { + CU_DEBUG("add node <type> failed."); + return XML_ERROR; + } if (os->arch) - xmlNewProp(tmp, BAD_CAST "arch", BAD_CAST os->arch); + domain->others = add_node_to_others(domain->others, + 0, + "arch", + os->arch, + TYPE_PROP, + 0, + "type"); if (os->machine) - xmlNewProp(tmp, BAD_CAST "machine", BAD_CAST os->machine); + domain->others = add_node_to_others(domain->others, + 0, + "machine", + os->machine, + TYPE_PROP, + 0, + "type"); - 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 | 31 +++++++++++++++++++++++++------ 1 files changed, 25 insertions(+), 6 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 7678503..046cb62 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -2186,21 +2186,40 @@ 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, + 0, + "init", + os->init, + TYPE_NODE, + 0, + 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, + 0, + "type", + os->type, + TYPE_NODE, + 0, + 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 | 18 ++++++++++++++---- 1 files changed, 14 insertions(+), 4 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 046cb62..4bce159 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -2226,11 +2226,21 @@ 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, + 0, + "os", + NULL, + TYPE_NODE, + 0, + "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 | 44 ++++++++++++++++++++++++++++++++++---------- 1 files changed, 34 insertions(+), 10 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index 4bce159..10a04a6 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -2256,20 +2256,44 @@ 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, + 0, + "features", + NULL, + TYPE_NODE, + 0, + "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, + 0, + "acpi", + NULL, + TYPE_NODE, + 0, + "features"); + + domain->others = add_node_to_others(domain->others, + 0, + "apic", + NULL, + TYPE_NODE, + 0, + "features"); - if (domain->pae) - xmlNewChild(features, NULL, BAD_CAST "pae", NULL); + domain->others = add_node_to_others(domain->others, + 0, + "pae", + NULL, + TYPE_NODE, + 0, + "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 10a04a6..c2ff98b 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -2338,6 +2338,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; + dev->others = others_to_xml(root, dev->others, 0, "devices"); + if (check_others_active(dev->others)) { + return "xml generation failed."; + } + } + + return NULL; +} + char *device_to_xml(struct virt_device *_dev) { char *xml = NULL; @@ -2402,6 +2420,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 | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c index c2ff98b..f8061b1 100644 --- a/libxkutil/xmlgen.c +++ b/libxkutil/xmlgen.c @@ -2463,9 +2463,12 @@ char *system_to_xml(struct domain *dominfo) &console_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) @@ -2493,6 +2496,9 @@ char *system_to_xml(struct domain *dominfo) if (xmlNewProp(root, BAD_CAST "type", BAD_CAST domtype) == NULL) goto out; + /* Parse all tags into others field of domain and generate xml in + * others_to_xml(). + */ msg = system_xml(root, dominfo); if (msg != NULL) goto out; @@ -2520,6 +2526,12 @@ char *system_to_xml(struct domain *dominfo) goto out; #endif + dominfo->others = others_to_xml(root, dominfo->others, 0, "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 70ca1b7..cff4a1d 100644 --- a/src/Virt_VirtualSystemManagementService.c +++ b/src/Virt_VirtualSystemManagementService.c @@ -587,6 +587,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; @@ -651,6 +652,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; @@ -1040,6 +1043,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; @@ -1161,6 +1167,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; } @@ -1185,6 +1194,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; } @@ -1772,6 +1784,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: @@ -1801,6 +1816,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 2b713de..e98ed39 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -2364,6 +2364,7 @@ static int _get_mem_device(const char *xml, struct virt_device **list) struct virt_device *mdev = NULL; int ret; bool mem_dump_core_set = false; + struct others *tmp = NULL; ret = parse_devices(xml, &mdevs, CIM_RES_TYPE_MEM); if (ret <= 0) @@ -2383,6 +2384,11 @@ 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); + /* libvirt dumpCore tag always belong to memory xml node, but * here we may have two mdev for memory node and currentMemory * node. So pick up one value. @@ -2402,6 +2408,7 @@ static int _get_mem_device(const char *xml, struct virt_device **list) 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->dev.mem.dumpCore = mdevs[0].dev.mem.dumpCore; } -- 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 e98ed39..94eb819 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -2438,6 +2438,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

Dear all, There are more and more bugs were reported as unsupported tags missing during resource update. And this issue is becoming more and more serious. My mission is solving this category bugs from designing by the end of this year. So could you help me review these patches and give me your suggestion? I hope I can get more feedback from community and solve it as soon as possible. If there is anything I can explain please reply me. Thank you very much. Sincerely yours, Xu Wang -------- 原始消息 -------- 主题: [PATCH V2 00/48] Solution to solve unsupported tag missing issue 日期: Mon, 28 Oct 2013 10:45:29 +0800 发件人: Xu Wang <cngesaint@gmail.com> 收件人: libvirt-cim@redhat.com 抄送: jferlan@redhat.com, mihajlov@linux.vnet.ibm.com, Xu Wang <gesaint@linux.vnet.ibm.com> What's new in V2: 1. Rebase commit to the current upstream. 2. Update console device support. 3. Add id and parent_id to handle there are more than two sub-node but with the same issue. 4. Add status (ACTIVE/INACTIVE) to identify if a node was fetched. 5. Adjust the original designing plan. Now after fetched a node from link list just change its status from ACTIVE to INACTIVE instead of delete it. Purpose of this update is to make link list keep the structure of xml and regenerate xml easily. 6. Necessary comments added. 7. Add function (compare_param_int/compare_param_str) to adjust the result of comparation (if any parameter is NULL/-1 the comparation result is TRUE instead of FALSE. 8. Bugs fixing. Such as attribute 'arch' under <type> of <os>, <dev> of <target> parsing, etc. -------------------------------------------------------------------------- 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 (48): 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_console_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 console_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 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 | 1959 ++++++++++++++++++++++----- libxkutil/device_parsing.h | 64 + libxkutil/xmlgen.c | 2103 +++++++++++++++++++++++------ src/Virt_VirtualSystemManagementService.c | 20 +- src/svpc_types.h | 1 + 5 files changed, 3445 insertions(+), 702 deletions(-)

On 11/11/2013 10:04 PM, Xu Wang wrote:
Dear all, There are more and more bugs were reported as unsupported tags missing during resource update. And this issue is becoming more and more serious. My mission is solving this category bugs from designing by the end of this year. So could you help me review these patches and give me your suggestion? I hope I can get more feedback from community and solve it as soon as possible. If there is anything I can explain please reply me. Thank you very much.
Sincerely yours, Xu Wang
I was reviewing this at the end of last month and was the last "good" run I got out of my cimtest before a 10/30/13 update to tog-pegasus seems to have removed the ability to use libvirt-cim as a provider. I have a feeling the issue has something to do with the PG_InterOp definitions, but I'm not quite sure as the wording on the OpenPegasus pages regarding this isn't clear to me. Unfortunately it seems the community has been reduced in scope to a very few and while libvirt continues to move forward libvirt-cim languishes behind. Lately finding time to review 50+ patches has been a challenge. In any case, while I haven't had the time to get into the details of the changes it seems the issue is that you have devised a way to ensure XML changes to libvirt aren't "lost" by libvirt-cim. I have to try and figure out another way to review/test the patches since my current means of my f19 laptop doesn't with tog-pegasus 2.12.1-8 no longer works. John
participants (3)
-
John Ferlan
-
Xu Wang
-
Xu Wang