From a8c25450bd25092009b7ba3b82d3b5b764f12915 Mon Sep 17 00:00:00 2001 From: Michael Weiser Date: Thu, 19 Dec 2019 22:52:33 +0100 Subject: [PATCH] details: snapshots: Drop saved state on restore Refuse to restore a non-running state from snapshot while there is saved memory state in order to avoid filesystem corruption. Present a message to the user to that effect and let them choose to either abort the operation or drop the saved state before restoring the snapshot. Reviewed-by: Cole Robinson Signed-off-by: Michael Weiser Suggested-by: Cole Robinson --- virtManager/details/snapshots.py | 14 ++++++++++++++ virtManager/object/domain.py | 6 ++++++ 2 files changed, 20 insertions(+) diff --git a/virtManager/details/snapshots.py b/virtManager/details/snapshots.py index 65d014a52..bc5b915a7 100644 --- a/virtManager/details/snapshots.py +++ b/virtManager/details/snapshots.py @@ -656,6 +656,20 @@ class vmmSnapshotPage(vmmGObjectUI): if not result: return + if self.vm.has_managed_save() and not snap.has_run_state(): + result = self.err.ok_cancel( + _("Saved state will be removed to avoid filesystem corruption"), + _("Snapshot '%s' contains only disk and no memory state. " + "Restoring the snapshot would leave the existing saved state " + "in place, effectively switching a disk underneath a running " + "system. Running the domain afterwards would likely result in " + "extensive filesystem corruption. Therefore the saved state " + "will be removed before restoring the snapshot." + ) % snap.get_name()) + if not result: + return + self.vm.remove_saved_image() + log.debug("Running snapshot '%s'", snap.get_name()) vmmAsyncJob.simple_async(self.vm.revert_to_snapshot, [snap], self, diff --git a/virtManager/object/domain.py b/virtManager/object/domain.py index 778d1feef..ec62b3542 100644 --- a/virtManager/object/domain.py +++ b/virtManager/object/domain.py @@ -161,6 +161,12 @@ class vmmDomainSnapshot(vmmLibvirtObject): Captured state is a running domain. """ return self._state_str_to_int() in [libvirt.VIR_DOMAIN_RUNNING] + def has_run_state(self): + """ + Captured state contains run state in addition to disk state. + """ + return self._state_str_to_int() in [libvirt.VIR_DOMAIN_RUNNING, + libvirt.VIR_DOMAIN_PAUSED] def is_current(self): return self._backend.isCurrent()