From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id B89781FF13B for ; Wed, 11 Mar 2026 10:46:36 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 03AC613302; Wed, 11 Mar 2026 10:45:49 +0100 (CET) From: Fiona Ebner To: pve-devel@lists.proxmox.com Subject: [PATCH storage v2 09/11] plugin: volume snapshot info: correctly return internal snapshot information Date: Wed, 11 Mar 2026 10:44:48 +0100 Message-ID: <20260311094506.22359-10-f.ebner@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260311094506.22359-1-f.ebner@proxmox.com> References: <20260311094506.22359-1-f.ebner@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1773222275488 X-SPAM-LEVEL: Spam detection results: 0 AWL -1.500 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy 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 URIBL_BLACK 3 Contains an URL listed in the URIBL blacklist [plugin.pm] Message-ID-Hash: AL2GUGH7BIJXVT5TMORZUWS2O6RT5TQD X-Message-ID-Hash: AL2GUGH7BIJXVT5TMORZUWS2O6RT5TQD X-MailFrom: f.ebner@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: If the $follow_backing_files parameter is set for qemu_img_info(), it will always return an array reference. For the implementation in Plugin.pm it will thus be detected as a volume chain even if the 'snapshot-as-volume-chain' storage configuration option is not used. Fix this, by relying on the storage configuration option. Flip the branches to avoid the need to negate the condition. For the implementation in LVMPlugin.pm, do not call qemu-img if the 'snapshot-as-volume-chain' storage configuration option is not used. Signed-off-by: Fiona Ebner --- src/PVE/Storage/LVMPlugin.pm | 4 ++-- src/PVE/Storage/Plugin.pm | 23 ++++++++++++----------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/PVE/Storage/LVMPlugin.pm b/src/PVE/Storage/LVMPlugin.pm index 512c217..f488ead 100644 --- a/src/PVE/Storage/LVMPlugin.pm +++ b/src/PVE/Storage/LVMPlugin.pm @@ -868,6 +868,8 @@ sub status { sub volume_snapshot_info { my ($class, $scfg, $storeid, $volname) = @_; + return {} if !$scfg->{'snapshot-as-volume-chain'}; + my $short_volname = ($class->parse_volname($volname))[1]; my $get_snapname_from_path = sub { @@ -892,9 +894,7 @@ sub volume_snapshot_info { } my $info = {}; my $order = 0; - return $info if ref($json_decode) ne 'ARRAY'; - #no snapshot or external snapshots is an arrayref my $snapshots = $json_decode; for my $snap (@$snapshots) { my $snapfile = $snap->{filename}; diff --git a/src/PVE/Storage/Plugin.pm b/src/PVE/Storage/Plugin.pm index 9dbdef6..b2545ce 100644 --- a/src/PVE/Storage/Plugin.pm +++ b/src/PVE/Storage/Plugin.pm @@ -1903,7 +1903,8 @@ sub volume_snapshot_info { my ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $format) = $class->parse_volname($volname); - my $json = PVE::Storage::Common::qemu_img_info($path, undef, 10, 1); + my $json = + PVE::Storage::Common::qemu_img_info($path, undef, 10, $scfg->{'snapshot-as-volume-chain'}); die "failed to query file information with qemu-img\n" if !$json; my $json_decode = eval { decode_json($json) }; if ($@) { @@ -1911,16 +1912,8 @@ sub volume_snapshot_info { } my $info = {}; my $order = 0; - if (ref($json_decode) eq 'HASH') { - #internal snapshots is a hashref - my $snapshots = $json_decode->{snapshots}; - for my $snap (@$snapshots) { - my $snapname = $snap->{name}; - $info->{$snapname}->{timestamp} = $snap->{'date-sec'}; - - } - } elsif (ref($json_decode) eq 'ARRAY') { - #no snapshot or external snapshots is an arrayref + if ($scfg->{'snapshot-as-volume-chain'}) { + # calling qemu_img_info() with $follow_backing_files gives an array reference my $snapshots = $json_decode; for my $snap (@$snapshots) { my $snapfile = $snap->{filename}; @@ -1947,6 +1940,14 @@ sub volume_snapshot_info { } $order++; } + } else { + # calling qemu_img_info() without $follow_backing_files gives a single hash reference + my $snapshots = $json_decode->{snapshots}; + for my $snap (@$snapshots) { + my $snapname = $snap->{name}; + $info->{$snapname}->{timestamp} = $snap->{'date-sec'}; + + } } return $info; -- 2.47.3