From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 47161921D9 for ; Tue, 21 Mar 2023 08:26:24 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 27AC4CBB0 for ; Tue, 21 Mar 2023 08:25:54 +0100 (CET) Received: from bastionodiso.odiso.net (bastionodiso.odiso.net [185.151.191.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Tue, 21 Mar 2023 08:25:52 +0100 (CET) Received: from kvmformation3.odiso.net (formationkvm3.odiso.net [10.3.94.12]) by bastionodiso.odiso.net (Postfix) with ESMTP id 5BDCA80C3; Tue, 21 Mar 2023 08:25:46 +0100 (CET) Received: by kvmformation3.odiso.net (Postfix, from userid 0) id 42DDF24CC3D; Tue, 21 Mar 2023 08:25:46 +0100 (CET) From: Alexandre Derumier To: pve-devel@lists.proxmox.com Date: Tue, 21 Mar 2023 08:25:44 +0100 Message-Id: <20230321072544.2290454-1-aderumier@odiso.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.063 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% HEADER_FROM_DIFFERENT_DOMAINS 0.25 From and EnvelopeFrom 2nd level mail domains are different KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods NO_DNS_FOR_FROM 0.001 Envelope sender has no MX or A DNS records SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record Subject: [pve-devel] [PATCH qemu-server] remote-migration: add target-cpu param X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 Mar 2023 07:26:24 -0000 This patch add support for remote migration when target cpu model is different. When defined, only the live storage migration is done, but instead to transfert memory, we cleanly shutdown source vm and restart the target vm. --- PVE/API2/Qemu.pm | 18 ++++++++++++++++++ PVE/CLI/qm.pm | 6 ++++++ PVE/QemuMigrate.pm | 20 +++++++++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm index 587bb22..6703c87 100644 --- a/PVE/API2/Qemu.pm +++ b/PVE/API2/Qemu.pm @@ -4460,6 +4460,12 @@ __PACKAGE__->register_method({ optional => 1, default => 0, }, + 'target-cpu' => { + optional => 1, + description => "Target Emulated CPU model. For online migration, the storage is live migrate, but the memory migration is skipped and the target vm is restarted.", + type => 'string', + format => 'pve-vm-cpu-conf', + }, 'target-storage' => get_standard_option('pve-targetstorage', { completion => \&PVE::QemuServer::complete_migration_storage, optional => 0, @@ -4557,11 +4563,14 @@ __PACKAGE__->register_method({ raise_param_exc({ 'target-bridge' => "failed to parse bridge map: $@" }) if $@; + my $target_cpu = extract_param($param, 'target-cpu'); + die "remote migration requires explicit storage mapping!\n" if $storagemap->{identity}; $param->{storagemap} = $storagemap; $param->{bridgemap} = $bridgemap; + $param->{targetcpu} = $target_cpu; $param->{remote} = { conn => $conn_args, # re-use fingerprint for tunnel client => $api_client, @@ -5604,6 +5613,15 @@ __PACKAGE__->register_method({ PVE::QemuServer::nbd_stop($state->{vmid}); return; }, + 'restart' => sub { + PVE::QemuServer::vm_stop(undef, $state->{vmid}, 1, 1); + 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 c3c2982..06c74c1 100755 --- a/PVE/CLI/qm.pm +++ b/PVE/CLI/qm.pm @@ -189,6 +189,12 @@ __PACKAGE__->register_method({ optional => 1, default => 0, }, + 'target-cpu' => { + optional => 1, + description => "Target Emulated CPU model. For online migration, the storage is live migrate, but the memory migration is skipped and the target vm is restarted.", + type => 'string', + format => 'pve-vm-cpu-conf', + }, '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 09cc1d8..0be4fe1 100644 --- a/PVE/QemuMigrate.pm +++ b/PVE/QemuMigrate.pm @@ -782,6 +782,7 @@ sub phase1_remote { my $remote_conf = PVE::QemuConfig->load_config($vmid); PVE::QemuConfig->update_volume_ids($remote_conf, $self->{volume_map}); + $remote_conf->{cpu} = $self->{opts}->{targetcpu}; my $bridges = map_bridges($remote_conf, $self->{opts}->{bridgemap}); for my $target (keys $bridges->%*) { for my $nic (keys $bridges->{$target}->%*) { @@ -1138,6 +1139,11 @@ sub phase2 { } } + if($self->{opts}->{targetcpu}){ + $self->log('info', "target cpu is different - skip live migration."); + return; + } + $self->log('info', "starting online/live migration on $migrate_uri"); $self->{livemigration} = 1; @@ -1566,7 +1572,15 @@ 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; + if ($self->{opts}->{targetcpu}) { + $shutdown_timeout = 180; + $shutdown = 1; + $self->log('info', "target cpu is different - clean shutdown of source vm."); + } + + eval { PVE::QemuServer::vm_stop($self->{storecfg}, $vmid, 1, 1, $shutdown_timeout, $shutdown); }; if (my $err = $@) { $self->log('err', "stopping vm failed - $err"); $self->{errors} = 1; @@ -1600,6 +1614,10 @@ sub phase3_cleanup { # clear migrate lock if ($tunnel && $tunnel->{version} >= 2) { PVE::Tunnel::write_tunnel($tunnel, 10, "unlock"); + if ($self->{opts}->{targetcpu}) { + $self->log('info', "target cpu is different - restart target vm."); + PVE::Tunnel::write_tunnel($tunnel, 10, 'restart'); + } PVE::Tunnel::finish_tunnel($tunnel); } else { -- 2.30.2