public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [PATCH manager] fix #7178: pve8to9: detect qcow2 TPM state volumes containing raw data
@ 2026-10-04 17:05 Michal Fox
  0 siblings, 0 replies; only message in thread
From: Michal Fox @ 2026-10-04 17:05 UTC (permalink / raw)
  To: pve-devel

Before qemu-server 8.3.3, cloning a VM template with a raw TPM state on
a directory storage as linked clone created a qcow2 overlay for it.
swtpm_setup used that file as raw TPM state and, as it found no valid
state in it, overwrote it with a new one, turning it into a raw file
with a qcow2 name.

With Proxmox VE 9, the TPM state is attached with the format of the
volume name, so such a VM fails to start with 'Image is not in qcow2
format'. Since qemu-server 8.3.3, it also fails to start on Proxmox VE
8, as swtpm only accepts raw volumes there, but the VM might not have
been started since then.

Check the TPM state volumes of all VMs that are named as qcow2 and on
a file based storage for the qcow2 magic, and warn about those that do
not have it, with how to fix them, as described in the bug report.

Signed-off-by: Michal Fox <me@dualfroz.com>
---
Tested the new check with mocked VM configs and storage config, on a
directory storage with a linked clone TPM state overwritten with raw
data (which 'qemu-img info' reports as raw), a real qcow2 and a raw TPM
state, one on LVM, one with a missing file and one on a storage that
does not exist: only the first one is reported, the last two are
skipped with the error. With the detection disabled or always true, the
test fails.

This is for master, it also applies to stable-8 with a 3-way merge, as
only the context of the 'use' lines differs there.

 PVE/CLI/pve8to9.pm | 48 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/PVE/CLI/pve8to9.pm b/PVE/CLI/pve8to9.pm
index 7305a7b6..b147f56e 100644
--- a/PVE/CLI/pve8to9.pm
+++ b/PVE/CLI/pve8to9.pm
@@ -27,6 +27,7 @@ use PVE::Storage::Plugin;
 use PVE::Tools qw(run_command split_list file_get_contents trim);
 use PVE::QemuConfig;
 use PVE::QemuServer;
+use PVE::QemuServer::Drive;
 use PVE::QemuServer::Machine;
 use PVE::QemuServer::Network;
 use PVE::VZDump::Common;
@@ -1076,6 +1077,51 @@ my sub check_qemu_machine_versions {
     }
 }
 
+sub check_qemu_tpmstate_volumes {
+    log_info("Checking VM TPM state volumes for qcow2 files containing raw data..");
+
+    my $storecfg = PVE::Storage::config();
+    my $affected = [];
+
+    my $vms = PVE::QemuServer::config_list();
+    for my $vmid (sort { $a <=> $b } keys $vms->%*) {
+        my $conf = PVE::QemuConfig->load_config($vmid);
+        next if !$conf->{tpmstate0};
+
+        my $volid = PVE::QemuServer::Drive::parse_drive('tpmstate0', $conf->{tpmstate0})->{file};
+        eval {
+            my ($storeid) = PVE::Storage::parse_volume_id($volid);
+            my $format = (PVE::Storage::parse_volname($storecfg, $volid))[6];
+            my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
+            # only volumes on file based storages could end up like this
+            return if $format ne 'qcow2' || !$scfg->{path};
+
+            my $path = PVE::Storage::path($storecfg, $volid);
+            open(my $fh, '<', $path) or die "unable to open '$path' - $!\n";
+            my $magic = '';
+            read($fh, $magic, 4);
+            close($fh);
+
+            # before qemu-server 8.3.3, swtpm_setup used the qcow2 overlay of linked clones as raw
+            # file and overwrote it with a new state
+            push $affected->@*, "VM $vmid: $volid" if $magic ne "QFI\xfb";
+        };
+        log_skip("could not check TPM state volume '$volid' of VM $vmid - $@") if $@;
+    }
+
+    if (!scalar($affected->@*)) {
+        log_pass("No qcow2 TPM state volumes with raw data found.");
+        return;
+    }
+
+    log_warn(
+        "The TPM state volumes of the following VMs are qcow2 files that contain raw data, which"
+            . " happened with linked clones. Such a VM fails to start in Proxmox VE 9. Rename the"
+            . " file to end with '.raw' and adapt the 'tpmstate0' line of the VM config accordingly,"
+            . " also dropping the base volume, like '101/base-101-disk-2.raw/':\n\t"
+            . join("\n\t", $affected->@*));
+}
+
 my sub check_max_length {
     my ($raw, $max_length, $warning) = @_;
     log_warn($warning) if defined($raw) && length($raw) > $max_length;
@@ -2098,6 +2144,8 @@ sub check_virtual_guests {
     }
 
     check_qemu_machine_versions();
+
+    check_qemu_tpmstate_volumes();
 }
 
 my $LEGACY_IPAM_DB = "/etc/pve/priv/ipam.db";
-- 
2.43.0




^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-10-04 17:05 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-04 17:05 [PATCH manager] fix #7178: pve8to9: detect qcow2 TPM state volumes containing raw data Michal Fox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal