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 067E081115 for ; Mon, 22 Nov 2021 11:30:53 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id EC6F11BF36 for ; Mon, 22 Nov 2021 11:30:22 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (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 firstgate.proxmox.com (Proxmox) with ESMTPS id A54401BF2B for ; Mon, 22 Nov 2021 11:30:21 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 7882C44074 for ; Mon, 22 Nov 2021 11:30:21 +0100 (CET) From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= To: pve-devel@lists.proxmox.com Date: Mon, 22 Nov 2021 11:30:11 +0100 Message-Id: <20211122103011.2374843-2-f.gruenbichler@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211122103011.2374843-1-f.gruenbichler@proxmox.com> References: <20211122103011.2374843-1-f.gruenbichler@proxmox.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.256 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH qemu-server 2/2] migrate: send updated tpmstate volid to target node 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: Mon, 22 Nov 2021 10:30:53 -0000 and update the in-memory config for starting the target VM accordingly. this possibly breaks migration new -> old iff - spice is not used (else the explicit ticket wins because it comes later) - a local TPM state volume is used - that local TPM state volume has a different volume id on the target node (switched storage, volname already taken, ..) because the target node will then mis-interpret the tpmstate0 line as spice ticket and set it accordingly. if the old tpm state volume ID does not exist on the target node, migration will fail. if it exists by chance, it might work albeit with a wrong spice ticket (new because of this patch) and tpm state volume (pre-existing breakage). Signed-off-by: Fabian Grünbichler --- Notes: https://forum.proxmox.com/threads/error-live-migrate-a-windows-vm-with-tpm.99906/#post-431345 IMHO this is okay since new->old is always best effort and might fail for $reasons. we could extend this to check the broadcasted version on the source node once pve-manager requires a new enough qemu-server, and die early there to avoid running into the compat issue.. the original compat logic was unfortunate - an "old" source node would only ever send an unprefixed spice ticket as first line on STDIN, if the compat logic had included a check for that this would be a bit easier.. PVE/API2/Qemu.pm | 4 ++++ PVE/QemuMigrate.pm | 8 ++++++++ PVE/QemuServer.pm | 10 +++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm index 8b834bb..6992f6f 100644 --- a/PVE/API2/Qemu.pm +++ b/PVE/API2/Qemu.pm @@ -2319,6 +2319,7 @@ __PACKAGE__->register_method({ my $spice_ticket; my $nbd_protocol_version = 0; my $replicated_volumes = {}; + my $tpmstate_vol; if ($stateuri && ($stateuri eq 'tcp' || $stateuri eq 'unix') && $migratedfrom && ($rpcenv->{type} eq 'cli')) { while (defined(my $line = )) { chomp $line; @@ -2328,6 +2329,8 @@ __PACKAGE__->register_method({ $nbd_protocol_version = $1; } elsif ($line =~ m/^replicated_volume: (.*)$/) { $replicated_volumes->{$1} = 1; + } elsif ($line =~ m/^tpmstate0: (.*)$/) { + $tpmstate_vol = $1; } elsif (!$spice_ticket) { # fallback for old source node $spice_ticket = $line; @@ -2369,6 +2372,7 @@ __PACKAGE__->register_method({ storagemap => $storagemap, nbd_proto_version => $nbd_protocol_version, replicated_volumes => $replicated_volumes, + tpmstate_vol => $tpmstate_vol, }; my $params = { diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm index ae3eaf1..c9bc39d 100644 --- a/PVE/QemuMigrate.pm +++ b/PVE/QemuMigrate.pm @@ -870,6 +870,14 @@ sub phase2 { # version > 0 for unix socket support my $nbd_protocol_version = 1; my $input = "nbd_protocol_version: $nbd_protocol_version\n"; + + if ($conf->{tpmstate0}) { + my $tpmdrive = PVE::QemuServer::parse_drive('tpmstate0', $conf->{tpmstate0}); + my $tpmvol = $tpmdrive->{file}; + $input .= "tpmstate0: $self->{volume_map}->{$tpmvol}" + if $self->{volume_map}->{$tpmvol} && $tpmvol ne $self->{volume_map}->{$tpmvol}; + } + $input .= "spice_ticket: $spice_ticket\n" if $spice_ticket; my @online_replicated_volumes = $self->filter_local_volumes('online', 1); diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index 76d45a2..45b704d 100644 --- a/PVE/QemuServer.pm +++ b/PVE/QemuServer.pm @@ -5370,7 +5370,8 @@ sub vm_start { # network => CIDR of migration network # type => secure/insecure - tunnel over encrypted connection or plain-text # nbd_proto_version => int, 0 for TCP, 1 for UNIX -# replicated_volumes = which volids should be re-used with bitmaps for nbd migration +# replicated_volumes => which volids should be re-used with bitmaps for nbd migration +# tpmstate_vol => new volid of tpmstate0, not yet contained in config sub vm_start_nolock { my ($storecfg, $vmid, $conf, $params, $migrate_opts) = @_; @@ -5395,6 +5396,13 @@ sub vm_start_nolock { # this way we can reuse the old ISO with the correct config PVE::QemuServer::Cloudinit::generate_cloudinitconfig($conf, $vmid) if !$migratedfrom; + # override TPM state vol if migrated, conf is out of date still + if (my $tpmvol = $migrate_opts->{tpmstate_vol}) { + my $parsed = parse_drive("tpmstate0", $conf->{tpmstate0}); + $parsed->{file} = $tpmvol; + $conf->{tpmstate0} = print_drive($parsed); + } + my $defaults = load_defaults(); # set environment variable useful inside network script -- 2.30.2