Make virDomainObjList self-locking via virObjectLockable

Switch virDomainObjList to inherit from virObjectLockable and
make all the APIs acquire/release the mutex when running. This
makes virDomainObjList completely self-locking and no longer
reliant on the hypervisor driver locks
This commit is contained in:
Daniel P. Berrange 2013-01-14 15:54:47 +00:00
parent eea87129f1
commit 582c445a96

View File

@ -840,9 +840,11 @@ virDomainObjPtr virDomainObjListFindByID(const virDomainObjListPtr doms,
int id) int id)
{ {
virDomainObjPtr obj; virDomainObjPtr obj;
virObjectLock(doms);
obj = virHashSearch(doms->objs, virDomainObjListSearchID, &id); obj = virHashSearch(doms->objs, virDomainObjListSearchID, &id);
if (obj) if (obj)
virObjectLock(obj); virObjectLock(obj);
virObjectUnlock(doms);
return obj; return obj;
} }
@ -853,11 +855,13 @@ virDomainObjPtr virDomainObjListFindByUUID(const virDomainObjListPtr doms,
char uuidstr[VIR_UUID_STRING_BUFLEN]; char uuidstr[VIR_UUID_STRING_BUFLEN];
virDomainObjPtr obj; virDomainObjPtr obj;
virObjectLock(doms);
virUUIDFormat(uuid, uuidstr); virUUIDFormat(uuid, uuidstr);
obj = virHashLookup(doms->objs, uuidstr); obj = virHashLookup(doms->objs, uuidstr);
if (obj) if (obj)
virObjectLock(obj); virObjectLock(obj);
virObjectUnlock(doms);
return obj; return obj;
} }
@ -879,9 +883,11 @@ virDomainObjPtr virDomainObjListFindByName(const virDomainObjListPtr doms,
const char *name) const char *name)
{ {
virDomainObjPtr obj; virDomainObjPtr obj;
virObjectLock(doms);
obj = virHashSearch(doms->objs, virDomainObjListSearchName, name); obj = virHashSearch(doms->objs, virDomainObjListSearchName, name);
if (obj) if (obj)
virObjectLock(obj); virObjectLock(obj);
virObjectUnlock(doms);
return obj; return obj;
} }
@ -1904,19 +1910,24 @@ void virDomainObjAssignDef(virDomainObjPtr domain,
* live config, not a future inactive config * live config, not a future inactive config
* *
*/ */
virDomainObjPtr virDomainObjListAdd(virDomainObjListPtr doms, static virDomainObjPtr
virCapsPtr caps, virDomainObjListAddLocked(virDomainObjListPtr doms,
const virDomainDefPtr def, virCapsPtr caps,
unsigned int flags, const virDomainDefPtr def,
virDomainDefPtr *oldDef) unsigned int flags,
virDomainDefPtr *oldDef)
{ {
virDomainObjPtr vm; virDomainObjPtr vm;
char uuidstr[VIR_UUID_STRING_BUFLEN]; char uuidstr[VIR_UUID_STRING_BUFLEN];
if (oldDef) if (oldDef)
*oldDef = false; *oldDef = false;
virUUIDFormat(def->uuid, uuidstr);
/* See if a VM with matching UUID already exists */ /* See if a VM with matching UUID already exists */
if ((vm = virDomainObjListFindByUUID(doms, def->uuid))) { if ((vm = virHashLookup(doms->objs, uuidstr))) {
virObjectLock(vm);
/* UUID matches, but if names don't match, refuse it */ /* UUID matches, but if names don't match, refuse it */
if (STRNEQ(vm->def->name, def->name)) { if (STRNEQ(vm->def->name, def->name)) {
virUUIDFormat(vm->def->uuid, uuidstr); virUUIDFormat(vm->def->uuid, uuidstr);
@ -1942,7 +1953,8 @@ virDomainObjPtr virDomainObjListAdd(virDomainObjListPtr doms,
oldDef); oldDef);
} else { } else {
/* UUID does not match, but if a name matches, refuse it */ /* UUID does not match, but if a name matches, refuse it */
if ((vm = virDomainObjListFindByName(doms, def->name))) { if ((vm = virHashSearch(doms->objs, virDomainObjListSearchName, def->name))) {
virObjectLock(vm);
virUUIDFormat(vm->def->uuid, uuidstr); virUUIDFormat(vm->def->uuid, uuidstr);
virReportError(VIR_ERR_OPERATION_FAILED, virReportError(VIR_ERR_OPERATION_FAILED,
_("domain '%s' already exists with uuid %s"), _("domain '%s' already exists with uuid %s"),
@ -1969,6 +1981,21 @@ error:
goto cleanup; goto cleanup;
} }
virDomainObjPtr virDomainObjListAdd(virDomainObjListPtr doms,
virCapsPtr caps,
const virDomainDefPtr def,
unsigned int flags,
virDomainDefPtr *oldDef)
{
virDomainObjPtr ret;
virObjectLock(doms);
ret = virDomainObjListAddLocked(doms, caps, def, flags, oldDef);
virObjectUnlock(doms);
return ret;
}
/* /*
* Mark the running VM config as transient. Ensures transient hotplug * Mark the running VM config as transient. Ensures transient hotplug
* operations do not persist past shutdown. * operations do not persist past shutdown.
@ -2087,11 +2114,14 @@ void virDomainObjListRemove(virDomainObjListPtr doms,
virDomainObjPtr dom) virDomainObjPtr dom)
{ {
char uuidstr[VIR_UUID_STRING_BUFLEN]; char uuidstr[VIR_UUID_STRING_BUFLEN];
virObjectLock(doms);
virUUIDFormat(dom->def->uuid, uuidstr); virUUIDFormat(dom->def->uuid, uuidstr);
virObjectUnlock(dom); virObjectUnlock(dom);
virHashRemoveEntry(doms->objs, uuidstr); virHashRemoveEntry(doms->objs, uuidstr);
virObjectUnlock(doms);
} }
@ -14904,7 +14934,7 @@ virDomainObjListLoadConfig(virDomainObjListPtr doms,
if ((autostart = virFileLinkPointsTo(autostartLink, configFile)) < 0) if ((autostart = virFileLinkPointsTo(autostartLink, configFile)) < 0)
goto error; goto error;
if (!(dom = virDomainObjListAdd(doms, caps, def, 0, &oldDef))) if (!(dom = virDomainObjListAddLocked(doms, caps, def, 0, &oldDef)))
goto error; goto error;
dom->autostart = autostart; dom->autostart = autostart;
@ -14993,6 +15023,8 @@ int virDomainObjListLoadAllConfigs(virDomainObjListPtr doms,
return -1; return -1;
} }
virObjectLock(doms);
while ((entry = readdir(dir))) { while ((entry = readdir(dir))) {
virDomainObjPtr dom; virDomainObjPtr dom;
@ -15030,7 +15062,7 @@ int virDomainObjListLoadAllConfigs(virDomainObjListPtr doms,
} }
closedir(dir); closedir(dir);
virObjectUnlock(doms);
return 0; return 0;
} }
@ -15155,10 +15187,12 @@ static void virDomainObjListCountInactive(void *payload, const void *name ATTRIB
int virDomainObjListNumOfDomains(virDomainObjListPtr doms, int active) int virDomainObjListNumOfDomains(virDomainObjListPtr doms, int active)
{ {
int count = 0; int count = 0;
virObjectLock(doms);
if (active) if (active)
virHashForEach(doms->objs, virDomainObjListCountActive, &count); virHashForEach(doms->objs, virDomainObjListCountActive, &count);
else else
virHashForEach(doms->objs, virDomainObjListCountInactive, &count); virHashForEach(doms->objs, virDomainObjListCountInactive, &count);
virObjectUnlock(doms);
return count; return count;
} }
@ -15183,7 +15217,9 @@ int virDomainObjListGetActiveIDs(virDomainObjListPtr doms,
int maxids) int maxids)
{ {
struct virDomainIDData data = { 0, maxids, ids }; struct virDomainIDData data = { 0, maxids, ids };
virObjectLock(doms);
virHashForEach(doms->objs, virDomainObjListCopyActiveIDs, &data); virHashForEach(doms->objs, virDomainObjListCopyActiveIDs, &data);
virObjectUnlock(doms);
return data.numids; return data.numids;
} }
@ -15219,7 +15255,9 @@ int virDomainObjListGetInactiveNames(virDomainObjListPtr doms,
{ {
struct virDomainNameData data = { 0, 0, maxnames, names }; struct virDomainNameData data = { 0, 0, maxnames, names };
int i; int i;
virObjectLock(doms);
virHashForEach(doms->objs, virDomainObjListCopyInactiveNames, &data); virHashForEach(doms->objs, virDomainObjListCopyInactiveNames, &data);
virObjectUnlock(doms);
if (data.oom) { if (data.oom) {
virReportOOMError(); virReportOOMError();
goto cleanup; goto cleanup;
@ -15258,8 +15296,9 @@ int virDomainObjListForEach(virDomainObjListPtr doms,
struct virDomainListIterData data = { struct virDomainListIterData data = {
callback, opaque, 0, callback, opaque, 0,
}; };
virObjectLock(doms);
virHashForEach(doms->objs, virDomainObjListHelper, &data); virHashForEach(doms->objs, virDomainObjListHelper, &data);
virObjectUnlock(doms);
return data.ret; return data.ret;
} }
@ -16030,6 +16069,7 @@ virDomainObjListExport(virDomainObjListPtr doms,
struct virDomainListData data = { conn, NULL, flags, 0, false }; struct virDomainListData data = { conn, NULL, flags, 0, false };
virObjectLock(doms);
if (domains) { if (domains) {
if (VIR_ALLOC_N(data.domains, virHashSize(doms->objs) + 1) < 0) { if (VIR_ALLOC_N(data.domains, virHashSize(doms->objs) + 1) < 0) {
virReportOOMError(); virReportOOMError();
@ -16059,6 +16099,7 @@ cleanup:
} }
VIR_FREE(data.domains); VIR_FREE(data.domains);
virObjectUnlock(doms);
return ret; return ret;
} }