mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
snapshot: enforce REVERT_FORCE on qemu
Implements the documentation for snapshot revert vs. force. Part of the patch tightens existing behavior (previously, reverting to an old snapshot without <domain> was blindly attempted, now it requires force), while part of it relaxes behavior (previously, it was not possible to revert an active domain to an ABI-incompatible active snapshot, now force allows this transition). * src/qemu/qemu_driver.c (qemuDomainRevertToSnapshot): Check for risky situations, and allow force to get past them.
This commit is contained in:
parent
70e015e12f
commit
29879b550b
@ -9654,7 +9654,8 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
|
|||||||
virDomainDefPtr config = NULL;
|
virDomainDefPtr config = NULL;
|
||||||
|
|
||||||
virCheckFlags(VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
|
||||||
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED, -1);
|
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED |
|
||||||
|
VIR_DOMAIN_SNAPSHOT_REVERT_FORCE, -1);
|
||||||
|
|
||||||
/* We have the following transitions, which create the following events:
|
/* We have the following transitions, which create the following events:
|
||||||
* 1. inactive -> inactive: none
|
* 1. inactive -> inactive: none
|
||||||
@ -9666,7 +9667,8 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
|
|||||||
* 7. paused -> inactive: EVENT_STOPPED
|
* 7. paused -> inactive: EVENT_STOPPED
|
||||||
* 8. paused -> running: EVENT_RESUMED
|
* 8. paused -> running: EVENT_RESUMED
|
||||||
* 9. paused -> paused: none
|
* 9. paused -> paused: none
|
||||||
* Also, several transitions occur even if we fail partway through.
|
* Also, several transitions occur even if we fail partway through,
|
||||||
|
* and use of FORCE can cause multiple transitions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
qemuDriverLock(driver);
|
qemuDriverLock(driver);
|
||||||
@ -9702,6 +9704,24 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
|
|||||||
"yet"));
|
"yet"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
if (!(flags & VIR_DOMAIN_SNAPSHOT_REVERT_FORCE)) {
|
||||||
|
if (!snap->def->dom) {
|
||||||
|
qemuReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY,
|
||||||
|
_("snapshot '%s' lacks domain '%s' rollback info"),
|
||||||
|
snap->def->name, vm->def->name);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (virDomainObjIsActive(vm) &&
|
||||||
|
!(snap->def->state == VIR_DOMAIN_RUNNING
|
||||||
|
|| snap->def->state == VIR_DOMAIN_PAUSED) &&
|
||||||
|
(flags & (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
|
||||||
|
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED))) {
|
||||||
|
qemuReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY,
|
||||||
|
_("must respawn qemu to start inactive snapshot"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (vm->current_snapshot) {
|
if (vm->current_snapshot) {
|
||||||
vm->current_snapshot->def->current = false;
|
vm->current_snapshot->def->current = false;
|
||||||
@ -9731,11 +9751,6 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
|
|||||||
VIR_FREE(xml);
|
VIR_FREE(xml);
|
||||||
if (!config)
|
if (!config)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else {
|
|
||||||
/* XXX Fail if VIR_DOMAIN_REVERT_FORCE is not set, rather than
|
|
||||||
* blindly hoping for the best. */
|
|
||||||
VIR_WARN("snapshot is lacking rollback information for domain '%s'",
|
|
||||||
snap->def->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
|
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
|
||||||
@ -9756,10 +9771,26 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
|
|||||||
/* Transitions 5, 6, 8, 9 */
|
/* Transitions 5, 6, 8, 9 */
|
||||||
/* Check for ABI compatibility. */
|
/* Check for ABI compatibility. */
|
||||||
if (config && !virDomainDefCheckABIStability(vm->def, config)) {
|
if (config && !virDomainDefCheckABIStability(vm->def, config)) {
|
||||||
/* XXX Add VIR_DOMAIN_REVERT_FORCE to permit killing
|
virErrorPtr err = virGetLastError();
|
||||||
* and restarting a new qemu, since loadvm monitor
|
|
||||||
* command won't work. */
|
if (!(flags & VIR_DOMAIN_SNAPSHOT_REVERT_FORCE)) {
|
||||||
goto endjob;
|
/* Re-spawn error using correct category. */
|
||||||
|
if (err->code == VIR_ERR_CONFIG_UNSUPPORTED)
|
||||||
|
qemuReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY, "%s",
|
||||||
|
err->str2);
|
||||||
|
goto endjob;
|
||||||
|
}
|
||||||
|
virResetError(err);
|
||||||
|
qemuProcessStop(driver, vm, 0,
|
||||||
|
VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT);
|
||||||
|
virDomainAuditStop(vm, "from-snapshot");
|
||||||
|
detail = VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT;
|
||||||
|
event = virDomainEventNewFromObj(vm,
|
||||||
|
VIR_DOMAIN_EVENT_STOPPED,
|
||||||
|
detail);
|
||||||
|
if (event)
|
||||||
|
qemuDomainEventQueue(driver, event);
|
||||||
|
goto load;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv = vm->privateData;
|
priv = vm->privateData;
|
||||||
@ -9795,6 +9826,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
|
|||||||
virDomainObjAssignDef(vm, config, false);
|
virDomainObjAssignDef(vm, config, false);
|
||||||
} else {
|
} else {
|
||||||
/* Transitions 2, 3 */
|
/* Transitions 2, 3 */
|
||||||
|
load:
|
||||||
was_stopped = true;
|
was_stopped = true;
|
||||||
if (config)
|
if (config)
|
||||||
virDomainObjAssignDef(vm, config, false);
|
virDomainObjAssignDef(vm, config, false);
|
||||||
|
Loading…
Reference in New Issue
Block a user