mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-24 13:35:17 +00:00
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: Chris Lalancette <clalance@redhat.com>
This commit is contained in:
parent
0c4010a1d7
commit
b69bbebbba
@ -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,14 +10766,19 @@ 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);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
||||||
|
if (qemuDomainObjEndJob(vm) == 0)
|
||||||
|
vm = NULL;
|
||||||
|
if (ret < 0)
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
snap->def->state = vm->state;
|
snap->def->state = vm->state;
|
||||||
@ -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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user