# HG changeset patch
# User Sharad Mishra <snmishra(a)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(a)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,