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 54F7C1FF15C for ; Fri, 17 Oct 2025 13:35:32 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 8326332E; Fri, 17 Oct 2025 13:35:37 +0200 (CEST) To: pve-devel@lists.proxmox.com Date: Fri, 17 Oct 2025 12:25:29 +0100 In-Reply-To: <20251017112539.26471-1-joao.sousa@eurotux.com> References: <20251017112539.26471-1-joao.sousa@eurotux.com> MIME-Version: 1.0 Message-ID: List-Id: Proxmox VE development discussion List-Post: From: Tiago Sousa via pve-devel Precedence: list Cc: Tiago Sousa X-Mailman-Version: 2.1.29 X-BeenThere: pve-devel@lists.proxmox.com List-Subscribe: , List-Unsubscribe: , List-Archive: Reply-To: Proxmox VE development discussion List-Help: Subject: [pve-devel] [PATCH pve-storage 4/4] plugin: lvmplugin: add underlay functions Content-Type: multipart/mixed; boundary="===============0599974861473103542==" Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" --===============0599974861473103542== Content-Type: message/rfc822 Content-Disposition: inline Return-Path: X-Original-To: pve-devel@lists.proxmox.com Delivered-To: pve-devel@lists.proxmox.com Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id D9608D0F6B for ; Fri, 17 Oct 2025 13:35:34 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id AD42127CCA for ; Fri, 17 Oct 2025 13:35:04 +0200 (CEST) Received: from eurotux.com (mail.eurotux.com [185.98.249.9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Fri, 17 Oct 2025 13:35:03 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by eurotux.com (Postfix) with ESMTP id B465230CFB15; Fri, 17 Oct 2025 12:26:02 +0100 (WEST) Authentication-Results: mail.prd.eurotux.pt (amavisd-new); dkim=pass (2048-bit key) reason="pass (just generated, assumed good)" header.d=eurotux.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=eurotux.com; h= content-transfer-encoding:mime-version:references:in-reply-to :x-mailer:message-id:date:date:subject:subject:from:from; s= default; t=1760700361; x=1762514762; bh=otmrPFPSl3N5QRrGmpvigjR/ Fehkg7rDqRwGEsfkdHM=; b=s+Jc2QL2iWgFTApAYy5qLkAoeIxwzVFH0LOLLrp6 VJVzMdQ59/udQEuTW7zseg7Uvfp5lZm8y1UjvyKe8V4yppr6WI9mLTDTvw76dg/f hvqudjUaVn4z0D9LrgF/LQu5Ilevhdd3LwijLyzh9xG/y0K+0akpmsCfK8tdbVXb y7kayAcaq13T4CLDWCdW5uDZGCA1gJT6l50ocD3A7pyMIWjNqJyMWU8HCI5WmyqQ J7UEhRbw87xzSOQYQPXdj2K1VNfxosVQQBZvM8QacnJmuUSPRTOzkOXlt/VUW09t D9BZv2MusBap8SHH/y1uoxEOwv8+NXCVPOHNfaWP3/dQdw== X-Virus-Scanned: amavisd-new at mail.prd.eurotux.pt Received: from eurotux.com ([127.0.0.1]) by localhost (mail.prd.eurotux.pt [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id lvF5zqTpivZ7; Fri, 17 Oct 2025 12:26:01 +0100 (WEST) Received: from proxmox.example (184.137.90.149.rev.vodafone.pt [149.90.137.184]) (Authenticated sender: joao.sousa@eurotux.com) by eurotux.com (Postfix) with ESMTPSA id A374A30CFB19; Fri, 17 Oct 2025 12:26:01 +0100 (WEST) From: Tiago Sousa To: pve-devel@lists.proxmox.com Subject: [PATCH pve-storage 4/4] plugin: lvmplugin: add underlay functions Date: Fri, 17 Oct 2025 12:25:29 +0100 Message-ID: <20251017112539.26471-5-joao.sousa@eurotux.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251017112539.26471-1-joao.sousa@eurotux.com> References: <20251017112539.26471-1-joao.sousa@eurotux.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SPAM-LEVEL: Spam detection results: 0 AWL -0.001 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain DKIM_VALID_EF -0.1 Message has a valid DKIM or DK signature from envelope-from domain DMARC_PASS -0.1 DMARC pass policy RCVD_IN_MSPIKE_H2 0.001 Average reputation (+2) SPF_HELO_PASS -0.001 SPF: HELO matches SPF record SPF_PASS -0.001 SPF: sender matches SPF record Signed-off-by: Tiago Sousa --- src/PVE/Storage.pm | 28 ++++++++++++++++ src/PVE/Storage/LVMPlugin.pm | 65 +++++++++++++++++++++++++++++++----- src/PVE/Storage/Plugin.pm | 29 +++++++++++++++- 3 files changed, 113 insertions(+), 9 deletions(-) diff --git a/src/PVE/Storage.pm b/src/PVE/Storage.pm index ebbaf45..e0b4ba8 100755 --- a/src/PVE/Storage.pm +++ b/src/PVE/Storage.pm @@ -480,6 +480,34 @@ sub volume_resize { } } =20 +sub volume_underlay_size_info { + my ($cfg, $volid, $timeout) =3D @_; + + my ($storeid, $volname) =3D parse_volume_id($volid, 1); + if ($storeid) { + my $scfg =3D storage_config($cfg, $storeid); + my $plugin =3D PVE::Storage::Plugin->lookup($scfg->{type}); + return $plugin->volume_underlay_size_info($scfg, $storeid, $voln= ame, $timeout); + } else { + return 0; + } +} + +sub volume_underlay_resize { + my ($cfg, $volid, $size, $running, $backing_snap) =3D @_; + + my ($storeid, $volname) =3D parse_volume_id($volid, 1); + if ($storeid) { + my $scfg =3D storage_config($cfg, $storeid); + my $plugin =3D PVE::Storage::Plugin->lookup($scfg->{type}); + return $plugin->volume_underlay_resize($scfg, $storeid, $volname= , $size, $running, $backing_snap); + } elsif ($volid =3D~ m|^(/.+)$| && -e $volid) { + die "resize file/device '$volid' is not possible\n"; + } else { + die "unable to parse volume ID '$volid'\n"; + } +} + sub volume_rollback_is_possible { my ($cfg, $volid, $snap, $blockers) =3D @_; =20 diff --git a/src/PVE/Storage/LVMPlugin.pm b/src/PVE/Storage/LVMPlugin.pm index dc5e648..74366c3 100644 --- a/src/PVE/Storage/LVMPlugin.pm +++ b/src/PVE/Storage/LVMPlugin.pm @@ -400,6 +400,8 @@ sub options { tagged_only =3D> { optional =3D> 1 }, bwlimit =3D> { optional =3D> 1 }, 'snapshot-as-volume-chain' =3D> { optional =3D> 1 }, + chunksize =3D> { optional =3D> 1 }, + 'chunk-percentage' =3D> { optional =3D> 1 }, }; } =20 @@ -939,6 +941,44 @@ sub volume_resize { $lvmsize =3D "${lvmsize}k"; =20 my $path =3D $class->path($scfg, $volname); + lv_extend($class, $scfg, $storeid, $lvmsize, $path); + + if (!$running && $format eq 'qcow2') { + my $preallocation =3D PVE::Storage::Plugin::preallocation_cmd_op= t($scfg, $format); + PVE::Storage::Common::qemu_img_resize($path, $format, $size, $pr= eallocation, 10); + } + + return 1; +} + +sub volume_underlay_resize { + my ($class, $scfg, $storeid, $volname, $backing_snap) =3D @_; + + my ($format) =3D ($class->parse_volname($volname))[6]; + + my $path =3D $class->filesystem_path($scfg, $volname); + my $json =3D PVE::Storage::Common::qemu_img_info($path, undef, 10, 0= ); + my $json_decode =3D eval { decode_json($json) }; + if ($@) { + die "Can't decode qemu snapshot list. Invalid JSON: $@\n"; + } + + my $virtual_size =3D $json_decode->{'virtual-size'} / 1024; + + my $underlay_size =3D lv_size($path, 10); + + my $updated_underlay_size =3D ($underlay_size + $scfg->{chunksize}) = / 1024; + $updated_underlay_size =3D calculate_lvm_size($virtual_size, $format= , $backing_snap) + if $updated_underlay_size >=3D $virtual_size; + + my $lvmsize =3D "${updated_underlay_size}k"; + lv_extend($class, $scfg, $storeid, $lvmsize, $path); + + return $updated_underlay_size; +} + +sub lv_extend { + my ($class, $scfg, $storeid, $lvmsize, $path) =3D @_; my $cmd =3D ['/sbin/lvextend', '-L', $lvmsize, $path]; =20 $class->cluster_lock_storage( @@ -949,13 +989,6 @@ sub volume_resize { run_command($cmd, errmsg =3D> "error resizing volume '$path'= "); }, ); - - if (!$running && $format eq 'qcow2') { - my $preallocation =3D PVE::Storage::Plugin::preallocation_cmd_op= t($scfg, $format); - PVE::Storage::Common::qemu_img_resize($path, $format, $size, $pr= eallocation, 10); - } - - return 1; } =20 sub volume_size_info { @@ -966,6 +999,22 @@ sub volume_size_info { =20 return PVE::Storage::Plugin::file_size_info($path, $timeout, $format= ) if $format eq 'qcow2'; =20 + my $size =3D lv_size($path, $timeout); + return wantarray ? ($size, 'raw', 0, undef) : $size; +} + +sub volume_underlay_size_info { + my ($class, $scfg, $storeid, $volname, $timeout) =3D @_; + + my ($format) =3D ($class->parse_volname($volname))[6]; + my $path =3D $class->filesystem_path($scfg, $volname); + + return lv_size($path, $timeout); +} + +sub lv_size { + my ($path, $timeout) =3D @_; + my $cmd =3D [ '/sbin/lvs', '--separator', @@ -989,7 +1038,7 @@ sub volume_size_info { $size =3D int(shift); }, ); - return wantarray ? ($size, 'raw', 0, undef) : $size; + return $size; } =20 sub volume_snapshot { diff --git a/src/PVE/Storage/Plugin.pm b/src/PVE/Storage/Plugin.pm index 8acd214..f08393b 100644 --- a/src/PVE/Storage/Plugin.pm +++ b/src/PVE/Storage/Plugin.pm @@ -228,6 +228,20 @@ my $defaultData =3D { default =3D> 0, optional =3D> 1, }, + chunksize =3D> { + type =3D> 'integer', + description =3D> 'The chunksize in Bytes to define the write= threshold' + . 'of thin disks on thick storage.', + default =3D> 1073741824, # 1 GiB + optional =3D> 1, + }, + 'chunk-percentage' =3D> { + type =3D> 'number', + description =3D> 'The percentage of written disk to define t= he write' + . 'threshold.', + default =3D> 0.5, + optional =3D> 1, + }, }, }; =20 @@ -1265,7 +1279,6 @@ sub volume_size_info { my $format =3D ($class->parse_volname($volname))[6]; my $path =3D $class->filesystem_path($scfg, $volname); return file_size_info($path, $timeout, $format); - } =20 sub volume_resize { @@ -1285,6 +1298,20 @@ sub volume_resize { return undef; } =20 +sub volume_underlay_size_info { + my ($class, $scfg, $storeid, $volname, $timeout) =3D @_; + + # Only supported by LVM for now + die "volume underlay is not supported for storage type '$scfg->{type= }'\n"; +} + +sub volume_underlay_resize { + my ($class, $scfg, $storeid, $volname, $backing_snap) =3D @_; + + # Only supported by LVM for now + die "volume underlay is not supported for storage type '$scfg->{type= }'\n"; +} + sub volume_snapshot { my ($class, $scfg, $storeid, $volname, $snap) =3D @_; =20 --=20 2.47.3 --===============0599974861473103542== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel --===============0599974861473103542==--