[Libvirt-cim] [PATCH] Workaround to fix race condition around libvirt init

Sharad Mishra snmishra at us.ibm.com
Fri Aug 26 17:32:18 UTC 2011


# HG changeset patch
# User Sharad Mishra <snmishra at us.ibm.com>
# Date 1314379933 25200
# Node ID a42b68361ed9cb4f7d6f15de5b58ccc68e88ef38
# Parent  a346baf140d64177a9dc1066677c307ee6518236
Workaround to fix race condition around libvirt init.

This patch fixes the race condition caused when mutiple
threads try to start a VM. This patch also fixes the issue
of incorrect mem allocation for VSSD property - emulator.

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 (0 == libvirt_initialized) {
+                pthread_mutex_lock(&libvirt_mutex);
+                if (0 == libvirt_initialized) {
+                        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,20 @@
         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;
+
+        memcpy(tmp, *list, sizeof(*tmp) * cur);
+        *list = tmp;
+
+        return true;
+}
+
 static bool fv_set_emulator(struct domain *domain,
                             const char *emu)
 {
@@ -198,6 +212,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,20 +1388,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;
-
-        memcpy(tmp, *list, sizeof(*tmp) * cur);
-        *list = tmp;
-
-        return true;
-}
-
 static char *add_device_nodup(struct virt_device *dev,
                               struct virt_device *list,
                               int max,




More information about the Libvirt-cim mailing list