
From: Xu Wang <cngesaint@outlook.com> Under nested KVM environment libvirt-cim could recognize kvm support correctly now. Signed-off-by: Xu Wang <cngesaint@outlook.com> --- libxkutil/device_parsing.c | 27 ++++++++++++++++++++ libxkutil/device_parsing.h | 2 + src/Virt_VirtualSystemManagementService.c | 38 +++++++++++++++++++++++++---- 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 436415a..16195da 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -396,6 +396,33 @@ err: return 0; } +int parse_domain_type(xmlNodePtr node, char **value) +{ + xmlNodePtr child = NULL; + char *type = NULL; + + child = node->children; + while (child != NULL) { + if (XSTREQ(child->name, "domain")) { + type = get_attr_value(child, "type"); + if (type != NULL) { + *value = strdup(type); + goto out; + } + } + + if (parse_domain_type(child, value) == 1) { + goto out; + } + + child = child->next; + } + + return 0; +out: + return 1; +} + static int parse_net_device(xmlNode *inode, struct virt_device **vdevs) { struct virt_device *vdev = NULL; diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h index 6f6b0b4..733324f 100644 --- a/libxkutil/device_parsing.h +++ b/libxkutil/device_parsing.h @@ -221,6 +221,8 @@ 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); +int parse_domain_type(xmlNodePtr node, char **value); + #define XSTREQ(x, y) (STREQ((char *)x, y)) #define STRPROP(d, p, n) (d->p = get_node_content(n)) diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c index 7b7261a..8e1e6b1 100644 --- a/src/Virt_VirtualSystemManagementService.c +++ b/src/Virt_VirtualSystemManagementService.c @@ -393,25 +393,53 @@ static bool system_has_kvm(const char *pfx) CMPIStatus s; virConnectPtr conn; char *caps = NULL; - bool kvm = false; bool disable_kvm = get_disable_kvm(); + char *val = NULL; + xmlDocPtr doc = NULL; + xmlNodePtr node = NULL; + int len; + bool kvm = false; /* sometimes disable KVM to avoid problem in nested KVM */ if (disable_kvm) { CU_DEBUG("Enter disable kvm mode!"); - return false; + goto out; } conn = connect_by_classname(_BROKER, pfx, &s); if ((conn == NULL) || (s.rc != CMPI_RC_OK)) { - return false; + goto out; } caps = virConnectGetCapabilities(conn); - if (caps != NULL) - kvm = (strstr(caps, "kvm") != NULL); + if (caps != NULL) { + len = strlen(caps) + 1; + + doc = xmlParseMemory(caps, len); + if (doc == NULL) { + CU_DEBUG("xmlParseMemory() call failed!"); + goto out; + } + + node = xmlDocGetRootElement(doc); + if (node == NULL) { + CU_DEBUG("xmlDocGetRootElement() call failed!"); + goto out; + } + + if (parse_domain_type(node, &val) && + STREQC(val, "kvm")) { + CU_DEBUG("The system support kvm!"); + kvm = true; + } else { + CU_DEBUG("Domain type is %s.", val); + } + } +out: free(caps); + free(doc); + free(val); virConnectClose(conn); -- 1.7.1