From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 5BC061FF13B for ; Wed, 11 Mar 2026 10:46:44 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id DC4F813429; Wed, 11 Mar 2026 10:45:50 +0100 (CET) From: Fiona Ebner To: pve-devel@lists.proxmox.com Subject: [PATCH storage v2 04/11] plugin/storage: volume resize: add snapname parameter Date: Wed, 11 Mar 2026 10:44:43 +0100 Message-ID: <20260311094506.22359-5-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-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1773222275182 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: 5PNSXOA6QM6OMYZEBJVFK62KVONMYT32 X-Message-ID-Hash: 5PNSXOA6QM6OMYZEBJVFK62KVONMYT32 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: For LVM storages using 'snapshot-as-volume-chain', it's necessary to ensure that the size for the LV of the target snapshot volume is large enough before doing a commit operation. Allow resizing a snapshot via the storage (plugin) API to prepare this. Suggested-by: Fabian Grünbichler Signed-off-by: Fiona Ebner --- src/PVE/Storage.pm | 4 ++-- src/PVE/Storage/BTRFSPlugin.pm | 3 ++- src/PVE/Storage/ESXiPlugin.pm | 2 +- src/PVE/Storage/ISCSIDirectPlugin.pm | 2 +- src/PVE/Storage/ISCSIPlugin.pm | 2 +- src/PVE/Storage/LVMPlugin.pm | 5 +++-- src/PVE/Storage/LvmThinPlugin.pm | 8 +++++++- src/PVE/Storage/PBSPlugin.pm | 2 +- src/PVE/Storage/Plugin.pm | 12 ++++++++---- src/PVE/Storage/RBDPlugin.pm | 4 +++- src/PVE/Storage/ZFSPlugin.pm | 5 +++-- src/PVE/Storage/ZFSPoolPlugin.pm | 4 +++- 12 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/PVE/Storage.pm b/src/PVE/Storage.pm index 6e87bac..c45d35b 100755 --- a/src/PVE/Storage.pm +++ b/src/PVE/Storage.pm @@ -393,7 +393,7 @@ sub volume_size_info { } sub volume_resize { - my ($cfg, $volid, $size, $running) = @_; + my ($cfg, $volid, $size, $running, $snapname) = @_; my $padding = (1024 - $size % 1024) % 1024; $size = $size + $padding; @@ -402,7 +402,7 @@ sub volume_resize { if ($storeid) { my $scfg = storage_config($cfg, $storeid); my $plugin = PVE::Storage::Plugin->lookup($scfg->{type}); - return $plugin->volume_resize($scfg, $storeid, $volname, $size, $running); + return $plugin->volume_resize($scfg, $storeid, $volname, $size, $running, $snapname); } elsif ($volid =~ m|^(/.+)$| && -e $volid) { die "resize file/device '$volid' is not possible\n"; } else { diff --git a/src/PVE/Storage/BTRFSPlugin.pm b/src/PVE/Storage/BTRFSPlugin.pm index e68d2bf..fb47aa0 100644 --- a/src/PVE/Storage/BTRFSPlugin.pm +++ b/src/PVE/Storage/BTRFSPlugin.pm @@ -496,10 +496,11 @@ sub volume_size_info { } sub volume_resize { - my ($class, $scfg, $storeid, $volname, $size, $running) = @_; + my ($class, $scfg, $storeid, $volname, $size, $running, $snapname) = @_; my $format = ($class->parse_volname($volname))[6]; if ($format eq 'subvol') { + die "resizing a snapshot is not supported for format 'subvol' in $class\n" if $snapname; # NOTE: `btrfs send/recv` actually drops quota information so supporting subvolumes with # quotas doesn't play nice with send/recv. die "cannot resize subvolume - btrfs quotas are currently not supported\n"; diff --git a/src/PVE/Storage/ESXiPlugin.pm b/src/PVE/Storage/ESXiPlugin.pm index f89e427..19f23bb 100644 --- a/src/PVE/Storage/ESXiPlugin.pm +++ b/src/PVE/Storage/ESXiPlugin.pm @@ -556,7 +556,7 @@ sub volume_import { } sub volume_resize { - my ($class, $scfg, $storeid, $volname, $size, $running) = @_; + my ($class, $scfg, $storeid, $volname, $size, $running, $snapname) = @_; die "resizing volumes is not supported for $class\n"; } diff --git a/src/PVE/Storage/ISCSIDirectPlugin.pm b/src/PVE/Storage/ISCSIDirectPlugin.pm index 62e9026..f976c31 100644 --- a/src/PVE/Storage/ISCSIDirectPlugin.pm +++ b/src/PVE/Storage/ISCSIDirectPlugin.pm @@ -227,7 +227,7 @@ sub volume_size_info { } sub volume_resize { - my ($class, $scfg, $storeid, $volname, $size, $running) = @_; + my ($class, $scfg, $storeid, $volname, $size, $running, $snapname) = @_; die "volume resize is not possible on iscsi device\n"; } diff --git a/src/PVE/Storage/ISCSIPlugin.pm b/src/PVE/Storage/ISCSIPlugin.pm index 30f4178..6472b2f 100644 --- a/src/PVE/Storage/ISCSIPlugin.pm +++ b/src/PVE/Storage/ISCSIPlugin.pm @@ -627,7 +627,7 @@ sub check_connection { } sub volume_resize { - my ($class, $scfg, $storeid, $volname, $size, $running) = @_; + my ($class, $scfg, $storeid, $volname, $size, $running, $snapname) = @_; die "volume resize is not possible on iscsi device"; } diff --git a/src/PVE/Storage/LVMPlugin.pm b/src/PVE/Storage/LVMPlugin.pm index 97c6b0a..e58cd33 100644 --- a/src/PVE/Storage/LVMPlugin.pm +++ b/src/PVE/Storage/LVMPlugin.pm @@ -987,7 +987,7 @@ sub deactivate_volume { } sub volume_resize { - my ($class, $scfg, $storeid, $volname, $size, $running) = @_; + my ($class, $scfg, $storeid, $volname, $size, $running, $snapname) = @_; my ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $format) = $class->parse_volname($volname); @@ -995,7 +995,8 @@ sub volume_resize { my $lvmsize = calculate_lvm_size($size / 1024, $format); $lvmsize = "${lvmsize}k"; - my $path = $class->path($scfg, $volname); + my $path = $class->path($scfg, $volname, $storeid, $snapname); + my $cmd = ['/sbin/lvextend', '-L', $lvmsize, $path]; $class->cluster_lock_storage( diff --git a/src/PVE/Storage/LvmThinPlugin.pm b/src/PVE/Storage/LvmThinPlugin.pm index 256ec43..cadf343 100644 --- a/src/PVE/Storage/LvmThinPlugin.pm +++ b/src/PVE/Storage/LvmThinPlugin.pm @@ -356,7 +356,13 @@ sub create_base { return $newvolname; } -# sub volume_resize {} reuse code from parent class +sub volume_resize { + my ($class, $scfg, $storeid, $volname, $size, $running, $snapname) = @_; + + die "resizing a snapshot is not supported for $class\n" if $snapname; + + return $class->SUPER::volume_resize($scfg, $storeid, $volname, $size, $running, $snapname); +} sub volume_snapshot { my ($class, $scfg, $storeid, $volname, $snap) = @_; diff --git a/src/PVE/Storage/PBSPlugin.pm b/src/PVE/Storage/PBSPlugin.pm index 17e285a..9e5a5ec 100644 --- a/src/PVE/Storage/PBSPlugin.pm +++ b/src/PVE/Storage/PBSPlugin.pm @@ -977,7 +977,7 @@ sub volume_size_info { } sub volume_resize { - my ($class, $scfg, $storeid, $volname, $size, $running) = @_; + my ($class, $scfg, $storeid, $volname, $size, $running, $snapname) = @_; die "volume resize is not possible on pbs device"; } diff --git a/src/PVE/Storage/Plugin.pm b/src/PVE/Storage/Plugin.pm index 9e93bab..042e599 100644 --- a/src/PVE/Storage/Plugin.pm +++ b/src/PVE/Storage/Plugin.pm @@ -1342,14 +1342,15 @@ sub volume_size_info { =head3 volume_resize - $plugin->volume_resize(\%scfg, $storeid, $volname, $size, $running); + $plugin->volume_resize(\%scfg, $storeid, $volname, $size, $running, $snapname); Resize a volume to the new C<$size> in bytes. The size is guaranteed to be a multiple of C<1024>. The implementation may pad to a larger size if required. In case of virtual machines, C<$running> indicates that the VM is currently running and the call will be followed by a C QMP command in QEMU. If resizing is supported natively via QEMU (for example, when using librbd), then the plugin should simply return if the VM is running. For containers, C<$running> will always be -C<0>. +C<0>. If a snapshot name is specified via C<$snapname>, then the snapshot is the target of the +resize operation. Cs in case of errors, or if the underlying storage implementation or the volume's format doesn't support resizing. @@ -1359,13 +1360,16 @@ This function should not return any value. =cut sub volume_resize { - my ($class, $scfg, $storeid, $volname, $size, $running) = @_; + my ($class, $scfg, $storeid, $volname, $size, $running, $snapname) = @_; die "can't resize this image format\n" if $volname !~ m/\.(raw|qcow2)$/; return 1 if $running; - my $path = $class->filesystem_path($scfg, $volname); + die "resizing a snapshot is not supported for $class without 'snapshot-as-volume-chain'\n" + if !$scfg->{'snapshot-as-volume-chain'} && $snapname; + + my $path = $class->filesystem_path($scfg, $volname, $snapname); my $format = ($class->parse_volname($volname))[6]; diff --git a/src/PVE/Storage/RBDPlugin.pm b/src/PVE/Storage/RBDPlugin.pm index 7d3e7ab..b537425 100644 --- a/src/PVE/Storage/RBDPlugin.pm +++ b/src/PVE/Storage/RBDPlugin.pm @@ -895,7 +895,9 @@ sub volume_size_info { } sub volume_resize { - my ($class, $scfg, $storeid, $volname, $size, $running) = @_; + my ($class, $scfg, $storeid, $volname, $size, $running, $snapname) = @_; + + die "resizing a snapshot is not supported for $class\n" if $snapname; return 1 if $running && !$scfg->{krbd}; # FIXME??? diff --git a/src/PVE/Storage/ZFSPlugin.pm b/src/PVE/Storage/ZFSPlugin.pm index 99d8c8f..74e0a08 100644 --- a/src/PVE/Storage/ZFSPlugin.pm +++ b/src/PVE/Storage/ZFSPlugin.pm @@ -392,11 +392,12 @@ sub free_image { } sub volume_resize { - my ($class, $scfg, $storeid, $volname, $size, $running) = @_; + my ($class, $scfg, $storeid, $volname, $size, $running, $snapname) = @_; $volname = ($class->parse_volname($volname))[1]; - my $new_size = $class->SUPER::volume_resize($scfg, $storeid, $volname, $size, $running); + my $new_size = + $class->SUPER::volume_resize($scfg, $storeid, $volname, $size, $running, $snapname); $class->zfs_resize_lu($scfg, $volname, $new_size); diff --git a/src/PVE/Storage/ZFSPoolPlugin.pm b/src/PVE/Storage/ZFSPoolPlugin.pm index 3b3456b..8319344 100644 --- a/src/PVE/Storage/ZFSPoolPlugin.pm +++ b/src/PVE/Storage/ZFSPoolPlugin.pm @@ -742,7 +742,9 @@ sub create_base { } sub volume_resize { - my ($class, $scfg, $storeid, $volname, $size, $running) = @_; + my ($class, $scfg, $storeid, $volname, $size, $running, $snapname) = @_; + + die "resizing a snapshot is not supported for $class\n" if $snapname; my $new_size = int($size / 1024); -- 2.47.3