all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Tiago Sousa via pve-devel <pve-devel@lists.proxmox.com>
To: pve-devel@lists.proxmox.com
Cc: Tiago Sousa <joao.sousa@eurotux.com>
Subject: [pve-devel] [PATCH pve-storage 4/4] plugin: lvmplugin: add underlay functions
Date: Fri, 17 Oct 2025 12:25:29 +0100	[thread overview]
Message-ID: <mailman.58.1760700935.362.pve-devel@lists.proxmox.com> (raw)
In-Reply-To: <20251017112539.26471-1-joao.sousa@eurotux.com>

[-- Attachment #1: Type: message/rfc822, Size: 10214 bytes --]

From: Tiago Sousa <joao.sousa@eurotux.com>
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>

Signed-off-by: Tiago Sousa <joao.sousa@eurotux.com>
---
 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 {
     }
 }
 
+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_underlay_resize {
+    my ($cfg, $volid, $size, $running, $backing_snap) = @_;
+
+    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_resize($scfg, $storeid, $volname, $size, $running, $backing_snap);
+    } elsif ($volid =~ 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) = @_;
 
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 => { optional => 1 },
         bwlimit => { optional => 1 },
         'snapshot-as-volume-chain' => { optional => 1 },
+        chunksize => { optional => 1 },
+        'chunk-percentage' => { optional => 1 },
     };
 }
 
@@ -939,6 +941,44 @@ 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, $backing_snap) = @_;
+
+    my ($format) = ($class->parse_volname($volname))[6];
+
+    my $path = $class->filesystem_path($scfg, $volname);
+    my $json = PVE::Storage::Common::qemu_img_info($path, undef, 10, 0);
+    my $json_decode = eval { decode_json($json) };
+    if ($@) {
+        die "Can't decode qemu snapshot list. Invalid JSON: $@\n";
+    }
+
+    my $virtual_size = $json_decode->{'virtual-size'} / 1024;
+
+    my $underlay_size = lv_size($path, 10);
+
+    my $updated_underlay_size = ($underlay_size + $scfg->{chunksize}) / 1024;
+    $updated_underlay_size = calculate_lvm_size($virtual_size, $format, $backing_snap)
+        if $updated_underlay_size >= $virtual_size;
+
+    my $lvmsize = "${updated_underlay_size}k";
+    lv_extend($class, $scfg, $storeid, $lvmsize, $path);
+
+    return $updated_underlay_size;
+}
+
+sub lv_extend {
+    my ($class, $scfg, $storeid, $lvmsize, $path) = @_;
     my $cmd = ['/sbin/lvextend', '-L', $lvmsize, $path];
 
     $class->cluster_lock_storage(
@@ -949,13 +989,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 {
@@ -966,6 +999,22 @@ sub volume_size_info {
 
     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',
         '--separator',
@@ -989,7 +1038,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 8acd214..f08393b 100644
--- a/src/PVE/Storage/Plugin.pm
+++ b/src/PVE/Storage/Plugin.pm
@@ -228,6 +228,20 @@ my $defaultData = {
             default => 0,
             optional => 1,
         },
+        chunksize => {
+            type => 'integer',
+            description => 'The chunksize in Bytes to define the write threshold'
+                . 'of thin disks on thick storage.',
+            default => 1073741824, # 1 GiB
+            optional => 1,
+        },
+        'chunk-percentage' => {
+            type => 'number',
+            description => 'The percentage of written disk to define the write'
+                . 'threshold.',
+            default => 0.5,
+            optional => 1,
+        },
     },
 };
 
@@ -1265,7 +1279,6 @@ 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_resize {
@@ -1285,6 +1298,20 @@ sub volume_resize {
     return undef;
 }
 
+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_underlay_resize {
+    my ($class, $scfg, $storeid, $volname, $backing_snap) = @_;
+
+    # 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) = @_;
 
-- 
2.47.3



[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

  parent reply	other threads:[~2025-10-17 11:35 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20251017112539.26471-1-joao.sousa@eurotux.com>
2025-10-17 11:25 ` [pve-devel] [PATCH pve-storage 1/4] pvestord: setup new pvestord daemon Tiago Sousa via pve-devel
2025-10-17 11:25 ` [pve-devel] [PATCH pve-storage 2/4] storage: add extend queue handling Tiago Sousa via pve-devel
2025-10-17 11:25 ` [pve-devel] [PATCH pve-storage 3/4] lvmplugin: add thin volume support for LVM external snapshots Tiago Sousa via pve-devel
2025-10-17 11:25 ` Tiago Sousa via pve-devel [this message]
2025-10-17 11:25 ` [pve-devel] [PATCH qemu-server 5/8] qmeventd: add block write threshold event handling Tiago Sousa via pve-devel
2025-10-17 11:25 ` [pve-devel] [PATCH qemu-server 6/8] blockdev: add set write threshold Tiago Sousa via pve-devel
2025-10-17 11:25 ` [pve-devel] [PATCH qemu-server 7/8] blockdev: add query-blockstats qmp command Tiago Sousa via pve-devel
2025-10-17 11:25 ` [pve-devel] [PATCH qemu-server 8/8] blockdev: add underlay resize Tiago Sousa via pve-devel
2025-10-17 11:25 ` [pve-devel] [PATCH pve-cluster 9/9] observe extend queue Tiago Sousa via pve-devel
2025-10-17 11:25 ` [pve-devel] [PATCH pve-manager 10/10] services: add pvestord service Tiago Sousa via pve-devel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=mailman.58.1760700935.362.pve-devel@lists.proxmox.com \
    --to=pve-devel@lists.proxmox.com \
    --cc=joao.sousa@eurotux.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal