[Libvirt-cim] [PATCH] (#2) Workaround to fix race condition around libvirt init

Eduardo Lima (Etrunko) eblima at linux.vnet.ibm.com
Wed Aug 31 13:41:56 UTC 2011


On 08/30/2011 02:14 PM, Sharad Mishra wrote:
> # HG changeset patch
> # User Sharad Mishra<snmishra at us.ibm.com>
> # Date 1314719316 25200
> # Node ID c54aafd0b2c6414f91b96bc30e2f148bb78d5c59
> # Parent  277b56b3863b5f81a3faa18aeb7b9951b963b489
> (#2) Workaround to fix race condition around libvirt init.
>
> This patch fixes the race condition caused when mutiple
> threads try to start VMs at the same time. This patch
> also fixes the issue of incorrect mem allocation for
> VSSD property - emulator.
>
> #2: included Edurdo's patch for make_space
>      took care of coding guidelines.
>
> Signed-off-by: Sharad Mishra<snmishra at us.ibm.com>
>
> diff --git a/libxkutil/misc_util.c b/libxkutil/misc_util.c
> --- a/libxkutil/misc_util.c
> +++ b/libxkutil/misc_util.c
> @@ -28,6 +28,7 @@
>   #include<stdbool.h>
>   #include<stdarg.h>
>   #include<unistd.h>
> +#include<pthread.h>
>   #include<libvirt/libvirt.h>
>   #include<libvirt/virterror.h>
>
> @@ -45,6 +46,9 @@
>   #include "misc_util.h"
>   #include "cs_util.h"
>
> +static pthread_mutex_t libvirt_mutex = PTHREAD_MUTEX_INITIALIZER;
> +/* libvirt library not initialized */
> +static int libvirt_initialized = 0;
>
>   #define URI_ENV "HYPURI"
>
> @@ -114,11 +118,15 @@
>
>           CU_DEBUG("Connecting to libvirt with uri `%s'", uri);
>
> +        pthread_mutex_lock(&libvirt_mutex);
> +
>           if (is_read_only())
>                   conn = virConnectOpenReadOnly(uri);
>           else
>                   conn = virConnectOpen(uri);
>
> +        pthread_mutex_unlock(&libvirt_mutex);
> +
>           if (!conn) {
>                   CU_DEBUG("Unable to connect to `%s'", uri);
>                   return NULL;
> @@ -530,7 +538,19 @@
>
>   bool libvirt_cim_init(void)
>   {
> -        return virInitialize() == 0;
> +        int ret = 0;
> +
> +        /* double-check lock pattern used for performance reasons */
> +        if (libvirt_initialized == 0) {
> +                pthread_mutex_lock(&libvirt_mutex);
> +                if (libvirt_initialized == 0) {
> +                        ret = virInitialize();
> +                        if (ret == 0)
> +                                libvirt_initialized = 1;
> +                }
> +                pthread_mutex_unlock(&libvirt_mutex);
> +        }
> +        return (ret == 0);
>   }
>
>   bool check_refs_pfx_match(const CMPIObjectPath *refa,
> diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c
> --- a/src/Virt_VirtualSystemManagementService.c
> +++ b/src/Virt_VirtualSystemManagementService.c
> @@ -188,6 +188,24 @@
>           return 1;
>   }
>
> +static bool make_space(struct virt_device **list, int cur, int new)
> +{
> +        struct virt_device *tmp;
> +
> +        tmp = calloc(cur + new, sizeof(*tmp));
> +        if (tmp == NULL)
> +                return false;
> +
> +        if (*list) {
> +                memcpy(tmp, *list, sizeof(*tmp) * cur);
> +                free(*list);
> +        }
> +
> +        *list = tmp;
> +
> +        return true;
> +}
> +
>   static bool fv_set_emulator(struct domain *domain,
>                               const char *emu)
>   {
> @@ -198,6 +216,11 @@
>           if (emu == NULL)
>                   return true;
>
> +        if (!make_space(&domain->dev_emu, 0, 1)) {
> +                CU_DEBUG("Failed to alloc disk list");
> +                return false;
> +        }
> +
>           cleanup_virt_device(domain->dev_emu);
>
>           domain->dev_emu->type = CIM_RES_TYPE_EMU;
> @@ -1369,24 +1392,6 @@
>           return msg;
>   }
>
> -static bool make_space(struct virt_device **list, int cur, int new)
> -{
> -        struct virt_device *tmp;
> -
> -        tmp = calloc(cur + new, sizeof(*tmp));
> -        if (tmp == NULL)
> -                return false;
> -
> -        if (*list) {
> -                memcpy(tmp, *list, sizeof(*tmp) * cur);
> -                free(*list);
> -        }
> -
> -        *list = tmp;
> -
> -        return true;
> -}
> -
>   static char *add_device_nodup(struct virt_device *dev,
>                                 struct virt_device *list,
>                                 int max,
>

+1. Tricky stuff. :)

-- 
Eduardo de Barros Lima
Software Engineer, Open Virtualization
Linux Technology Center - IBM/Brazil
eblima at br.ibm.com




More information about the Libvirt-cim mailing list