提交 d9fcd17e 编写于 作者: E Eric Blake

qemu: fix nested job with driver lock held

qemuMigrationUpdateJobStatus (called in a loop by migration
and save tasks) uses qemuDomainObjEnterMonitorWithDriver;
however, that function ended up starting a nested job without
releasing the driver.

Since no one else is making nested calls, we can inline the
internal functions to properly track driver_locked.

* src/qemu/qemu_domain.h (qemuDomainObjBeginNestedJob)
(qemuDomainObjBeginNestedJobWithDriver)
(qemuDomainObjEndNestedJob): Drop unused prototypes.
* src/qemu/qemu_domain.c (qemuDomainObjEnterMonitorInternal):
Reflect driver lock to nested job.
(qemuDomainObjBeginNestedJob)
(qemuDomainObjBeginNestedJobWithDriver)
(qemuDomainObjEndNestedJob): Drop unused functions.
上级 09d7eba9
...@@ -831,31 +831,6 @@ int qemuDomainObjBeginAsyncJobWithDriver(struct qemud_driver *driver, ...@@ -831,31 +831,6 @@ int qemuDomainObjBeginAsyncJobWithDriver(struct qemud_driver *driver,
asyncJob); asyncJob);
} }
/*
* Use this to protect monitor sections within active async job.
*
* The caller must call qemuDomainObjBeginAsyncJob{,WithDriver} before it can
* use this method. Never use this method if you only own non-async job, use
* qemuDomainObjBeginJob{,WithDriver} instead.
*/
int
qemuDomainObjBeginNestedJob(struct qemud_driver *driver,
virDomainObjPtr obj)
{
return qemuDomainObjBeginJobInternal(driver, false, obj,
QEMU_JOB_ASYNC_NESTED,
QEMU_ASYNC_JOB_NONE);
}
int
qemuDomainObjBeginNestedJobWithDriver(struct qemud_driver *driver,
virDomainObjPtr obj)
{
return qemuDomainObjBeginJobInternal(driver, true, obj,
QEMU_JOB_ASYNC_NESTED,
QEMU_ASYNC_JOB_NONE);
}
/* /*
* obj must be locked before calling, qemud_driver does not matter * obj must be locked before calling, qemud_driver does not matter
* *
...@@ -888,21 +863,6 @@ qemuDomainObjEndAsyncJob(struct qemud_driver *driver, virDomainObjPtr obj) ...@@ -888,21 +863,6 @@ qemuDomainObjEndAsyncJob(struct qemud_driver *driver, virDomainObjPtr obj)
return virDomainObjUnref(obj); return virDomainObjUnref(obj);
} }
void
qemuDomainObjEndNestedJob(struct qemud_driver *driver, virDomainObjPtr obj)
{
qemuDomainObjPrivatePtr priv = obj->privateData;
qemuDomainObjResetJob(priv);
qemuDomainObjSaveJob(driver, obj);
virCondSignal(&priv->job.cond);
/* safe to ignore since the surrounding async job increased the reference
* counter as well */
ignore_value(virDomainObjUnref(obj));
}
static int ATTRIBUTE_NONNULL(1) static int ATTRIBUTE_NONNULL(1)
qemuDomainObjEnterMonitorInternal(struct qemud_driver *driver, qemuDomainObjEnterMonitorInternal(struct qemud_driver *driver,
bool driver_locked, bool driver_locked,
...@@ -911,7 +871,9 @@ qemuDomainObjEnterMonitorInternal(struct qemud_driver *driver, ...@@ -911,7 +871,9 @@ qemuDomainObjEnterMonitorInternal(struct qemud_driver *driver,
qemuDomainObjPrivatePtr priv = obj->privateData; qemuDomainObjPrivatePtr priv = obj->privateData;
if (priv->job.active == QEMU_JOB_NONE && priv->job.asyncJob) { if (priv->job.active == QEMU_JOB_NONE && priv->job.asyncJob) {
if (qemuDomainObjBeginNestedJob(driver, obj) < 0) if (qemuDomainObjBeginJobInternal(driver, driver_locked, obj,
QEMU_JOB_ASYNC_NESTED,
QEMU_ASYNC_JOB_NONE) < 0)
return -1; return -1;
if (!virDomainObjIsActive(obj)) { if (!virDomainObjIsActive(obj)) {
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
...@@ -952,8 +914,15 @@ qemuDomainObjExitMonitorInternal(struct qemud_driver *driver, ...@@ -952,8 +914,15 @@ qemuDomainObjExitMonitorInternal(struct qemud_driver *driver,
priv->mon = NULL; priv->mon = NULL;
} }
if (priv->job.active == QEMU_JOB_ASYNC_NESTED) if (priv->job.active == QEMU_JOB_ASYNC_NESTED) {
qemuDomainObjEndNestedJob(driver, obj); qemuDomainObjResetJob(priv);
qemuDomainObjSaveJob(driver, obj);
virCondSignal(&priv->job.cond);
/* safe to ignore since the surrounding async job increased
* the reference counter as well */
ignore_value(virDomainObjUnref(obj));
}
} }
/* /*
...@@ -962,7 +931,7 @@ qemuDomainObjExitMonitorInternal(struct qemud_driver *driver, ...@@ -962,7 +931,7 @@ qemuDomainObjExitMonitorInternal(struct qemud_driver *driver,
* To be called immediately before any QEMU monitor API call * To be called immediately before any QEMU monitor API call
* Must have already either called qemuDomainObjBeginJob() and checked * Must have already either called qemuDomainObjBeginJob() and checked
* that the VM is still active or called qemuDomainObjBeginAsyncJob, in which * that the VM is still active or called qemuDomainObjBeginAsyncJob, in which
* case this will call qemuDomainObjBeginNestedJob. * case this will start a nested job.
* *
* To be followed with qemuDomainObjExitMonitor() once complete * To be followed with qemuDomainObjExitMonitor() once complete
*/ */
...@@ -988,7 +957,7 @@ void qemuDomainObjExitMonitor(struct qemud_driver *driver, ...@@ -988,7 +957,7 @@ void qemuDomainObjExitMonitor(struct qemud_driver *driver,
* To be called immediately before any QEMU monitor API call * To be called immediately before any QEMU monitor API call
* Must have already either called qemuDomainObjBeginJobWithDriver() and * Must have already either called qemuDomainObjBeginJobWithDriver() and
* checked that the VM is still active or called qemuDomainObjBeginAsyncJob, * checked that the VM is still active or called qemuDomainObjBeginAsyncJob,
* in which case this will call qemuDomainObjBeginNestedJobWithDriver. * in which case this will start a nested job.
* *
* To be followed with qemuDomainObjExitMonitorWithDriver() once complete * To be followed with qemuDomainObjExitMonitorWithDriver() once complete
*/ */
......
...@@ -143,9 +143,6 @@ int qemuDomainObjBeginAsyncJob(struct qemud_driver *driver, ...@@ -143,9 +143,6 @@ int qemuDomainObjBeginAsyncJob(struct qemud_driver *driver,
virDomainObjPtr obj, virDomainObjPtr obj,
enum qemuDomainAsyncJob asyncJob) enum qemuDomainAsyncJob asyncJob)
ATTRIBUTE_RETURN_CHECK; ATTRIBUTE_RETURN_CHECK;
int qemuDomainObjBeginNestedJob(struct qemud_driver *driver,
virDomainObjPtr obj)
ATTRIBUTE_RETURN_CHECK;
int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver, int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver,
virDomainObjPtr obj, virDomainObjPtr obj,
enum qemuDomainJob job) enum qemuDomainJob job)
...@@ -154,9 +151,6 @@ int qemuDomainObjBeginAsyncJobWithDriver(struct qemud_driver *driver, ...@@ -154,9 +151,6 @@ int qemuDomainObjBeginAsyncJobWithDriver(struct qemud_driver *driver,
virDomainObjPtr obj, virDomainObjPtr obj,
enum qemuDomainAsyncJob asyncJob) enum qemuDomainAsyncJob asyncJob)
ATTRIBUTE_RETURN_CHECK; ATTRIBUTE_RETURN_CHECK;
int qemuDomainObjBeginNestedJobWithDriver(struct qemud_driver *driver,
virDomainObjPtr obj)
ATTRIBUTE_RETURN_CHECK;
int qemuDomainObjEndJob(struct qemud_driver *driver, int qemuDomainObjEndJob(struct qemud_driver *driver,
virDomainObjPtr obj) virDomainObjPtr obj)
...@@ -164,9 +158,6 @@ int qemuDomainObjEndJob(struct qemud_driver *driver, ...@@ -164,9 +158,6 @@ int qemuDomainObjEndJob(struct qemud_driver *driver,
int qemuDomainObjEndAsyncJob(struct qemud_driver *driver, int qemuDomainObjEndAsyncJob(struct qemud_driver *driver,
virDomainObjPtr obj) virDomainObjPtr obj)
ATTRIBUTE_RETURN_CHECK; ATTRIBUTE_RETURN_CHECK;
void qemuDomainObjEndNestedJob(struct qemud_driver *driver,
virDomainObjPtr obj);
void qemuDomainObjSetJobPhase(struct qemud_driver *driver, void qemuDomainObjSetJobPhase(struct qemud_driver *driver,
virDomainObjPtr obj, virDomainObjPtr obj,
int phase); int phase);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册