[PATCH pve-storage v1 12/54] plugin: use closure for inner loop logic in list_volumes

Max R. Carrara
2026-04-22T11:15:19Z

Factor most of the body of the inner loop of the `list_volumes()`
plugin API method into a closure and provide additional context for
why we have such an elaborate check for VM / CT disks in the first
place.

This has the added benefit that we now also do not modify the volume
hashes on the fly anymore when determining whether a volume's type
aligns with a guest's type. Small difference, but might make it a
little easier to adapt that code in the future, e.g. when we align
vtypes and content types.

Also, rename `$item` to `$volume` for clarity's sake.

Signed-off-by: Max R. Carrara <m.carrara@proxmox.com>
---
src/PVE/Storage/Plugin.pm | 49 +++++++++++++++++++++++++--------------
1 file changed, 32 insertions(+), 17 deletions(-)

diff --git a/src/PVE/Storage/Plugin.pm b/src/PVE/Storage/Plugin.pm
index 106cff6f..c96c1ed7 100644
--- a/src/PVE/Storage/Plugin.pm
+++ b/src/PVE/Storage/Plugin.pm
@@ -1820,29 +1820,44 @@ sub list_volumes {
return;
};

+ my $get_content_type_for_volume = sub {
+ my ($volume, $type) = @_;
+
+ # It is currently impossible to determine whether a volume belongs to a
+ # VM or a CT based on the output of list_images alone.
+ # Therefore, we use the parsed ID ($volume->{vmid}) to look up the guest
+ # and make sure that the guest's type corresponds to the volume's type.
+ if ($type eq 'images' || $type eq 'rootdir') {
+ my $vminfo = $vmlist->{ids}->{ $volume->{vmid} };
+
+ my $vmtype;
+ if (defined($vminfo)) {
+ $vmtype = $vminfo->{type};
+ }
+
+ my $content_type = 'images';
+ if (defined($vmtype) && $vmtype eq 'lxc') {
+ $content_type = 'rootdir';
+ }
+
+ return if $content_type ne $type;
+ }
+
+ return $type;
+ };
+
for my $type ($content_types->@*) {
my $raw_volumes = $get_raw_volumes_for_type->($type);

next if !defined($raw_volumes);

- for my $item ($raw_volumes->@*) {
- if ($type eq 'images' || $type eq 'rootdir') {
- my $vminfo = $vmlist->{ids}->{ $item->{vmid} };
- my $vmtype;
- if (defined($vminfo)) {
- $vmtype = $vminfo->{type};
- }
- if (defined($vmtype) && $vmtype eq 'lxc') {
- $item->{content} = 'rootdir';
- } else {
- $item->{content} = 'images';
- }
- next if $type ne $item->{content};
- } else {
- $item->{content} = $type;
- }
+ for my $volume ($raw_volumes->@*) {
+ my $content_type = $get_content_type_for_volume->($volume, $type);

- push $res->@*, $item;
+ next if !defined($content_type);
+
+ $volume->{content} = $content_type;
+ push $res->@*, $volume;
}
}

--
2.47.3