mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-02 09:55:18 +00:00
lib: Grab write lock when modifying list of domains
In some places where virDomainObjListForEach() is called the passed callback calls virDomainObjListRemoveLocked(). Well, this is unsafe, because the former only grabs a read lock but the latter modifies the list. I've identified the following unsafe calls: - qemuProcessReconnectAll() - libxlReconnectDomains() The rest seem to be safe. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
56f024f457
commit
d301bc8d08
@ -114,7 +114,7 @@ bhyveAutostartDomains(bhyveConnPtr driver)
|
||||
|
||||
struct bhyveAutostartData data = { driver, conn };
|
||||
|
||||
virDomainObjListForEach(driver->domains, bhyveAutostartDomain, &data);
|
||||
virDomainObjListForEach(driver->domains, false, bhyveAutostartDomain, &data);
|
||||
|
||||
virObjectUnref(conn);
|
||||
}
|
||||
|
@ -466,7 +466,7 @@ virBhyveProcessReconnectAll(bhyveConnPtr driver)
|
||||
data.driver = driver;
|
||||
data.kd = kd;
|
||||
|
||||
virDomainObjListForEach(driver->domains, virBhyveProcessReconnect, &data);
|
||||
virDomainObjListForEach(driver->domains, false, virBhyveProcessReconnect, &data);
|
||||
|
||||
kvm_close(kd);
|
||||
}
|
||||
|
@ -818,24 +818,32 @@ virDomainObjListHelper(void *payload,
|
||||
/**
|
||||
* virDomainObjListForEach:
|
||||
* @doms: Pointer to the domain object list
|
||||
* @modify: Whether to lock @doms for modify operation
|
||||
* @callback: callback to run over each domain on the list
|
||||
* @opaque: opaque data to pass to @callback
|
||||
*
|
||||
* For every domain on the list (@doms) run @callback on it. If
|
||||
* @callback fails (i.e. returns a negative value), the iteration
|
||||
* carries still on until all domains are visited.
|
||||
* carries still on until all domains are visited. Moreover, if
|
||||
* @callback wants to modify the list of domains (@doms) then
|
||||
* @modify must be set to true.
|
||||
*
|
||||
* Returns: 0 on success,
|
||||
* -1 otherwise.
|
||||
*/
|
||||
int
|
||||
virDomainObjListForEach(virDomainObjListPtr doms,
|
||||
bool modify,
|
||||
virDomainObjListIterator callback,
|
||||
void *opaque)
|
||||
{
|
||||
struct virDomainListIterData data = {
|
||||
callback, opaque, 0,
|
||||
};
|
||||
|
||||
if (modify)
|
||||
virObjectRWLockWrite(doms);
|
||||
else
|
||||
virObjectRWLockRead(doms);
|
||||
virHashForEach(doms->objs, virDomainObjListHelper, &data);
|
||||
virObjectRWUnlock(doms);
|
||||
|
@ -91,6 +91,7 @@ typedef int (*virDomainObjListIterator)(virDomainObjPtr dom,
|
||||
void *opaque);
|
||||
|
||||
int virDomainObjListForEach(virDomainObjListPtr doms,
|
||||
bool modify,
|
||||
virDomainObjListIterator callback,
|
||||
void *opaque);
|
||||
|
||||
|
@ -497,7 +497,7 @@ libxlReconnectDomain(virDomainObjPtr vm,
|
||||
static void
|
||||
libxlReconnectDomains(libxlDriverPrivatePtr driver)
|
||||
{
|
||||
virDomainObjListForEach(driver->domains, libxlReconnectDomain, driver);
|
||||
virDomainObjListForEach(driver->domains, true, libxlReconnectDomain, driver);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -800,10 +800,12 @@ libxlStateInitialize(bool privileged,
|
||||
NULL, NULL) < 0)
|
||||
goto error;
|
||||
|
||||
virDomainObjListForEach(libxl_driver->domains, libxlAutostartDomain,
|
||||
virDomainObjListForEach(libxl_driver->domains, false,
|
||||
libxlAutostartDomain,
|
||||
libxl_driver);
|
||||
|
||||
virDomainObjListForEach(libxl_driver->domains, libxlDomainManagedSaveLoad,
|
||||
virDomainObjListForEach(libxl_driver->domains, false,
|
||||
libxlDomainManagedSaveLoad,
|
||||
libxl_driver);
|
||||
|
||||
return VIR_DRV_STATE_INIT_COMPLETE;
|
||||
@ -832,7 +834,8 @@ libxlStateReload(void)
|
||||
libxl_driver->xmlopt,
|
||||
NULL, libxl_driver);
|
||||
|
||||
virDomainObjListForEach(libxl_driver->domains, libxlAutostartDomain,
|
||||
virDomainObjListForEach(libxl_driver->domains, false,
|
||||
libxlAutostartDomain,
|
||||
libxl_driver);
|
||||
|
||||
virObjectUnref(cfg);
|
||||
|
@ -1639,7 +1639,7 @@ virLXCProcessAutostartAll(virLXCDriverPtr driver)
|
||||
|
||||
struct virLXCProcessAutostartData data = { driver, conn };
|
||||
|
||||
virDomainObjListForEach(driver->domains,
|
||||
virDomainObjListForEach(driver->domains, false,
|
||||
virLXCProcessAutostartDomain,
|
||||
&data);
|
||||
|
||||
@ -1760,6 +1760,6 @@ virLXCProcessReconnectDomain(virDomainObjPtr vm,
|
||||
int virLXCProcessReconnectAll(virLXCDriverPtr driver,
|
||||
virDomainObjListPtr doms)
|
||||
{
|
||||
virDomainObjListForEach(doms, virLXCProcessReconnectDomain, driver);
|
||||
virDomainObjListForEach(doms, false, virLXCProcessReconnectDomain, driver);
|
||||
return 0;
|
||||
}
|
||||
|
@ -304,7 +304,7 @@ qemuAutostartDomain(virDomainObjPtr vm,
|
||||
static void
|
||||
qemuAutostartDomains(virQEMUDriverPtr driver)
|
||||
{
|
||||
virDomainObjListForEach(driver->domains, qemuAutostartDomain, driver);
|
||||
virDomainObjListForEach(driver->domains, false, qemuAutostartDomain, driver);
|
||||
}
|
||||
|
||||
|
||||
@ -1055,10 +1055,12 @@ qemuStateInitialize(bool privileged,
|
||||
* the driver with. This is to avoid race between autostart and reconnect
|
||||
* threads */
|
||||
virDomainObjListForEach(qemu_driver->domains,
|
||||
false,
|
||||
qemuDomainFindMaxID,
|
||||
&qemu_driver->lastvmid);
|
||||
|
||||
virDomainObjListForEach(qemu_driver->domains,
|
||||
false,
|
||||
qemuDomainNetsRestart,
|
||||
NULL);
|
||||
|
||||
@ -1072,14 +1074,17 @@ qemuStateInitialize(bool privileged,
|
||||
goto error;
|
||||
|
||||
virDomainObjListForEach(qemu_driver->domains,
|
||||
false,
|
||||
qemuDomainSnapshotLoad,
|
||||
cfg->snapshotDir);
|
||||
|
||||
virDomainObjListForEach(qemu_driver->domains,
|
||||
false,
|
||||
qemuDomainCheckpointLoad,
|
||||
cfg->checkpointDir);
|
||||
|
||||
virDomainObjListForEach(qemu_driver->domains,
|
||||
false,
|
||||
qemuDomainManagedSaveLoad,
|
||||
qemu_driver);
|
||||
|
||||
|
@ -8369,7 +8369,8 @@ void
|
||||
qemuProcessReconnectAll(virQEMUDriverPtr driver)
|
||||
{
|
||||
struct qemuProcessReconnectData data = {.driver = driver};
|
||||
virDomainObjListForEach(driver->domains, qemuProcessReconnectHelper, &data);
|
||||
virDomainObjListForEach(driver->domains, true,
|
||||
qemuProcessReconnectHelper, &data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -990,7 +990,7 @@ static int vmwareDomainObjListUpdateDomain(virDomainObjPtr dom, void *data)
|
||||
static void
|
||||
vmwareDomainObjListUpdateAll(virDomainObjListPtr doms, struct vmware_driver *driver)
|
||||
{
|
||||
virDomainObjListForEach(doms, vmwareDomainObjListUpdateDomain, driver);
|
||||
virDomainObjListForEach(doms, false, vmwareDomainObjListUpdateDomain, driver);
|
||||
}
|
||||
|
||||
static int
|
||||
|
Loading…
x
Reference in New Issue
Block a user