提交 d301bc8d 编写于 作者: M Michal Privoznik

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: NMichal Privoznik <mprivozn@redhat.com>
Reviewed-by: NJán Tomko <jtomko@redhat.com>
上级 56f024f4
...@@ -114,7 +114,7 @@ bhyveAutostartDomains(bhyveConnPtr driver) ...@@ -114,7 +114,7 @@ bhyveAutostartDomains(bhyveConnPtr driver)
struct bhyveAutostartData data = { driver, conn }; struct bhyveAutostartData data = { driver, conn };
virDomainObjListForEach(driver->domains, bhyveAutostartDomain, &data); virDomainObjListForEach(driver->domains, false, bhyveAutostartDomain, &data);
virObjectUnref(conn); virObjectUnref(conn);
} }
......
...@@ -466,7 +466,7 @@ virBhyveProcessReconnectAll(bhyveConnPtr driver) ...@@ -466,7 +466,7 @@ virBhyveProcessReconnectAll(bhyveConnPtr driver)
data.driver = driver; data.driver = driver;
data.kd = kd; data.kd = kd;
virDomainObjListForEach(driver->domains, virBhyveProcessReconnect, &data); virDomainObjListForEach(driver->domains, false, virBhyveProcessReconnect, &data);
kvm_close(kd); kvm_close(kd);
} }
...@@ -818,24 +818,32 @@ virDomainObjListHelper(void *payload, ...@@ -818,24 +818,32 @@ virDomainObjListHelper(void *payload,
/** /**
* virDomainObjListForEach: * virDomainObjListForEach:
* @doms: Pointer to the domain object list * @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 * @callback: callback to run over each domain on the list
* @opaque: opaque data to pass to @callback * @opaque: opaque data to pass to @callback
* *
* For every domain on the list (@doms) run @callback on it. If * For every domain on the list (@doms) run @callback on it. If
* @callback fails (i.e. returns a negative value), the iteration * @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, * Returns: 0 on success,
* -1 otherwise. * -1 otherwise.
*/ */
int int
virDomainObjListForEach(virDomainObjListPtr doms, virDomainObjListForEach(virDomainObjListPtr doms,
bool modify,
virDomainObjListIterator callback, virDomainObjListIterator callback,
void *opaque) void *opaque)
{ {
struct virDomainListIterData data = { struct virDomainListIterData data = {
callback, opaque, 0, callback, opaque, 0,
}; };
if (modify)
virObjectRWLockWrite(doms);
else
virObjectRWLockRead(doms); virObjectRWLockRead(doms);
virHashForEach(doms->objs, virDomainObjListHelper, &data); virHashForEach(doms->objs, virDomainObjListHelper, &data);
virObjectRWUnlock(doms); virObjectRWUnlock(doms);
......
...@@ -91,6 +91,7 @@ typedef int (*virDomainObjListIterator)(virDomainObjPtr dom, ...@@ -91,6 +91,7 @@ typedef int (*virDomainObjListIterator)(virDomainObjPtr dom,
void *opaque); void *opaque);
int virDomainObjListForEach(virDomainObjListPtr doms, int virDomainObjListForEach(virDomainObjListPtr doms,
bool modify,
virDomainObjListIterator callback, virDomainObjListIterator callback,
void *opaque); void *opaque);
......
...@@ -497,7 +497,7 @@ libxlReconnectDomain(virDomainObjPtr vm, ...@@ -497,7 +497,7 @@ libxlReconnectDomain(virDomainObjPtr vm,
static void static void
libxlReconnectDomains(libxlDriverPrivatePtr driver) libxlReconnectDomains(libxlDriverPrivatePtr driver)
{ {
virDomainObjListForEach(driver->domains, libxlReconnectDomain, driver); virDomainObjListForEach(driver->domains, true, libxlReconnectDomain, driver);
} }
static int static int
...@@ -800,10 +800,12 @@ libxlStateInitialize(bool privileged, ...@@ -800,10 +800,12 @@ libxlStateInitialize(bool privileged,
NULL, NULL) < 0) NULL, NULL) < 0)
goto error; goto error;
virDomainObjListForEach(libxl_driver->domains, libxlAutostartDomain, virDomainObjListForEach(libxl_driver->domains, false,
libxlAutostartDomain,
libxl_driver); libxl_driver);
virDomainObjListForEach(libxl_driver->domains, libxlDomainManagedSaveLoad, virDomainObjListForEach(libxl_driver->domains, false,
libxlDomainManagedSaveLoad,
libxl_driver); libxl_driver);
return VIR_DRV_STATE_INIT_COMPLETE; return VIR_DRV_STATE_INIT_COMPLETE;
...@@ -832,7 +834,8 @@ libxlStateReload(void) ...@@ -832,7 +834,8 @@ libxlStateReload(void)
libxl_driver->xmlopt, libxl_driver->xmlopt,
NULL, libxl_driver); NULL, libxl_driver);
virDomainObjListForEach(libxl_driver->domains, libxlAutostartDomain, virDomainObjListForEach(libxl_driver->domains, false,
libxlAutostartDomain,
libxl_driver); libxl_driver);
virObjectUnref(cfg); virObjectUnref(cfg);
......
...@@ -1639,7 +1639,7 @@ virLXCProcessAutostartAll(virLXCDriverPtr driver) ...@@ -1639,7 +1639,7 @@ virLXCProcessAutostartAll(virLXCDriverPtr driver)
struct virLXCProcessAutostartData data = { driver, conn }; struct virLXCProcessAutostartData data = { driver, conn };
virDomainObjListForEach(driver->domains, virDomainObjListForEach(driver->domains, false,
virLXCProcessAutostartDomain, virLXCProcessAutostartDomain,
&data); &data);
...@@ -1760,6 +1760,6 @@ virLXCProcessReconnectDomain(virDomainObjPtr vm, ...@@ -1760,6 +1760,6 @@ virLXCProcessReconnectDomain(virDomainObjPtr vm,
int virLXCProcessReconnectAll(virLXCDriverPtr driver, int virLXCProcessReconnectAll(virLXCDriverPtr driver,
virDomainObjListPtr doms) virDomainObjListPtr doms)
{ {
virDomainObjListForEach(doms, virLXCProcessReconnectDomain, driver); virDomainObjListForEach(doms, false, virLXCProcessReconnectDomain, driver);
return 0; return 0;
} }
...@@ -304,7 +304,7 @@ qemuAutostartDomain(virDomainObjPtr vm, ...@@ -304,7 +304,7 @@ qemuAutostartDomain(virDomainObjPtr vm,
static void static void
qemuAutostartDomains(virQEMUDriverPtr driver) qemuAutostartDomains(virQEMUDriverPtr driver)
{ {
virDomainObjListForEach(driver->domains, qemuAutostartDomain, driver); virDomainObjListForEach(driver->domains, false, qemuAutostartDomain, driver);
} }
...@@ -1055,10 +1055,12 @@ qemuStateInitialize(bool privileged, ...@@ -1055,10 +1055,12 @@ qemuStateInitialize(bool privileged,
* the driver with. This is to avoid race between autostart and reconnect * the driver with. This is to avoid race between autostart and reconnect
* threads */ * threads */
virDomainObjListForEach(qemu_driver->domains, virDomainObjListForEach(qemu_driver->domains,
false,
qemuDomainFindMaxID, qemuDomainFindMaxID,
&qemu_driver->lastvmid); &qemu_driver->lastvmid);
virDomainObjListForEach(qemu_driver->domains, virDomainObjListForEach(qemu_driver->domains,
false,
qemuDomainNetsRestart, qemuDomainNetsRestart,
NULL); NULL);
...@@ -1072,14 +1074,17 @@ qemuStateInitialize(bool privileged, ...@@ -1072,14 +1074,17 @@ qemuStateInitialize(bool privileged,
goto error; goto error;
virDomainObjListForEach(qemu_driver->domains, virDomainObjListForEach(qemu_driver->domains,
false,
qemuDomainSnapshotLoad, qemuDomainSnapshotLoad,
cfg->snapshotDir); cfg->snapshotDir);
virDomainObjListForEach(qemu_driver->domains, virDomainObjListForEach(qemu_driver->domains,
false,
qemuDomainCheckpointLoad, qemuDomainCheckpointLoad,
cfg->checkpointDir); cfg->checkpointDir);
virDomainObjListForEach(qemu_driver->domains, virDomainObjListForEach(qemu_driver->domains,
false,
qemuDomainManagedSaveLoad, qemuDomainManagedSaveLoad,
qemu_driver); qemu_driver);
......
...@@ -8369,7 +8369,8 @@ void ...@@ -8369,7 +8369,8 @@ void
qemuProcessReconnectAll(virQEMUDriverPtr driver) qemuProcessReconnectAll(virQEMUDriverPtr driver)
{ {
struct qemuProcessReconnectData data = {.driver = 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) ...@@ -990,7 +990,7 @@ static int vmwareDomainObjListUpdateDomain(virDomainObjPtr dom, void *data)
static void static void
vmwareDomainObjListUpdateAll(virDomainObjListPtr doms, struct vmware_driver *driver) vmwareDomainObjListUpdateAll(virDomainObjListPtr doms, struct vmware_driver *driver)
{ {
virDomainObjListForEach(doms, vmwareDomainObjListUpdateDomain, driver); virDomainObjListForEach(doms, false, vmwareDomainObjListUpdateDomain, driver);
} }
static int static int
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册