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 <[email protected]>
Signed-off-by: Fiona Ebner <[email protected]>
---
 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 aa472f5..a134334 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 2797d9e..1463335 100644
--- a/src/PVE/Storage/LvmThinPlugin.pm
+++ b/src/PVE/Storage/LvmThinPlugin.pm
@@ -355,7 +355,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 b0d3bbf..221c872 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<block_resize> 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.
 
 C<die>s 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



_______________________________________________
pve-devel mailing list
[email protected]
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to