[pve-devel] [PATCH qemu-server] Fix #2171: VM statefile was not activated
Fabian Grünbichler
f.gruenbichler at proxmox.com
Tue Oct 8 08:36:57 CEST 2019
On October 7, 2019 2:41 pm, Alwin Antreich wrote:
> Machine states that were created on snapshots with memory could not be
> restored on rollback. The state volume was not activated so KVM couldn't
> load the state.
>
> This patch moves the path generation into vm_start and de-/activates the
> state volume.
alternatively, the following could also work and re-use more code so
that we don't miss the next special handling of some corner case.
rolling back from a snapshot with state is just like resuming, but we
want to keep the statefile instead of deleting it.
(untested):
diff --git a/PVE/QemuConfig.pm b/PVE/QemuConfig.pm
index edbf1a7..b70c276 100644
--- a/PVE/QemuConfig.pm
+++ b/PVE/QemuConfig.pm
@@ -358,9 +358,7 @@ sub __snapshot_rollback_vm_stop {
sub __snapshot_rollback_vm_start {
my ($class, $vmid, $vmstate, $data) = @_;
- my $storecfg = PVE::Storage::config();
- my $statefile = PVE::Storage::path($storecfg, $vmstate);
- PVE::QemuServer::vm_start($storecfg, $vmid, $statefile, undef, undef, undef, $data->{forcemachine});
+ PVE::QemuServer::vm_start($storecfg, $vmid, $vmstate, undef, undef, undef, $data->{forcemachine});
}
sub __snapshot_rollback_get_unused {
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 8376260..f2d19e1 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -5418,6 +5418,11 @@ sub vm_start {
print "Resuming suspended VM\n";
}
+ if ($statefile && $statefile ne 'tcp' && $statefile ne 'unix') {
+ # re-use resume code
+ $conf->{vmstate} = $statefile;
+ }
+
my ($cmd, $vollist, $spice_port) = config_to_command($storecfg, $vmid, $conf, $defaults, $forcemachine);
my $migrate_port = 0;
@@ -5465,8 +5470,6 @@ sub vm_start {
push @$cmd, '-incoming', $migrate_uri;
push @$cmd, '-S';
- } else {
- push @$cmd, '-loadstate', $statefile;
}
} elsif ($paused) {
push @$cmd, '-S';
@@ -5616,11 +5619,16 @@ sub vm_start {
property => "guest-stats-polling-interval",
value => 2) if (!defined($conf->{balloon}) || $conf->{balloon});
- if ($is_suspended && (my $vmstate = $conf->{vmstate})) {
- print "Resumed VM, removing state\n";
- delete $conf->@{qw(lock vmstate runningmachine)};
+ if (my $vmstate = $conf->{vmstate}) {
PVE::Storage::deactivate_volumes($storecfg, [$vmstate]);
- PVE::Storage::vdisk_free($storecfg, $vmstate);
+ delete $conf->{vmstate};
+
+ if ($is_suspended) {
+ print "Resumed VM, removing state\n";
+ delete $conf->@{qw(lock runningmachine)};
+ PVE::Storage::vdisk_free($storecfg, $vmstate);
+ }
+
PVE::QemuConfig->write_config($vmid, $conf);
}
>
> Signed-off-by: Alwin Antreich <a.antreich at proxmox.com>
> ---
> PVE/QemuConfig.pm | 3 +--
> PVE/QemuServer.pm | 10 +++++++++-
> 2 files changed, 10 insertions(+), 3 deletions(-)
>
> diff --git a/PVE/QemuConfig.pm b/PVE/QemuConfig.pm
> index edbf1a7..e9796a3 100644
> --- a/PVE/QemuConfig.pm
> +++ b/PVE/QemuConfig.pm
> @@ -359,8 +359,7 @@ sub __snapshot_rollback_vm_start {
> my ($class, $vmid, $vmstate, $data) = @_;
>
> my $storecfg = PVE::Storage::config();
> - my $statefile = PVE::Storage::path($storecfg, $vmstate);
> - PVE::QemuServer::vm_start($storecfg, $vmid, $statefile, undef, undef, undef, $data->{forcemachine});
> + PVE::QemuServer::vm_start($storecfg, $vmid, $vmstate, undef, undef, undef, $data->{forcemachine});
> }
>
> sub __snapshot_rollback_get_unused {
> diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
> index 8376260..39315b3 100644
> --- a/PVE/QemuServer.pm
> +++ b/PVE/QemuServer.pm
> @@ -5420,6 +5420,7 @@ sub vm_start {
>
> my ($cmd, $vollist, $spice_port) = config_to_command($storecfg, $vmid, $conf, $defaults, $forcemachine);
>
> +
> my $migrate_port = 0;
> my $migrate_uri;
> if ($statefile) {
> @@ -5466,7 +5467,12 @@ sub vm_start {
> push @$cmd, '-S';
>
> } else {
> - push @$cmd, '-loadstate', $statefile;
> + my $sfile = $statefile;
> + if (!-e $statefile) {
> + PVE::Storage::activate_volumes($storecfg, [$statefile]);
> + $sfile = PVE::Storage::path($storecfg, $statefile);
> + }
why only activate if the file does not exist? $statefile should be a
full volume ID including storage at this point, it does not make sense
to check for existence?
> + push @$cmd, '-loadstate', $sfile;
> }
> } elsif ($paused) {
> push @$cmd, '-S';
> @@ -5622,6 +5628,8 @@ sub vm_start {
> PVE::Storage::deactivate_volumes($storecfg, [$vmstate]);
> PVE::Storage::vdisk_free($storecfg, $vmstate);
> PVE::QemuConfig->write_config($vmid, $conf);
> + } elsif ($statefile && (!-e $statefile)) {
> + PVE::Storage::deactivate_volumes($storecfg, [$statefile]);
this check looks wrong? we should always deactivate, no need to check
whether it does not exist? (and like above, it always does not exist
AFAICT?)
> }
>
> PVE::GuestHelpers::exec_hookscript($conf, $vmid, 'post-start');
> --
> 2.20.1
>
>
> _______________________________________________
> pve-devel mailing list
> pve-devel at pve.proxmox.com
> https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
>
>
More information about the pve-devel
mailing list