提交 b69bbebb 编写于 作者: C Chris Lalancette

Fix up the locking in the snapshot code.

In particular I was forgetting to take the qemuMonitorPrivatePtr
lock (via qemuDomainObjBeginJob), which would cause problems
if two users tried to access the same domain at the same time.
This patch also fixes a problem where I was forgetting to remove
a transient domain from the list of domains.

Thanks to Stephen Shaw for pointing out the problem and testing
out the initial patch.
Signed-off-by: NChris Lalancette <clalance@redhat.com>
上级 0c4010a1
...@@ -10700,7 +10700,6 @@ static virDomainSnapshotPtr qemuDomainSnapshotCreateXML(virDomainPtr domain, ...@@ -10700,7 +10700,6 @@ static virDomainSnapshotPtr qemuDomainSnapshotCreateXML(virDomainPtr domain,
virDomainSnapshotPtr snapshot = NULL; virDomainSnapshotPtr snapshot = NULL;
char uuidstr[VIR_UUID_STRING_BUFLEN]; char uuidstr[VIR_UUID_STRING_BUFLEN];
virDomainSnapshotDefPtr def; virDomainSnapshotDefPtr def;
qemuDomainObjPrivatePtr priv;
const char *qemuimgarg[] = { NULL, "snapshot", "-c", NULL, NULL, NULL }; const char *qemuimgarg[] = { NULL, "snapshot", "-c", NULL, NULL, NULL };
int i; int i;
...@@ -10767,15 +10766,20 @@ static virDomainSnapshotPtr qemuDomainSnapshotCreateXML(virDomainPtr domain, ...@@ -10767,15 +10766,20 @@ static virDomainSnapshotPtr qemuDomainSnapshotCreateXML(virDomainPtr domain,
} }
} }
else { else {
qemuDomainObjPrivatePtr priv;
int ret;
if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
goto cleanup;
priv = vm->privateData; priv = vm->privateData;
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitorWithDriver(driver, vm);
if (qemuMonitorCreateSnapshot(priv->mon, def->name) < 0) { ret = qemuMonitorCreateSnapshot(priv->mon, def->name);
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitorWithDriver(driver, vm);
if (qemuDomainObjEndJob(vm) == 0)
vm = NULL;
if (ret < 0)
goto cleanup; goto cleanup;
} }
qemuDomainObjExitMonitorWithDriver(driver, vm);
}
snap->def->state = vm->state; snap->def->state = vm->state;
...@@ -11047,18 +11051,18 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, ...@@ -11047,18 +11051,18 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
rc = qemuMonitorLoadSnapshot(priv->mon, snap->def->name); rc = qemuMonitorLoadSnapshot(priv->mon, snap->def->name);
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitorWithDriver(driver, vm);
if (rc < 0) if (rc < 0)
goto cleanup; goto endjob;
} }
else { else {
if (qemuDomainSnapshotSetActive(vm, driver->snapshotDir) < 0) if (qemuDomainSnapshotSetActive(vm, driver->snapshotDir) < 0)
goto cleanup; goto endjob;
rc = qemudStartVMDaemon(snapshot->domain->conn, driver, vm, NULL, rc = qemudStartVMDaemon(snapshot->domain->conn, driver, vm, NULL,
-1); -1);
if (qemuDomainSnapshotSetInactive(vm, driver->snapshotDir) < 0) if (qemuDomainSnapshotSetInactive(vm, driver->snapshotDir) < 0)
goto cleanup; goto endjob;
if (rc < 0) if (rc < 0)
goto cleanup; goto endjob;
} }
if (snap->def->state == VIR_DOMAIN_PAUSED) { if (snap->def->state == VIR_DOMAIN_PAUSED) {
...@@ -11073,7 +11077,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, ...@@ -11073,7 +11077,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitorWithDriver(driver, vm);
if (rc < 0) { if (rc < 0) {
vm->state = state; vm->state = state;
goto cleanup; goto endjob;
} }
} }
...@@ -11097,20 +11101,26 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, ...@@ -11097,20 +11101,26 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
event = virDomainEventNewFromObj(vm, event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT); VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT);
if (!vm->persistent) {
if (qemuDomainObjEndJob(vm) > 0)
virDomainRemoveInactive(&driver->domains, vm);
vm = NULL;
}
} }
if (qemuDomainSnapshotSetActive(vm, driver->snapshotDir) < 0) if (qemuDomainSnapshotSetActive(vm, driver->snapshotDir) < 0)
goto cleanup; goto endjob;
} }
vm->state = snap->def->state; vm->state = snap->def->state;
ret = 0; ret = 0;
cleanup: endjob:
if (vm && qemuDomainObjEndJob(vm) == 0) if (vm && qemuDomainObjEndJob(vm) == 0)
vm = NULL; vm = NULL;
cleanup:
if (event) if (event)
qemuDomainEventQueue(driver, event); qemuDomainEventQueue(driver, event);
if (vm) if (vm)
...@@ -11264,6 +11274,9 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, ...@@ -11264,6 +11274,9 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
goto cleanup; goto cleanup;
} }
if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
goto cleanup;
if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN) { if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN) {
rem.driver = driver; rem.driver = driver;
rem.vm = vm; rem.vm = vm;
...@@ -11272,11 +11285,15 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, ...@@ -11272,11 +11285,15 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
virHashForEach(vm->snapshots.objs, qemuDomainSnapshotDiscardChildren, virHashForEach(vm->snapshots.objs, qemuDomainSnapshotDiscardChildren,
&rem); &rem);
if (rem.err < 0) if (rem.err < 0)
goto cleanup; goto endjob;
} }
ret = qemuDomainSnapshotDiscard(driver, vm, snap); ret = qemuDomainSnapshotDiscard(driver, vm, snap);
endjob:
if (qemuDomainObjEndJob(vm) == 0)
vm = NULL;
cleanup: cleanup:
if (vm) if (vm)
virDomainObjUnlock(vm); virDomainObjUnlock(vm);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册