From: Jincheng Miao <jmiao(a)redhat.com>
The code would lookup the snapshot object before acquiring the job. This
could lead to a crash as one thread could delete the snapshot object,
while a second thread already had the reference.
Signed-off-by: Jincheng Miao <jmiao(a)redhat.com>
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_driver.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9f200f0..8e5c353 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -14013,9 +14013,12 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr
snapshot,
goto cleanup;
}
- if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
+ if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ goto endjob;
+
if (!vm->persistent &&
snap->def->state != VIR_DOMAIN_RUNNING &&
snap->def->state != VIR_DOMAIN_PAUSED &&
@@ -14024,13 +14027,13 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr
snapshot,
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("transient domain needs to request run or pause "
"to revert to inactive snapshot"));
- goto cleanup;
+ goto endjob;
}
if (virDomainSnapshotIsExternal(snap)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("revert to external snapshot not supported yet"));
- goto cleanup;
+ goto endjob;
}
if (!(flags & VIR_DOMAIN_SNAPSHOT_REVERT_FORCE)) {
@@ -14038,7 +14041,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr
snapshot,
virReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY,
_("snapshot '%s' lacks domain '%s'
rollback info"),
snap->def->name, vm->def->name);
- goto cleanup;
+ goto endjob;
}
if (virDomainObjIsActive(vm) &&
!(snap->def->state == VIR_DOMAIN_RUNNING
@@ -14047,7 +14050,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr
snapshot,
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED))) {
virReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY, "%s",
_("must respawn qemu to start inactive snapshot"));
- goto cleanup;
+ goto endjob;
}
}
@@ -14056,7 +14059,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr
snapshot,
vm->current_snapshot->def->current = false;
if (qemuDomainSnapshotWriteMetadata(vm, vm->current_snapshot,
cfg->snapshotDir) < 0)
- goto cleanup;
+ goto endjob;
vm->current_snapshot = NULL;
/* XXX Should we restore vm->current_snapshot after this point
* in the failure cases where we know there was no change? */
@@ -14071,12 +14074,9 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr
snapshot,
if (snap->def->dom) {
config = virDomainDefCopy(snap->def->dom, caps, driver->xmlopt, true);
if (!config)
- goto cleanup;
+ goto endjob;
}
- if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
- goto cleanup;
-
switch ((virDomainState) snap->def->state) {
case VIR_DOMAIN_RUNNING:
case VIR_DOMAIN_PAUSED:
@@ -14386,9 +14386,12 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr
snapshot,
if (virDomainSnapshotDeleteEnsureACL(snapshot->domain->conn, vm->def) <
0)
goto cleanup;
- if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
+ if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
+ goto endjob;
+
if (!metadata_only) {
if (!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) &&
virDomainSnapshotIsExternal(snap))
@@ -14401,13 +14404,10 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr
snapshot,
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("deletion of %d external disk snapshots not "
"supported yet"), external);
- goto cleanup;
+ goto endjob;
}
}
- if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
- goto cleanup;
-
if (flags & (VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN |
VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY)) {
rem.driver = driver;
--
2.0.2