This patch makes the OpenVZ driver thread safe
openvz_conf.h | 2 +
openvz_driver.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 102 insertions(+), 3 deletions(-)
Daniel
diff --git a/src/openvz_conf.h b/src/openvz_conf.h
--- a/src/openvz_conf.h
+++ b/src/openvz_conf.h
@@ -53,6 +53,8 @@ enum { OPENVZ_WARN, OPENVZ_ERR };
#define VZCTL_BRIDGE_MIN_VERSION ((3 * 1000 * 1000) + (0 * 1000) + 22 + 1)
struct openvz_driver {
+ PTHREAD_MUTEX_T(lock);
+
virCapsPtr caps;
virDomainObjList domains;
int version;
diff --git a/src/openvz_driver.c b/src/openvz_driver.c
--- a/src/openvz_driver.c
+++ b/src/openvz_driver.c
@@ -66,6 +66,16 @@ static int openvzGetMaxVCPUs(virConnectP
static int openvzGetMaxVCPUs(virConnectPtr conn, const char *type);
static int openvzDomainGetMaxVcpus(virDomainPtr dom);
static int openvzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus);
+
+static void openvzDriverLock(struct openvz_driver *driver)
+{
+ pthread_mutex_lock(&driver->lock);
+}
+
+static void openvzDriverUnlock(struct openvz_driver *driver)
+{
+ pthread_mutex_unlock(&driver->lock);
+}
struct openvz_driver ovz_driver;
@@ -159,7 +169,10 @@ static virDomainPtr openvzDomainLookupBy
virDomainObjPtr vm;
virDomainPtr dom = NULL;
+ openvzDriverLock(driver);
vm = virDomainFindByID(&driver->domains, id);
+ openvzDriverUnlock(driver);
+
if (!vm) {
openvzError(conn, VIR_ERR_NO_DOMAIN, NULL);
goto cleanup;
@@ -170,12 +183,16 @@ static virDomainPtr openvzDomainLookupBy
dom->id = vm->def->id;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return dom;
}
static int openvzGetVersion(virConnectPtr conn, unsigned long *version) {
struct openvz_driver *driver = conn->privateData;
+ openvzDriverLock(driver);
*version = driver->version;
+ openvzDriverUnlock(driver);
return 0;
}
@@ -185,7 +202,10 @@ static char *openvzGetOSType(virDomainPt
virDomainObjPtr vm;
char *ret = NULL;
+ openvzDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ openvzDriverUnlock(driver);
+
if (!vm) {
openvzError(dom->conn, VIR_ERR_NO_DOMAIN, NULL);
goto cleanup;
@@ -195,6 +215,8 @@ static char *openvzGetOSType(virDomainPt
openvzError(dom->conn, VIR_ERR_NO_MEMORY, NULL);
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -205,7 +227,10 @@ static virDomainPtr openvzDomainLookupBy
virDomainObjPtr vm;
virDomainPtr dom = NULL;
+ openvzDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, uuid);
+ openvzDriverUnlock(driver);
+
if (!vm) {
openvzError(conn, VIR_ERR_NO_DOMAIN, NULL);
goto cleanup;
@@ -216,6 +241,8 @@ static virDomainPtr openvzDomainLookupBy
dom->id = vm->def->id;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return dom;
}
@@ -225,7 +252,10 @@ static virDomainPtr openvzDomainLookupBy
virDomainObjPtr vm;
virDomainPtr dom = NULL;
+ openvzDriverLock(driver);
vm = virDomainFindByName(&driver->domains, name);
+ openvzDriverUnlock(driver);
+
if (!vm) {
openvzError(conn, VIR_ERR_NO_DOMAIN, NULL);
goto cleanup;
@@ -236,6 +266,8 @@ static virDomainPtr openvzDomainLookupBy
dom->id = vm->def->id;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return dom;
}
@@ -245,7 +277,10 @@ static int openvzDomainGetInfo(virDomain
virDomainObjPtr vm;
int ret = -1;
+ openvzDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ openvzDriverUnlock(driver);
+
if (!vm) {
openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
@@ -270,6 +305,8 @@ static int openvzDomainGetInfo(virDomain
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -279,7 +316,10 @@ static char *openvzDomainDumpXML(virDoma
virDomainObjPtr vm;
char *ret = NULL;
+ openvzDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ openvzDriverUnlock(driver);
+
if (!vm) {
openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
@@ -289,6 +329,8 @@ static char *openvzDomainDumpXML(virDoma
ret = virDomainDefFormat(dom->conn, vm->def, flags);
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -312,7 +354,10 @@ static int openvzDomainShutdown(virDomai
const char *prog[] = {VZCTL, "--quiet", "stop", PROGRAM_SENTINAL,
NULL};
int ret = -1;
+ openvzDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ openvzDriverUnlock(driver);
+
if (!vm) {
openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
@@ -334,6 +379,8 @@ static int openvzDomainShutdown(virDomai
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -344,7 +391,10 @@ static int openvzDomainReboot(virDomainP
const char *prog[] = {VZCTL, "--quiet", "restart",
PROGRAM_SENTINAL, NULL};
int ret = -1;
+ openvzDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ openvzDriverUnlock(driver);
+
if (!vm) {
openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
@@ -363,6 +413,8 @@ static int openvzDomainReboot(virDomainP
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -593,6 +645,7 @@ openvzDomainDefineXML(virConnectPtr conn
const char *prog[OPENVZ_MAX_ARG];
prog[0] = NULL;
+ openvzDriverLock(driver);
if ((vmdef = virDomainDefParseString(conn, driver->caps, xml)) == NULL)
goto cleanup;
@@ -650,12 +703,15 @@ cleanup:
cleanup:
virDomainDefFree(vmdef);
cmdExecFree(prog);
+ if (vm)
+ virDomainObjUnlock(vm);
+ openvzDriverUnlock(driver);
return dom;
}
static virDomainPtr
openvzDomainCreateXML(virConnectPtr conn, const char *xml,
- unsigned int flags ATTRIBUTE_UNUSED)
+ unsigned int flags ATTRIBUTE_UNUSED)
{
struct openvz_driver *driver = conn->privateData;
virDomainDefPtr vmdef = NULL;
@@ -665,6 +721,7 @@ openvzDomainCreateXML(virConnectPtr conn
const char *progcreate[OPENVZ_MAX_ARG];
progcreate[0] = NULL;
+ openvzDriverLock(driver);
if ((vmdef = virDomainDefParseString(conn, driver->caps, xml)) == NULL)
goto cleanup;
@@ -731,6 +788,9 @@ cleanup:
cleanup:
virDomainDefFree(vmdef);
cmdExecFree(progcreate);
+ if (vm)
+ virDomainObjUnlock(vm);
+ openvzDriverUnlock(driver);
return dom;
}
@@ -742,7 +802,10 @@ openvzDomainCreate(virDomainPtr dom)
const char *prog[] = {VZCTL, "--quiet", "start",
PROGRAM_SENTINAL, NULL };
int ret = -1;
+ openvzDriverLock(driver);
vm = virDomainFindByName(&driver->domains, dom->name);
+ openvzDriverUnlock(driver);
+
if (!vm) {
openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching id"));
@@ -768,6 +831,8 @@ openvzDomainCreate(virDomainPtr dom)
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -779,6 +844,7 @@ openvzDomainUndefine(virDomainPtr dom)
const char *prog[] = { VZCTL, "--quiet", "destroy",
PROGRAM_SENTINAL, NULL };
int ret = -1;
+ openvzDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN, "%s", _("no
domain with matching uuid"));
@@ -798,9 +864,13 @@ openvzDomainUndefine(virDomainPtr dom)
}
virDomainRemoveInactive(&driver->domains, vm);
+ vm = NULL;
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ openvzDriverUnlock(driver);
return ret;
}
@@ -814,7 +884,10 @@ openvzDomainSetAutostart(virDomainPtr do
"--save", NULL };
int ret = -1;
+ openvzDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ openvzDriverUnlock(driver);
+
if (!vm) {
openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN, "%s", _("no
domain with matching uuid"));
goto cleanup;
@@ -828,6 +901,8 @@ openvzDomainSetAutostart(virDomainPtr do
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -839,7 +914,10 @@ openvzDomainGetAutostart(virDomainPtr do
char value[1024];
int ret = -1;
+ openvzDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ openvzDriverUnlock(driver);
+
if (!vm) {
openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
@@ -858,6 +936,8 @@ openvzDomainGetAutostart(virDomainPtr do
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -884,7 +964,10 @@ static int openvzDomainSetVcpus(virDomai
unsigned int pcpus;
int ret = -1;
+ openvzDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ openvzDriverUnlock(driver);
+
if (!vm) {
openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
@@ -915,6 +998,8 @@ static int openvzDomainSetVcpus(virDomai
ret = 0;
cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
return ret;
}
@@ -993,7 +1078,9 @@ static char *openvzGetCapabilities(virCo
struct openvz_driver *driver = conn->privateData;
char *ret;
+ openvzDriverLock(driver);
ret = virCapabilitiesFormatXML(driver->caps);
+ openvzDriverUnlock(driver);
return ret;
}
@@ -1036,9 +1123,14 @@ static int openvzNumDomains(virConnectPt
struct openvz_driver *driver = conn->privateData;
int nactive = 0, i;
- for (i = 0 ; i < driver->domains.count ; i++)
+ openvzDriverLock(driver);
+ for (i = 0 ; i < driver->domains.count ; i++) {
+ virDomainObjLock(driver->domains.objs[i]);
if (virDomainIsActive(driver->domains.objs[i]))
nactive++;
+ virDomainObjUnlock(driver->domains.objs[i]);
+ }
+ openvzDriverUnlock(driver);
return nactive;
}
@@ -1133,9 +1225,14 @@ static int openvzNumDefinedDomains(virCo
struct openvz_driver *driver = conn->privateData;
int ninactive = 0, i;
- for (i = 0 ; i < driver->domains.count ; i++)
+ openvzDriverLock(driver);
+ for (i = 0 ; i < driver->domains.count ; i++) {
+ virDomainObjLock(driver->domains.objs[i]);
if (!virDomainIsActive(driver->domains.objs[i]))
ninactive++;
+ virDomainObjUnlock(driver->domains.objs[i]);
+ }
+ openvzDriverUnlock(driver);
return ninactive;
}
--
|: Red Hat, Engineering, London -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://ovirt.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|