From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id DAB601FF0DF for ; Thu, 05 Nov 2026 17:36:47 +0100 (CET) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id CFBE92156F; Thu, 05 Nov 2026 17:36:43 +0100 (CET) From: =?UTF-8?q?Michael=20K=C3=B6ppl?= To: pve-devel@lists.proxmox.com Subject: [PATCH storage 3/3] lvm plugin: do not hold inherited locks in cleanup workers Date: Thu, 5 Nov 2026 17:36:37 +0100 Message-ID: <20261105163637.1318072-4-m.koeppl@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20261105163637.1318072-1-m.koeppl@proxmox.com> References: <20261105163637.1318072-1-m.koeppl@proxmox.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1793896598616 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.212 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: WKSIAVS46QMG5H6N5AKZTMDC7PIGZZIM X-Message-ID-Hash: WKSIAVS46QMG5H6N5AKZTMDC7PIGZZIM X-MailFrom: m.koeppl@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: The LVM plugin forks its own cleanup workers when rolling back or deleting snapshots of qcow2 volumes and after failed imports. Like the worker forked by vdisk_free(), they inherit the locks of their caller and keep them held until the cleanup is done. This can happen, e.g., when restoring a backup over an existing VM with a qcow2 snapshot on LVM and a disk excluded from the backup, which deletes that disk's snapshot while holding the config lock. After the restore has finished, changing or starting the VM then fails with a lock timeout until the cleanup is done. Close the inherited lock handles at the start of these workers too. Since the cleanup worker of a rollback no longer holds the guest migration lock, another rollback of the same volume can start while the previous volume is still being wiped. Renaming the current volume to del- then fails, but only after the guest was already locked for the rollback, leaving it locked. Check in volume_rollback_is_possible() that del- does not exist, so such a rollback is refused before the guest is locked. Signed-off-by: Michael Köppl --- src/PVE/Storage/LVMPlugin.pm | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/PVE/Storage/LVMPlugin.pm b/src/PVE/Storage/LVMPlugin.pm index a6a5eb70..f9e6936f 100644 --- a/src/PVE/Storage/LVMPlugin.pm +++ b/src/PVE/Storage/LVMPlugin.pm @@ -50,7 +50,15 @@ my sub fork_cleanup_worker { return if !$cleanup_worker; my $rpcenv = PVE::RPCEnvironment::get(); my $authuser = $rpcenv->get_user(); - $rpcenv->fork_worker('imgdel', undef, $authuser, $cleanup_worker); + $rpcenv->fork_worker( + 'imgdel', + undef, + $authuser, + sub { + PVE::Tools::close_inherited_lock_handles(); + $cleanup_worker->(@_); + }, + ); } sub lvm_pv_info { @@ -1645,6 +1653,12 @@ sub volume_rollback_is_possible { die "can't rollback, '$snap' is not most recent snapshot on '$volname'\n" if scalar($blockers->@*) > 0; + my $vg = $scfg->{vgname}; + my $name = ($class->parse_volname($volname))[1]; + my $lvs = lvm_list_volumes($vg); + die "can't rollback, previous volume '$vg/del-$name' is still being removed\n" + if $lvs->{$vg}->{"del-$name"}; + return 1; } -- 2.47.3