Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
src/qemu/qemu_snapshot.c | 148 ++++++++++++++++++++++-----------------
1 file changed, 83 insertions(+), 65 deletions(-)
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 6b300d808a..1a32b15f51 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -2153,6 +2153,84 @@ qemuSnapshotInternalRevertInactive(virQEMUDriver *driver,
}
+static int
+qemuSnapshotRevertInactive(virDomainObj *vm,
+ virDomainSnapshotPtr snapshot,
+ virDomainMomentObj *snap,
+ virQEMUDriver *driver,
+ virQEMUDriverConfig *cfg,
+ virDomainDef **inactiveConfig,
+ unsigned int start_flags,
+ unsigned int flags)
+{
+ virObjectEvent *event = NULL;
+ virObjectEvent *event2 = NULL;
+ int detail;
+ bool defined = false;
+ int rc;
+
+ /* Transitions 1, 4, 7 */
+ /* Newer qemu -loadvm refuses to revert to the state of a snapshot
+ * created by qemu-img snapshot -c. If the domain is running, we
+ * must take it offline; then do the revert using qemu-img.
+ */
+
+ if (virDomainObjIsActive(vm)) {
+ /* Transitions 4, 7 */
+ qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT,
+ QEMU_ASYNC_JOB_START, 0);
+ virDomainAuditStop(vm, "from-snapshot");
+ detail = VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT;
+ event = virDomainEventLifecycleNewFromObj(vm,
+ VIR_DOMAIN_EVENT_STOPPED,
+ detail);
+ virObjectEventStateQueue(driver->domainEventState, event);
+ }
+
+ if (qemuSnapshotInternalRevertInactive(driver, vm, snap) < 0) {
+ qemuDomainRemoveInactive(driver, vm);
+ return -1;
+ }
+
+ if (*inactiveConfig) {
+ virDomainObjAssignDef(vm, inactiveConfig, false, NULL);
+ return -1;
+ }
+
+ if (flags & (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
+ VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED)) {
+ /* Flush first event, now do transition 2 or 3 */
+ bool paused = (flags & VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED) != 0;
+
+ start_flags |= paused ? VIR_QEMU_PROCESS_START_PAUSED : 0;
+
+ rc = qemuProcessStart(snapshot->domain->conn, driver, vm, NULL,
+ QEMU_ASYNC_JOB_START, NULL, -1, NULL, NULL,
+ VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
+ start_flags);
+ virDomainAuditStart(vm, "from-snapshot", rc >= 0);
+ if (rc < 0) {
+ qemuDomainRemoveInactive(driver, vm);
+ return -1;
+ }
+ detail = VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT;
+ event = virDomainEventLifecycleNewFromObj(vm,
+ VIR_DOMAIN_EVENT_STARTED,
+ detail);
+ virObjectEventStateQueue(driver->domainEventState, event);
+ if (paused) {
+ detail = VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT;
+ event2 = virDomainEventLifecycleNewFromObj(vm,
+ VIR_DOMAIN_EVENT_SUSPENDED,
+ detail);
+ virObjectEventStateQueue(driver->domainEventState, event2);
+ }
+ }
+
+ return qemuSnapshotRevertWriteMetadata(vm, snap, driver, cfg, defined);
+}
+
+
int
qemuSnapshotRevert(virDomainObj *vm,
virDomainSnapshotPtr snapshot,
@@ -2162,15 +2240,10 @@ qemuSnapshotRevert(virDomainObj *vm,
int ret = -1;
virDomainMomentObj *snap = NULL;
virDomainSnapshotDef *snapdef;
- virObjectEvent *event = NULL;
- virObjectEvent *event2 = NULL;
- int detail;
- int rc;
g_autoptr(virDomainDef) config = NULL;
g_autoptr(virDomainDef) inactiveConfig = NULL;
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
unsigned int start_flags = VIR_QEMU_PROCESS_START_GEN_VMID;
- bool defined = false;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED |
@@ -2224,64 +2297,11 @@ qemuSnapshotRevert(virDomainObj *vm,
case VIR_DOMAIN_SNAPSHOT_SHUTDOWN:
case VIR_DOMAIN_SNAPSHOT_SHUTOFF:
case VIR_DOMAIN_SNAPSHOT_CRASHED:
- /* Transitions 1, 4, 7 */
- /* Newer qemu -loadvm refuses to revert to the state of a snapshot
- * created by qemu-img snapshot -c. If the domain is running, we
- * must take it offline; then do the revert using qemu-img.
- */
-
- if (virDomainObjIsActive(vm)) {
- /* Transitions 4, 7 */
- qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT,
- QEMU_ASYNC_JOB_START, 0);
- virDomainAuditStop(vm, "from-snapshot");
- detail = VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT;
- event = virDomainEventLifecycleNewFromObj(vm,
- VIR_DOMAIN_EVENT_STOPPED,
- detail);
- virObjectEventStateQueue(driver->domainEventState, event);
- }
-
- if (qemuSnapshotInternalRevertInactive(driver, vm, snap) < 0) {
- qemuDomainRemoveInactive(driver, vm);
- goto endjob;
- }
-
- if (inactiveConfig) {
- virDomainObjAssignDef(vm, &inactiveConfig, false, NULL);
- defined = true;
- }
-
- if (flags & (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
- VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED)) {
- /* Flush first event, now do transition 2 or 3 */
- bool paused = (flags & VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED) != 0;
-
- start_flags |= paused ? VIR_QEMU_PROCESS_START_PAUSED : 0;
-
- rc = qemuProcessStart(snapshot->domain->conn, driver, vm, NULL,
- QEMU_ASYNC_JOB_START, NULL, -1, NULL, NULL,
- VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
- start_flags);
- virDomainAuditStart(vm, "from-snapshot", rc >= 0);
- if (rc < 0) {
- qemuDomainRemoveInactive(driver, vm);
- goto endjob;
- }
- detail = VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT;
- event = virDomainEventLifecycleNewFromObj(vm,
- VIR_DOMAIN_EVENT_STARTED,
- detail);
- virObjectEventStateQueue(driver->domainEventState, event);
- if (paused) {
- detail = VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT;
- event2 = virDomainEventLifecycleNewFromObj(vm,
- VIR_DOMAIN_EVENT_SUSPENDED,
- detail);
- virObjectEventStateQueue(driver->domainEventState, event2);
- }
- }
- break;
+ ret = qemuSnapshotRevertInactive(vm, snapshot, snap,
+ driver, cfg,
+ &inactiveConfig,
+ start_flags, flags);
+ goto endjob;
case VIR_DOMAIN_SNAPSHOT_PMSUSPENDED:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
@@ -2301,8 +2321,6 @@ qemuSnapshotRevert(virDomainObj *vm,
goto endjob;
}
- ret = qemuSnapshotRevertWriteMetadata(vm, snap, driver, cfg, defined);
-
endjob:
qemuProcessEndJob(driver, vm);
--
2.31.1