[pve-devel] [PATCH v5 qemu-server 2/3] remote-migration: add restart param

Alexandre Derumier aderumier at odiso.com
Thu Oct 26 10:57:09 CEST 2023


This patch add support for migration without memory transfert.

After the optionnal storage migration, we cleanly shutdown source vm
and restart the target vm. (like a virtual restart between source/dest)

Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 PVE/API2/Qemu.pm   | 19 +++++++++++++++++++
 PVE/CLI/qm.pm      |  5 +++++
 PVE/QemuMigrate.pm | 31 ++++++++++++++++++++++++++++---
 3 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 38bdaab..c0ae516 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -4583,6 +4583,11 @@ __PACKAGE__->register_method({
 		optional => 1,
 		default => 0,
 	    },
+	    'restart' => {
+		type => 'boolean',
+		description => "For online migration, skip memory migration and restart the vm.",
+		optional => 1,
+	    },
 	    'target-storage' => get_standard_option('pve-targetstorage', {
 		completion => \&PVE::QemuServer::complete_migration_storage,
 		optional => 0,
@@ -5729,6 +5734,20 @@ __PACKAGE__->register_method({
 		    PVE::QemuServer::nbd_stop($state->{vmid});
 		    return;
 		},
+		'restart' => sub {
+		    my $nocheck = 1;
+		    my $timeout = 1;
+		    my $shutdown = undef;
+		    my $force = undef;
+		    my $keepactive = 1;
+		    PVE::QemuServer::vm_stop($storecfg, $state->{vmid}, $nocheck, $timeout, undef, undef, $keepactive);
+		    my $info = PVE::QemuServer::vm_start_nolock(
+			$state->{storecfg},
+			$state->{vmid},
+			$state->{conf},
+		    );
+		    return;
+		},
 		'resume' => sub {
 		    if (PVE::QemuServer::Helpers::vm_running_locally($state->{vmid})) {
 			PVE::QemuServer::vm_resume($state->{vmid}, 1, 1);
diff --git a/PVE/CLI/qm.pm b/PVE/CLI/qm.pm
index b17b4fe..12c5291 100755
--- a/PVE/CLI/qm.pm
+++ b/PVE/CLI/qm.pm
@@ -189,6 +189,11 @@ __PACKAGE__->register_method({
 		optional => 1,
 		default => 0,
 	    },
+	    'restart' => {
+		type => 'boolean',
+		description => "For online migration , skip memory migration and restart the vm.",
+		optional => 1,
+	    },
 	    'target-storage' => get_standard_option('pve-targetstorage', {
 		completion => \&PVE::QemuServer::complete_migration_storage,
 		optional => 0,
diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm
index 7dd3455..c801362 100644
--- a/PVE/QemuMigrate.pm
+++ b/PVE/QemuMigrate.pm
@@ -731,6 +731,11 @@ sub cleanup_bitmaps {
 sub live_migration {
     my ($self, $vmid, $migrate_uri, $spice_port) = @_;
 
+    if($self->{opts}->{'restart'}){
+	$self->log('info', "using restart migration - skipping live migration.");
+	return;
+    }
+
     my $conf = $self->{vmconf};
 
     $self->log('info', "starting online/live migration on $migrate_uri");
@@ -1358,7 +1363,14 @@ sub phase2 {
 	# finish block-job with block-job-cancel, to disconnect source VM from NBD
 	# to avoid it trying to re-establish it. We are in blockjob ready state,
 	# thus, this command changes to it to blockjob complete (see qapi docs)
-	eval { PVE::QemuServer::qemu_drive_mirror_monitor($vmid, undef, $self->{storage_migration_jobs}, 'cancel'); };
+	my $finish_cmd = "cancel";
+	if ($self->{opts}->{'restart'}) {
+	    # no live migration.
+	    # finish block-job with block-job-complete, the source will switch to remote NDB
+	    # then we cleanly stop the source vm during phase3
+	    $finish_cmd = "complete";
+	}
+	eval { PVE::QemuServer::qemu_drive_mirror_monitor($vmid, undef, $self->{storage_migration_jobs}, $finish_cmd); };
 	if (my $err = $@) {
 	    die "Failed to complete storage migration: $err\n";
 	}
@@ -1575,7 +1587,17 @@ sub phase3_cleanup {
     };
 
     # always stop local VM with nocheck, since config is moved already
-    eval { PVE::QemuServer::vm_stop($self->{storecfg}, $vmid, 1, 1); };
+    my $shutdown_timeout = undef;
+    my $shutdown = undef;
+    my $force_stop = undef;
+    if ($self->{opts}->{'restart'}) {
+	$shutdown_timeout = 180;
+	$shutdown = 1;
+	$force_stop = 1;
+	$self->log('info', "shutting down source vm");
+    }
+
+    eval { PVE::QemuServer::vm_stop($self->{storecfg}, $vmid, 1, 1, $shutdown_timeout, $shutdown, $force_stop); };
     if (my $err = $@) {
 	$self->log('err', "stopping vm failed - $err");
 	$self->{errors} = 1;
@@ -1609,7 +1631,10 @@ sub phase3_cleanup {
     # clear migrate lock
     if ($tunnel && $tunnel->{version} >= 2) {
 	PVE::Tunnel::write_tunnel($tunnel, 10, "unlock");
-
+	if ($self->{opts}->{'restart'}) {
+	    $self->log('info', "restart target vm");
+	    PVE::Tunnel::write_tunnel($tunnel, 10, 'restart');
+	}
 	PVE::Tunnel::finish_tunnel($tunnel);
     } else {
 	my $cmd = [ @{$self->{rem_ssh}}, 'qm', 'unlock', $vmid ];
-- 
2.39.2





More information about the pve-devel mailing list