all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Alexandre Derumier via pve-devel <pve-devel@lists.proxmox.com>
To: pve-devel@lists.proxmox.com
Cc: Alexandre Derumier <alexandre.derumier@groupe-cyllene.com>
Subject: [pve-devel] [PATCH FOLLOW-UP storage 10/14] lvmplugin: add volume_snapshot_info
Date: Wed, 16 Jul 2025 08:31:49 +0200	[thread overview]
Message-ID: <mailman.1508.1752647585.395.pve-devel@lists.proxmox.com> (raw)
In-Reply-To: <20250716063153.1647681-1-alexandre.derumier@groupe-cyllene.com>

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

From: Alexandre Derumier <alexandre.derumier@groupe-cyllene.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH FOLLOW-UP storage 10/14] lvmplugin: add volume_snapshot_info
Date: Wed, 16 Jul 2025 08:31:49 +0200
Message-ID: <20250716063153.1647681-15-alexandre.derumier@groupe-cyllene.com>

and remove public methods:
get_snapname_from_path
get_snap_volname

Signed-off-by: Alexandre Derumier <alexandre.derumier@groupe-cyllene.com>
---
 src/PVE/Storage/LVMPlugin.pm | 76 ++++++++++++++++++++++++++----------
 src/PVE/Storage/Plugin.pm    | 41 ++++++++-----------
 2 files changed, 73 insertions(+), 44 deletions(-)

diff --git a/src/PVE/Storage/LVMPlugin.pm b/src/PVE/Storage/LVMPlugin.pm
index 8a61bc5..0e2c38c 100644
--- a/src/PVE/Storage/LVMPlugin.pm
+++ b/src/PVE/Storage/LVMPlugin.pm
@@ -443,20 +443,6 @@ sub parse_volname {
     die "unable to parse lvm volume name '$volname'\n";
 }
 
