From 24bb59b85808b2ff4685a18f62183bfa1762c107 Mon Sep 17 00:00:00 2001 From: Tiago Sousa Date: Fri, 19 Sep 2025 16:36:11 +0100 Subject: [PATCH] underlay functions --- src/PVE/Storage.pm | 13 ++++++ src/PVE/Storage/ISCSIPlugin.pm | 4 +- src/PVE/Storage/LVMPlugin.pm | 75 +++++++++++++++++++++++++++------- src/PVE/Storage/Plugin.pm | 6 +++ 4 files changed, 80 insertions(+), 18 deletions(-) diff --git a/src/PVE/Storage.pm b/src/PVE/Storage.pm index ebbaf45..e3ba44a 100755 --- a/src/PVE/Storage.pm +++ b/src/PVE/Storage.pm @@ -462,6 +462,19 @@ sub volume_size_info { } } +sub volume_underlay_size_info { + my ($cfg, $volid, $timeout) = @_; + + my ($storeid, $volname) = parse_volume_id($volid, 1); + if ($storeid) { + my $scfg = storage_config($cfg, $storeid); + my $plugin = PVE::Storage::Plugin->lookup($scfg->{type}); + return $plugin->volume_underlay_size_info($scfg, $storeid, $volname, $timeout); + } else { + return 0; + } +} + sub volume_resize { my ($cfg, $volid, $size, $running) = @_; diff --git a/src/PVE/Storage/ISCSIPlugin.pm b/src/PVE/Storage/ISCSIPlugin.pm index 33b3d19..30f4178 100644 --- a/src/PVE/Storage/ISCSIPlugin.pm +++ b/src/PVE/Storage/ISCSIPlugin.pm @@ -48,9 +48,7 @@ sub iscsi_session_list { outfunc => sub { my $line = shift; # example: tcp: [1] 192.168.122.252:3260,1 iqn.2003-01.org.linux-iscsi.proxmox-nfs.x8664:sn.00567885ba8f (non-flash) - if ($line =~ - m/^tcp:\s+\[(\S+)\]\s+(\S+:\d+)\,\S+\s+(\S+)\s+\S+?\s*$/ - ) { + if ($line =~ m/^tcp:\s+\[(\S+)\]\s+(\S+:\d+)\,\S+\s+(\S+)\s+\S+?\s*$/) { my ($session_id, $portal, $target) = ($1, $2, $3); # there can be several sessions per target (multipath) push @{ $res->{$target} }, { session_id => $session_id, portal => $portal }; diff --git a/src/PVE/Storage/LVMPlugin.pm b/src/PVE/Storage/LVMPlugin.pm index f2a3890..182ca07 100644 --- a/src/PVE/Storage/LVMPlugin.pm +++ b/src/PVE/Storage/LVMPlugin.pm @@ -575,7 +575,7 @@ sub lvrename { } my sub lvm_qcow2_format { - my ($class, $storeid, $scfg, $name, $fmt, $backing_snap, $size) = @_; + my ($class, $storeid, $scfg, $name, $fmt, $backing_snap, $size, $thin) = @_; $class->activate_volume($storeid, $scfg, $name); my $path = $class->path($scfg, $name, $storeid); @@ -583,11 +583,11 @@ my sub lvm_qcow2_format { my $options = { preallocation => PVE::Storage::Plugin::preallocation_cmd_opt($scfg, $fmt), }; - if ($backing_snap) { + if ($thin) { my $backing_volname = get_snap_name($class, $name, $backing_snap); - my $is_thin = 1; + # TODO: make this variable a check box when taking a snapshot PVE::Storage::Common::qemu_img_create_qcow2_backed( - $path, $backing_volname, $fmt, $options, $is_thin, + $path, $backing_volname, $fmt, $options, $thin, ); } else { PVE::Storage::Common::qemu_img_create($fmt, $size, $path, $options); @@ -649,7 +649,8 @@ my sub alloc_lvm_image { return if $fmt ne 'qcow2'; #format the lvm volume with qcow2 format - eval { lvm_qcow2_format($class, $storeid, $scfg, $name, $fmt, $backing_snap, $size) }; + my $thin = 1; + eval { lvm_qcow2_format($class, $storeid, $scfg, $name, $fmt, $backing_snap, $size, $thin) }; if ($@) { my $err = $@; #no need to safe cleanup as the volume is still empty @@ -936,6 +937,42 @@ sub volume_resize { $lvmsize = "${lvmsize}k"; my $path = $class->path($scfg, $volname); + lv_extend($class, $scfg, $storeid, $lvmsize, $path); + + if (!$running && $format eq 'qcow2') { + my $preallocation = PVE::Storage::Plugin::preallocation_cmd_opt($scfg, $format); + PVE::Storage::Common::qemu_img_resize($path, $format, $size, $preallocation, 10); + } + + return 1; +} + +sub volume_underlay_resize { + my ($class, $scfg, $storeid, $volname) = @_; + + my ($format) = ($class->parse_volname($volname))[6]; + # extend underlay lv + # need to check if next size is going to surpass the qemu img + # if so need to calculate the final size with calculate_lvm_size + # by using qemu_img_info + my $path = $class->filesystem_path($scfg, $volname); + my $json = PVE::Storage::Common::qemu_img_info($path, undef, 10, 0); + my $virtual_size = int($json->{'virtual-size'}); + + my $underlay_size = lv_size($path, 10); + # FIX: 1GiB increment needs to change to a configurable var $scfg->{block_size} + my $updated_underlay_size = $underlay_size + (1024 * 1024 * 1024); + $updated_underlay_size = calculate_lvm_size($virtual_size / 1024, $format, $backing_snap) + if $updated_underlay_size >= $virtual_size; + + my $lvmsize = "${updated_underlay_size}k"; + lv_extend($class,$scfg,$storeid,$lvmsize,$path); + + return 1; +} + +sub lv_extend { + my ($class, $scfg, $storeid, $lvmsize, $path) = @_; my $cmd = ['/sbin/lvextend', '-L', $lvmsize, $path]; $class->cluster_lock_storage( @@ -946,13 +983,6 @@ sub volume_resize { run_command($cmd, errmsg => "error resizing volume '$path'"); }, ); - - if (!$running && $format eq 'qcow2') { - my $preallocation = PVE::Storage::Plugin::preallocation_cmd_opt($scfg, $format); - PVE::Storage::Common::qemu_img_resize($path, $format, $size, $preallocation, 10); - } - - return 1; } sub volume_size_info { @@ -961,8 +991,23 @@ sub volume_size_info { my ($format) = ($class->parse_volname($volname))[6]; my $path = $class->filesystem_path($scfg, $volname); - # TODO: Find a way to make this conditional for thin volumes - # return PVE::Storage::Plugin::file_size_info($path, $timeout, $format) if $format eq 'qcow2'; + return PVE::Storage::Plugin::file_size_info($path, $timeout, $format) if $format eq 'qcow2'; + + my $size = lv_size($path, $timeout); + return wantarray ? ($size, 'raw', 0, undef) : $size; +} + +sub volume_underlay_size_info { + my ($class, $scfg, $storeid, $volname, $timeout) = @_; + + my ($format) = ($class->parse_volname($volname))[6]; + my $path = $class->filesystem_path($scfg, $volname); + + return lv_size($path, $timeout); +} + +sub lv_size { + my ($path, $timeout) = @_; my $cmd = [ '/sbin/lvs', @@ -987,7 +1032,7 @@ sub volume_size_info { $size = int(shift); }, ); - return wantarray ? ($size, 'raw', 0, undef) : $size; + return $size; } sub volume_snapshot { diff --git a/src/PVE/Storage/Plugin.pm b/src/PVE/Storage/Plugin.pm index 2291d72..dc68e56 100644 --- a/src/PVE/Storage/Plugin.pm +++ b/src/PVE/Storage/Plugin.pm @@ -1265,7 +1265,13 @@ sub volume_size_info { my $format = ($class->parse_volname($volname))[6]; my $path = $class->filesystem_path($scfg, $volname); return file_size_info($path, $timeout, $format); +} +sub volume_underlay_size_info { + my ($class, $scfg, $storeid, $volname, $timeout) = @_; + + # Only supported by LVM for now + die "volume underlay is not supported for storage type '$scfg->{type}'\n" } sub volume_resize {