This patch fills in the previous stub methods for locking/unlocking
internal objects.
With the following methods return a locked object
virDomainFindByID
virDomainFindByName
virDomainFindByUUID
virDomainAssignDef
All the other methods accepting a virDomainObjPtr instance, require that
the object first be locked.
For virDomainDefPtr objects, if they are standalone, no locking is
required (hence why the Xen driver isn't touched in any of these patches).
If they are associated with a virDomainObjPtr though, this parent object
must be locked.
The same applies for virNetworkObjPtr, virStoragePoolObjPtr and the
virNodeDeviceObjPtr objects & their methods.
domain_conf.c | 40 ++++++++++++++++++++++++++++++++++++----
domain_conf.h | 2 ++
network_conf.c | 46 ++++++++++++++++++++++++++++++++++++++--------
network_conf.h | 2 ++
node_device_conf.c | 28 +++++++++++++++++++++++++++-
node_device_conf.h | 2 ++
storage_conf.c | 35 ++++++++++++++++++++++++++++++++---
storage_conf.h | 2 ++
8 files changed, 141 insertions(+), 16 deletions(-)
Daniel
diff --git a/src/domain_conf.c b/src/domain_conf.c
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -151,10 +151,13 @@ virDomainObjPtr virDomainFindByID(const
{
unsigned int i;
- for (i = 0 ; i < doms->count ; i++)
+ for (i = 0 ; i < doms->count ; i++) {
+ virDomainObjLock(doms->objs[i]);
if (virDomainIsActive(doms->objs[i]) &&
doms->objs[i]->def->id == id)
return doms->objs[i];
+ virDomainObjUnlock(doms->objs[i]);
+ }
return NULL;
}
@@ -165,9 +168,12 @@ virDomainObjPtr virDomainFindByUUID(cons
{
unsigned int i;
- for (i = 0 ; i < doms->count ; i++)
+ for (i = 0 ; i < doms->count ; i++) {
+ virDomainObjLock(doms->objs[i]);
if (!memcmp(doms->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN))
return doms->objs[i];
+ virDomainObjUnlock(doms->objs[i]);
+ }
return NULL;
}
@@ -177,9 +183,12 @@ virDomainObjPtr virDomainFindByName(cons
{
unsigned int i;
- for (i = 0 ; i < doms->count ; i++)
+ for (i = 0 ; i < doms->count ; i++) {
+ virDomainObjLock(doms->objs[i]);
if (STREQ(doms->objs[i]->def->name, name))
return doms->objs[i];
+ virDomainObjUnlock(doms->objs[i]);
+ }
return NULL;
}
@@ -455,6 +464,8 @@ virDomainObjPtr virDomainAssignDef(virCo
return NULL;
}
+ pthread_mutex_init(&domain->lock, NULL);
+ virDomainObjLock(domain);
domain->state = VIR_DOMAIN_SHUTOFF;
domain->def = def;
@@ -475,8 +486,12 @@ void virDomainRemoveInactive(virDomainOb
{
unsigned int i;
+ virDomainObjUnlock(dom);
+
for (i = 0 ; i < doms->count ; i++) {
+ virDomainObjLock(doms->objs[i]);
if (doms->objs[i] == dom) {
+ virDomainObjUnlock(doms->objs[i]);
virDomainObjFree(doms->objs[i]);
if (i < (doms->count - 1))
@@ -490,6 +505,7 @@ void virDomainRemoveInactive(virDomainOb
break;
}
+ virDomainObjUnlock(doms->objs[i]);
}
}
@@ -3337,8 +3353,10 @@ int virDomainLoadAllConfigs(virConnectPt
entry->d_name,
notify,
opaque);
- if (dom)
+ if (dom) {
+ virDomainObjUnlock(dom);
dom->persistent = 1;
+ }
}
closedir(dir);
@@ -3459,6 +3477,19 @@ const char *virDomainDefDefaultEmulator(
}
+#ifdef HAVE_PTHREAD_H
+
+void virDomainObjLock(virDomainObjPtr obj)
+{
+ pthread_mutex_lock(&obj->lock);
+}
+
+void virDomainObjUnlock(virDomainObjPtr obj)
+{
+ pthread_mutex_unlock(&obj->lock);
+}
+
+#else
void virDomainObjLock(virDomainObjPtr obj ATTRIBUTE_UNUSED)
{
}
@@ -3466,5 +3497,6 @@ void virDomainObjUnlock(virDomainObjPtr
void virDomainObjUnlock(virDomainObjPtr obj ATTRIBUTE_UNUSED)
{
}
+#endif
#endif /* ! PROXY */
diff --git a/src/domain_conf.h b/src/domain_conf.h
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -454,6 +454,8 @@ typedef struct _virDomainObj virDomainOb
typedef struct _virDomainObj virDomainObj;
typedef virDomainObj *virDomainObjPtr;
struct _virDomainObj {
+ PTHREAD_MUTEX_T(lock);
+
int stdin_fd;
int stdout_fd;
int stdout_watch;
diff --git a/src/network_conf.c b/src/network_conf.c
--- a/src/network_conf.c
+++ b/src/network_conf.c
@@ -58,9 +58,12 @@ virNetworkObjPtr virNetworkFindByUUID(co
{
unsigned int i;
- for (i = 0 ; i < nets->count ; i++)
+ for (i = 0 ; i < nets->count ; i++) {
+ virNetworkObjLock(nets->objs[i]);
if (!memcmp(nets->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN))
return nets->objs[i];
+ virNetworkObjUnlock(nets->objs[i]);
+ }
return NULL;
}
@@ -70,9 +73,12 @@ virNetworkObjPtr virNetworkFindByName(co
{
unsigned int i;
- for (i = 0 ; i < nets->count ; i++)
+ for (i = 0 ; i < nets->count ; i++) {
+ virNetworkObjLock(nets->objs[i]);
if (STREQ(nets->objs[i]->def->name, name))
return nets->objs[i];
+ virNetworkObjUnlock(nets->objs[i]);
+ }
return NULL;
}
@@ -157,7 +163,8 @@ virNetworkObjPtr virNetworkAssignDef(vir
virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
return NULL;
}
-
+ pthread_mutex_init(&network->lock, NULL);
+ virNetworkObjLock(network);
network->def = def;
if (VIR_REALLOC_N(nets->objs, nets->count + 1) < 0) {
@@ -178,8 +185,11 @@ void virNetworkRemoveInactive(virNetwork
{
unsigned int i;
+ virNetworkObjUnlock(net);
for (i = 0 ; i < nets->count ; i++) {
+ virNetworkObjLock(nets->objs[i]);
if (nets->objs[i] == net) {
+ virNetworkObjUnlock(nets->objs[i]);
virNetworkObjFree(nets->objs[i]);
if (i < (nets->count - 1))
@@ -193,6 +203,7 @@ void virNetworkRemoveInactive(virNetwork
break;
}
+ virNetworkObjUnlock(nets->objs[i]);
}
}
@@ -770,6 +781,8 @@ int virNetworkLoadAllConfigs(virConnectP
}
while ((entry = readdir(dir))) {
+ virNetworkObjPtr net;
+
if (entry->d_name[0] == '.')
continue;
@@ -778,11 +791,13 @@ int virNetworkLoadAllConfigs(virConnectP
/* NB: ignoring errors, so one malformed config doesn't
kill the whole process */
- virNetworkLoadConfig(conn,
- nets,
- configDir,
- autostartDir,
- entry->d_name);
+ net = virNetworkLoadConfig(conn,
+ nets,
+ configDir,
+ autostartDir,
+ entry->d_name);
+ if (net)
+ virNetworkObjUnlock(net);
}
closedir(dir);
@@ -812,6 +827,19 @@ int virNetworkDeleteConfig(virConnectPtr
return 0;
}
+#ifdef HAVE_PTHREAD_H
+
+void virNetworkObjLock(virNetworkObjPtr obj)
+{
+ pthread_mutex_lock(&obj->lock);
+}
+
+void virNetworkObjUnlock(virNetworkObjPtr obj)
+{
+ pthread_mutex_unlock(&obj->lock);
+}
+
+#else
void virNetworkObjLock(virNetworkObjPtr obj ATTRIBUTE_UNUSED)
{
}
@@ -819,3 +847,5 @@ void virNetworkObjUnlock(virNetworkObjPt
void virNetworkObjUnlock(virNetworkObjPtr obj ATTRIBUTE_UNUSED)
{
}
+
+#endif
diff --git a/src/network_conf.h b/src/network_conf.h
--- a/src/network_conf.h
+++ b/src/network_conf.h
@@ -82,6 +82,8 @@ typedef struct _virNetworkObj virNetwork
typedef struct _virNetworkObj virNetworkObj;
typedef virNetworkObj *virNetworkObjPtr;
struct _virNetworkObj {
+ PTHREAD_MUTEX_T(lock);
+
pid_t dnsmasqPid;
unsigned int active : 1;
unsigned int autostart : 1;
diff --git a/src/node_device_conf.c b/src/node_device_conf.c
--- a/src/node_device_conf.c
+++ b/src/node_device_conf.c
@@ -59,9 +59,12 @@ virNodeDeviceObjPtr virNodeDeviceFindByN
{
unsigned int i;
- for (i = 0; i < devs->count; i++)
+ for (i = 0; i < devs->count; i++) {
+ virNodeDeviceObjLock(devs->objs[i]);
if (STREQ(devs->objs[i]->def->name, name))
return devs->objs[i];
+ virNodeDeviceObjUnlock(devs->objs[i]);
+ }
return NULL;
}
@@ -125,6 +128,8 @@ virNodeDeviceObjPtr virNodeDeviceAssignD
return NULL;
}
+ pthread_mutex_init(&device->lock, NULL);
+ virNodeDeviceObjLock(device);
device->def = def;
if (VIR_REALLOC_N(devs->objs, devs->count+1) < 0) {
@@ -144,8 +149,12 @@ void virNodeDeviceObjRemove(virNodeDevic
{
unsigned int i;
+ virNodeDeviceObjUnlock(dev);
+
for (i = 0; i < devs->count; i++) {
+ virNodeDeviceObjLock(dev);
if (devs->objs[i] == dev) {
+ virNodeDeviceObjUnlock(dev);
virNodeDeviceObjFree(devs->objs[i]);
if (i < (devs->count - 1))
@@ -159,6 +168,7 @@ void virNodeDeviceObjRemove(virNodeDevic
break;
}
+ virNodeDeviceObjUnlock(dev);
}
}
@@ -398,6 +408,20 @@ void virNodeDevCapsDefFree(virNodeDevCap
}
+#ifdef HAVE_PTHREAD_H
+
+void virNodeDeviceObjLock(virNodeDeviceObjPtr obj)
+{
+ pthread_mutex_lock(&obj->lock);
+}
+
+void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj)
+{
+ pthread_mutex_unlock(&obj->lock);
+}
+
+#else
+
void virNodeDeviceObjLock(virNodeDeviceObjPtr obj ATTRIBUTE_UNUSED)
{
}
@@ -405,3 +429,5 @@ void virNodeDeviceObjUnlock(virNodeDevic
void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj ATTRIBUTE_UNUSED)
{
}
+
+#endif
diff --git a/src/node_device_conf.h b/src/node_device_conf.h
--- a/src/node_device_conf.h
+++ b/src/node_device_conf.h
@@ -142,6 +142,8 @@ typedef struct _virNodeDeviceObj virNode
typedef struct _virNodeDeviceObj virNodeDeviceObj;
typedef virNodeDeviceObj *virNodeDeviceObjPtr;
struct _virNodeDeviceObj {
+ PTHREAD_MUTEX_T(lock);
+
virNodeDeviceDefPtr def; /* device definition */
void *privateData; /* driver-specific private data */
void (*privateFree)(void *data); /* destructor for private data */
diff --git a/src/storage_conf.c b/src/storage_conf.c
--- a/src/storage_conf.c
+++ b/src/storage_conf.c
@@ -305,8 +305,12 @@ virStoragePoolObjRemove(virStoragePoolOb
{
unsigned int i;
+ virStoragePoolObjUnlock(pool);
+
for (i = 0 ; i < pools->count ; i++) {
+ virStoragePoolObjLock(pools->objs[i]);
if (pools->objs[i] == pool) {
+ virStoragePoolObjUnlock(pools->objs[i]);
virStoragePoolObjFree(pools->objs[i]);
if (i < (pools->count - 1))
@@ -320,6 +324,7 @@ virStoragePoolObjRemove(virStoragePoolOb
break;
}
+ virStoragePoolObjUnlock(pools->objs[i]);
}
}
@@ -1143,9 +1148,12 @@ virStoragePoolObjFindByUUID(virStoragePo
const unsigned char *uuid) {
unsigned int i;
- for (i = 0 ; i < pools->count ; i++)
+ for (i = 0 ; i < pools->count ; i++) {
+ virStoragePoolObjLock(pools->objs[i]);
if (!memcmp(pools->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN))
return pools->objs[i];
+ virStoragePoolObjUnlock(pools->objs[i]);
+ }
return NULL;
}
@@ -1155,9 +1163,12 @@ virStoragePoolObjFindByName(virStoragePo
const char *name) {
unsigned int i;
- for (i = 0 ; i < pools->count ; i++)
+ for (i = 0 ; i < pools->count ; i++) {
+ virStoragePoolObjLock(pools->objs[i]);
if (STREQ(pools->objs[i]->def->name, name))
return pools->objs[i];
+ virStoragePoolObjUnlock(pools->objs[i]);
+ }
return NULL;
}
@@ -1233,6 +1244,8 @@ virStoragePoolObjAssignDef(virConnectPtr
return NULL;
}
+ pthread_mutex_init(&pool->lock, NULL);
+ virStoragePoolObjLock(pool);
pool->active = 0;
pool->def = def;
@@ -1317,6 +1330,7 @@ virStoragePoolLoadAllConfigs(virConnectP
char *xml = NULL;
char path[PATH_MAX];
char autostartLink[PATH_MAX];
+ virStoragePoolObjPtr pool;
if (entry->d_name[0] == '.')
continue;
@@ -1341,7 +1355,9 @@ virStoragePoolLoadAllConfigs(virConnectP
if (virFileReadAll(path, 8192, &xml) < 0)
continue;
- virStoragePoolObjLoad(conn, pools, entry->d_name, path, xml, autostartLink);
+ pool = virStoragePoolObjLoad(conn, pools, entry->d_name, path, xml,
autostartLink);
+ if (pool)
+ virStoragePoolObjUnlock(pool);
VIR_FREE(xml);
}
@@ -1499,6 +1515,18 @@ char *virStoragePoolSourceListFormat(vir
}
+#ifdef HAVE_PTHREAD_H
+
+void virStoragePoolObjLock(virStoragePoolObjPtr obj)
+{
+ pthread_mutex_lock(&obj->lock);
+}
+
+void virStoragePoolObjUnlock(virStoragePoolObjPtr obj)
+{
+ pthread_mutex_unlock(&obj->lock);
+}
+#else
void virStoragePoolObjLock(virStoragePoolObjPtr obj ATTRIBUTE_UNUSED)
{
}
@@ -1506,3 +1534,4 @@ void virStoragePoolObjUnlock(virStorageP
void virStoragePoolObjUnlock(virStoragePoolObjPtr obj ATTRIBUTE_UNUSED)
{
}
+#endif
diff --git a/src/storage_conf.h b/src/storage_conf.h
--- a/src/storage_conf.h
+++ b/src/storage_conf.h
@@ -223,6 +223,8 @@ typedef virStoragePoolObj *virStoragePoo
typedef virStoragePoolObj *virStoragePoolObjPtr;
struct _virStoragePoolObj {
+ PTHREAD_MUTEX_T(lock);
+
char *configFile;
char *autostartLink;
int active;
--
|: 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 :|