[Libvirt-cim] [PATCH] Improve support of nested KVM
John Ferlan
jferlan at redhat.com
Mon Jun 17 23:56:29 UTC 2013
On 05/24/2013 03:34 AM, cngesaint at outlook.com wrote:
> From: Xu Wang <cngesaint at outlook.com>
>
> Under nested KVM environment libvirt-cim could recognize kvm support
> correctly now.
>
> Signed-off-by: Xu Wang <cngesaint at outlook.com>
> ---
> libxkutil/device_parsing.c | 19 +++++++++++++++++++
> libxkutil/device_parsing.h | 2 ++
> src/Virt_VirtualSystemManagementService.c | 22 +++++++++++++++++++---
> 3 files changed, 40 insertions(+), 3 deletions(-)
>
> diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c
> index 436415a..58d9094 100644
> --- a/libxkutil/device_parsing.c
> +++ b/libxkutil/device_parsing.c
> @@ -396,6 +396,25 @@ err:
> return 0;
> }
>
> +int parse_domain_type(xmlNodePtr node, char **value)
> +{
> + xmlNodePtr child = NULL;
> +
> + child = node->children;
> + while (child != NULL) {
> + if (XSTREQ(child->name, "domain")) {
> + *value = get_attr_value(child, "type");
This returns either a NULL or strdup()'d value. It seems by the makeup
of this loop that we will continue down a "child" forward link list
potentially overwriting a previous value and leaking memory.
Is there something that should cause us to exit the loop?
> + }
> + if (parse_domain_type(child, value) != 1)
> + goto err;
So a child could have a child.
> + child = child->next;
> + }
> +
> + return 1;
We potentially could return a 1, but a NULL 'val' - is that expected.
> +err:
> + return 0;
This function does not return CMPI_RC_OK or whatever else so the caller
shouldn't be comparing against that...
> +}
> +
> 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..5210fdf 100644
> --- a/src/Virt_VirtualSystemManagementService.c
> +++ b/src/Virt_VirtualSystemManagementService.c
> @@ -393,8 +393,13 @@ 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;
> + int ret;
> + xmlDocPtr doc;
> + xmlNodePtr node;
I think both of these need to be initialized to NULL because of the
free() below.
> + int len;
> + bool kvm = false;
>
> /* sometimes disable KVM to avoid problem in nested KVM */
> if (disable_kvm) {
> @@ -408,10 +413,21 @@ static bool system_has_kvm(const char *pfx)
> }
>
> 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) {
/* Error message ? Do we care */
goto cleanup;
}
> + node = xmlDocGetRootElement(doc);
if (node == NULL) {
/* Error message ? Do we care */
goto cleanup;
}
> + ret = parse_domain_type(node, &val);
> + CU_DEBUG("domain type is %s.", val);
^^^^^
Move inside the if statement below, val could be NULL
> + if (ret == CMPI_RC_OK) {
== 1) {
> + if(STREQC(val, "kvm"))
^^
Add a space between "if" and "("
> + kvm = true;
> + }
> + }
} else {
/* Do we care what failure means here?? */
}
Alternatively,
if (parse_domain_type(node, &val) &&
STREQC(val, "kvm")) {
kvm = true;
} else {
if (val)
CU_DEBUG("domain type is %s.", val);
}
cleanup:
>
> free(caps);
> + free(doc);
> + free(val);
>
> virConnectClose(conn);
>
>
More information about the Libvirt-cim
mailing list