[libvirt] PATCH: 18/28: Thread safety for OpenVZ driver

Daniel P. Berrange berrange at redhat.com
Sun Nov 30 23:59:55 UTC 2008


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 :|




More information about the libvir-list mailing list