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 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list