-#return snapshot name from a file path
-sub get_snapname_from_path {
-    my ($class, $volname, $path) = @_;
-
-    my $basepath = basename($path);
-    my $name = ($volname =~ s/\.[^.]+$//r);
-    if ($basepath =~ m/^snap_${name}_(.*)\.qcow2$/) {
-        return $1;
-    } elsif ($basepath eq $volname) {
-        return 'current';
-    }
-    return undef;
-}
-
 my sub get_snap_name {
     my ($class, $volname, $snapname) = @_;
 
@@ -472,12 +458,6 @@ my sub get_snap_name {
     }
 }
 
-sub get_snap_volname {
-    my ($class, $volname, $snapname) = @_;
-
-    return get_snap_name($class, $volname, $snapname);
-}
-
 sub filesystem_path {
     my ($class, $scfg, $volname, $snapname) = @_;
 
@@ -787,6 +767,62 @@ sub status {
     return undef;
 }
 
+sub volume_snapshot_info {
+    my ($class, $scfg, $storeid, $volname) = @_;
+
+    my $get_snapname_from_path = sub {
+        my ($volname, $path) = @_;
+
+        my $basepath = basename($path);
+        my $name = ($volname =~ s/\.[^.]+$//r);
+        if ($basepath =~ m/^snap_${name}_(.*)\.qcow2$/) {
+            return $1;
+        } elsif ($basepath eq $volname) {
+            return 'current';
+        }
+        return undef;
+    };
+
+    my $path = $class->filesystem_path($scfg, $volname);
+    my ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $format) =
+        $class->parse_volname($volname);
+
+    my $json = PVE::Storage::Common::qemu_img_info($path, undef, 10, 1);
+    die "failed to query file information with qemu-img\n" if !$json;
+    my $json_decode = eval { decode_json($json) };
+    if ($@) {
+        die "Can't decode qemu snapshot list. Invalid JSON: $@\n";
+    }
+    my $info = {};
+    my $order = 0;
+    return $info if ref($json_decode) ne 'ARRAY';
+
+    #no snapshot or external  snapshots is an arrayref
+    my $snapshots = $json_decode;
+    for my $snap (@$snapshots) {
+        my $snapfile = $snap->{filename};
+        my $snapname = $get_snapname_from_path->($volname, $snapfile);
+        #not a proxmox snapshot
+        next if !$snapname;
+
+        my $snapvolname = get_snap_name($class, $volname, $snapname);
+
+        $info->{$snapname}->{order} = $order;
+        $info->{$snapname}->{file} = $snapfile;
+        $info->{$snapname}->{volname} = "$snapvolname";
+        $info->{$snapname}->{volid} = "$storeid:$snapvolname";
+
+        my $parentfile = $snap->{'backing-filename'};
+        if ($parentfile) {
+            my $parentname = $get_snapname_from_path->($volname, $parentfile);
+            $info->{$snapname}->{parent} = $parentname;
+            $info->{$parentname}->{child} = $snapname;
+        }
+        $order++;
+    }
+    return $info;
+}
+
 sub activate_storage {
     my ($class, $storeid, $scfg, $cache) = @_;
 
diff --git a/src/PVE/Storage/Plugin.pm b/src/PVE/Storage/Plugin.pm
index 8ea62e4..aafb13c 100644
--- a/src/PVE/Storage/Plugin.pm
+++ b/src/PVE/Storage/Plugin.pm
@@ -1718,27 +1718,6 @@ sub status {
     return ($res->{total}, $res->{avail}, $res->{used}, 1);
 }
 
-sub get_snap_volname {
-    my ($class, $volname, $snapname) = @_;
-
-    my $vmid = ($class->parse_volname($volname))[2];
-    my $name = get_snap_name($class, $volname, $snapname);
-    return "$vmid/$name";
-}
-
-#return snapshot name from a file path
-sub get_snapname_from_path {
-    my ($class, $volname, $path) = @_;
-
-    my $basepath = basename($path);
-    if ($basepath =~ m/^snap-(.*)-vm(.*)$/) {
-        return $1;
-    } elsif ($basepath eq basename($volname)) {
-        return 'current';
-    }
-    return undef;
-}
-
 # Returns a hash with the snapshot names as keys and the following data:
 # id        - Unique id to distinguish different snapshots even if the have the same name.
 # timestamp - Creation time of the snapshot (seconds since epoch).
@@ -1746,6 +1725,18 @@ sub get_snapname_from_path {
 sub volume_snapshot_info {
     my ($class, $scfg, $storeid, $volname) = @_;
 
+    my $get_snapname_from_path = sub {
+        my ($volname, $path) = @_;
+
+        my $basepath = basename($path);
+        if ($basepath =~ m/^snap-(.*)-vm(.*)$/) {
+            return $1;
+        } elsif ($basepath eq basename($volname)) {
+            return 'current';
+        }
+        return undef;
+    };
+
     my $path = $class->filesystem_path($scfg, $volname);
     my ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $format) =
         $class->parse_volname($volname);
@@ -1772,11 +1763,13 @@ sub volume_snapshot_info {
         my $snapshots = $json_decode;
         for my $snap (@$snapshots) {
             my $snapfile = $snap->{filename};
-            my $snapname = $class->get_snapname_from_path($volname, $snapfile);
+            my $snapname = $get_snapname_from_path->($volname, $snapfile);
             #not a proxmox snapshot
             next if !$snapname;
 
-            my $snapvolname = $class->get_snap_volname($volname, $snapname);
+            my $snapvolname = get_snap_name($class, $volname, $snapname);
+            $snapvolname = "$vmid/$snapvolname";
+
             $info->{$snapname}->{order} = $order;
             $info->{$snapname}->{file} = $snapfile;
             $info->{$snapname}->{volname} = "$snapvolname";
@@ -1785,7 +1778,7 @@ sub volume_snapshot_info {
 
             my $parentfile = $snap->{'backing-filename'};
             if ($parentfile) {
-                my $parentname = $class->get_snapname_from_path($volname, $parentfile);
+                my $parentname = $get_snapname_from_path->($volname, $parentfile);
                 $info->{$snapname}->{parent} = $parentname;
                 $info->{$parentname}->{child} = $snapname;
             }
-- 
2.39.5



[-- 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-07-16  6:33 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20250716063153.1647681-1-alexandre.derumier@groupe-cyllene.com>
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP qemu-server 1/4] api2: move_disk: use parse_volname to find old volume format Alexandre Derumier via pve-devel
2025-07-16 13:58   ` [pve-devel] applied-series: " Wolfgang Bumiller
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP storage 01/14] helpers: make qemu_img* storage config independent Alexandre Derumier via pve-devel
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP qemu-server 2/4] blockdev_rename: remove old left-over rename() Alexandre Derumier via pve-devel
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP storage 02/14] helpers: move qemu_img* to Common module Alexandre Derumier via pve-devel
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP qemu-server 3/4] generate_backing_blockdev: use current_sub for private recursive Alexandre Derumier via pve-devel
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP storage 03/14] rename_snapshot: fix parameter checks Alexandre Derumier via pve-devel
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP qemu-server 4/4] blockdev_external_snapshot: rework to avoid $running param Alexandre Derumier via pve-devel
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP storage 04/14] lvm snapshot: activate volume Alexandre Derumier via pve-devel
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP storage 05/14] common: fix qemu_img_resize Alexandre Derumier via pve-devel
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP storage 06/14] plugin: volume_export: don't allow export of external snapshots Alexandre Derumier via pve-devel
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP storage 07/14] lvmplugin: alloc_snap_image: die if file_size_info return empty size Alexandre Derumier via pve-devel
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP storage 08/14] lvmplugin: snapshot: use relative path for backing image Alexandre Derumier via pve-devel
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP storage 09/14] plugin|lvmplugin: don't allow volume rename if external snapshots exist Alexandre Derumier via pve-devel
2025-07-16  6:31 ` Alexandre Derumier via pve-devel [this message]
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP storage 11/14] plugin: lvmplugin: add parse_snap_name Alexandre Derumier via pve-devel
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP storage 12/14] plugin : improve parse_namedir warning Alexandre Derumier via pve-devel
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP storage 13/14] lvmplugin: add external-snapshots option && forbid creation of qcow2 volumes without it Alexandre Derumier via pve-devel
2025-07-16  6:31 ` [pve-devel] [PATCH FOLLOW-UP storage 14/14] storage: remove $running param from volume_snapshot Alexandre Derumier 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.1508.1752647585.395.pve-devel@lists.proxmox.com \
    --to=pve-devel@lists.proxmox.com \
    --cc=alexandre.derumier@groupe-cyllene.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