public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Fiona Ebner <f.ebner@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH qemu-server 18/18] fix #7066: api: allow live snapshot (remove) of qcow2 TPM drive with snapshot-as-volume-chain
Date: Wed,  3 Dec 2025 14:26:44 +0100	[thread overview]
Message-ID: <20251203132949.109685-19-f.ebner@proxmox.com> (raw)
In-Reply-To: <20251203132949.109685-1-f.ebner@proxmox.com>

Commit "snapshot: support live snapshot (remove) of qcow2 TPM drive on
storage with snapshot-as-volume-chain" prepared for this. It's not a
revert of commit c7d839df ("snapshot: prohibit live snapshot (remove)
of qcow2 TPM drive on storage with snapshot-as-volume-chain"), because
there is a single limitation remaining. That limitation is removing
the top-most snapshot live when the current image is exported via
FUSE, because exporting unshares the 'resize' permission, which would
be required by both 'block-commit' and 'block-stream', for example:

> QEMU storage daemon 100 qsd command 'block-commit' failed - Permission
> conflict on node '#block017': permissions 'resize' are both required
> by node 'drive-tpmstate0' (uses node '#block017' as 'file' child) and
> unshared by commit job 'commit-drive-tpmstate0' (uses node '#block017'
> as 'main node' child).

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
 src/PVE/API2/Qemu.pm | 39 ++++++++++++++-------------------------
 1 file changed, 14 insertions(+), 25 deletions(-)

diff --git a/src/PVE/API2/Qemu.pm b/src/PVE/API2/Qemu.pm
index 5a627936..859afce9 100644
--- a/src/PVE/API2/Qemu.pm
+++ b/src/PVE/API2/Qemu.pm
@@ -726,11 +726,11 @@ my $check_cpu_model_access = sub {
     }
 };
 
-# TODO switch to doing internal snapshots only for TPM? Need a way to tell the storage. Also needs
-# handling for pre-existing as-volume-chain snapshots then. Or is there a way to make QSD+swtpm
-# compatible with using volume-chain live?
-my sub assert_tpm_snapshot_compat {
-    my ($vmid, $conf, $op, $snap_conf) = @_;
+# The top-most snapshot for a FUSE-exported TPM state cannot be removed live, because exporting
+# unshares the 'resize' permission, which would be required by both 'block-commit' and
+# 'block-stream'.
+my sub assert_tpm_snapshot_delete_possible {
+    my ($vmid, $conf, $snap_conf, $snap_name) = @_;
 
     return if !$conf->{tpmstate0};
     return if !PVE::QemuServer::Helpers::vm_running_locally($vmid);
@@ -739,19 +739,19 @@ my sub assert_tpm_snapshot_compat {
     my $volid = $drive->{file};
     my $storecfg = PVE::Storage::config();
 
-    if ($snap_conf) {
-        return if !$snap_conf->{tpmstate0};
-        my $snap_drive = PVE::QemuServer::Drive::parse_drive('tpmstate0', $snap_conf->{tpmstate0});
-        return if $volid ne $snap_drive->{file};
-    }
+    return if $conf->{parent} ne $snap_name; # allowed if not top-most snapshot
+
+    return if !$snap_conf->{tpmstate0};
+    my $snap_drive = PVE::QemuServer::Drive::parse_drive('tpmstate0', $snap_conf->{tpmstate0});
+    return if $volid ne $snap_drive->{file};
 
     my $format = PVE::QemuServer::Drive::checked_volume_format($storecfg, $volid);
     my ($storeid) = PVE::Storage::parse_volume_id($volid, 1);
     if ($storeid && $format eq 'qcow2') {
         my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
         if ($scfg && $scfg->{'snapshot-as-volume-chain'}) {
-            die "snapshot $op of TPM state '$volid' on storage with 'snapshot-as-volume-chain' is"
-                . " not yet supported while the VM is running.\n";
+            die "top-most snapshot of TPM state '$volid' on storage with 'snapshot-as-volume-chain'"
+                . " cannot be removed while the VM is running.\n";
         }
     }
 }
@@ -6074,14 +6074,6 @@ __PACKAGE__->register_method({
             0);
 
         my $realcmd = sub {
-            PVE::QemuConfig->lock_config(
-                $vmid,
-                sub {
-                    my $conf = PVE::QemuConfig->load_config($vmid);
-                    assert_tpm_snapshot_compat($vmid, $conf, 'create');
-                },
-            );
-
             PVE::Cluster::log_msg('info', $authuser, "snapshot VM $vmid: $snapname");
             PVE::QemuConfig->snapshot_create(
                 $vmid, $snapname, $param->{vmstate}, $param->{description},
@@ -6338,11 +6330,8 @@ __PACKAGE__->register_method({
                 $vmid,
                 sub {
                     my $conf = PVE::QemuConfig->load_config($vmid);
-                    assert_tpm_snapshot_compat(
-                        $vmid,
-                        $conf,
-                        'delete',
-                        $conf->{snapshots}->{$snapname},
+                    assert_tpm_snapshot_delete_possible(
+                        $vmid, $conf, $conf->{snapshots}->{$snapname}, $snapname,
                     );
                 },
             );
-- 
2.47.3



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


      parent reply	other threads:[~2025-12-03 13:31 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-03 13:26 [pve-devel] [PATCH-SERIES qemu-server 00/18] " Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 01/18] block job: fix variable name in documentation Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 02/18] qmp client: add default timeouts for more block commands Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 03/18] drive: introduce drive_uses_qsd_fuse() helper Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 04/18] monitor: add vm_qmp_peer() helper Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 05/18] monitor: add qsd_peer() helper Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 06/18] blockdev: rename variable in get_node_name_below_throttle() for readability Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 07/18] blockdev: switch get_node_name_below_throttle() to use QMP peer Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 08/18] blockdev: switch detach() " Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 09/18] blockdev: switch blockdev_replace() " Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 10/18] blockdev: switch blockdev_external_snapshot() " Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 11/18] block job: switch qemu_handle_concluded_blockjob() " Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 12/18] block job: switch qemu_blockjobs_cancel() " Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 13/18] block job: switch qemu_drive_mirror_monitor() " Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 14/18] blockdev: switch blockdev_delete() " Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 15/18] blockdev: switch blockdev_stream() " Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 16/18] blockdev: switch blockdev_commit() " Fiona Ebner
2025-12-03 13:26 ` [pve-devel] [PATCH qemu-server 17/18] snapshot: support live snapshot (remove) of qcow2 TPM drive on storage with snapshot-as-volume-chain Fiona Ebner
2025-12-03 13:26 ` Fiona Ebner [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251203132949.109685-19-f.ebner@proxmox.com \
    --to=f.ebner@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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