From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 00FBC1FF2C8 for ; Wed, 17 Jul 2024 11:41:47 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 9FE3E38482; Wed, 17 Jul 2024 11:41:56 +0200 (CEST) From: Max Carrara To: pve-devel@lists.proxmox.com Date: Wed, 17 Jul 2024 11:40:07 +0200 Message-Id: <20240717094034.124857-10-m.carrara@proxmox.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240717094034.124857-1-m.carrara@proxmox.com> References: <20240717094034.124857-1-m.carrara@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.030 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [RFC pve-storage 09/36] plugin: lvm: move LVM helper subroutines into separate common module X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" A plugin should only do "plugin stuff" and not provide helper subs that other modules also use, so move those helpers into a separate module and document them. This new `Common::LVM` module is a submodule of `Common` (as its name implies) as that logically groups LVM-related subroutines together. The changes of this commit are backwards-compatible; the old subs act as mere wrappers and will emit a warning when used. Signed-off-by: Max Carrara --- src/PVE/Storage/Common.pm | 4 + src/PVE/Storage/Common/LVM.pm | 432 ++++++++++++++++++++++++++++++++ src/PVE/Storage/Common/Makefile | 1 + src/PVE/Storage/LVMPlugin.pm | 254 +++++-------------- 4 files changed, 497 insertions(+), 194 deletions(-) create mode 100644 src/PVE/Storage/Common/LVM.pm diff --git a/src/PVE/Storage/Common.pm b/src/PVE/Storage/Common.pm index a2ae979..0ca0db1 100644 --- a/src/PVE/Storage/Common.pm +++ b/src/PVE/Storage/Common.pm @@ -32,6 +32,10 @@ be grouped in a submodule can also be found here. =over +=item C + +Utilities concerned with LVM, such as manipulating logical volumes. + =item C Utilities concerned with working with paths. diff --git a/src/PVE/Storage/Common/LVM.pm b/src/PVE/Storage/Common/LVM.pm new file mode 100644 index 0000000..e0e3263 --- /dev/null +++ b/src/PVE/Storage/Common/LVM.pm @@ -0,0 +1,432 @@ +package PVE::Storage::Common::LVM; + +use strict; +use warnings; + +use IO::File; + +use PVE::Tools qw(run_command trim); + +use parent qw(Exporter); + +our @EXPORT_OK = qw( + lvm_pv_info + lvm_clear_first_sector + lvm_create_volume_group + lvm_destroy_volume_group + lvm_vgs + lvm_list_volumes + lvm_lvcreate + lvm_lvrename +); + +=pod + +=head1 NAME + +Common::LVM - Provides helper subroutines that wrap commonly used LVM commands + +=head1 FUNCTIONS + +=cut + +my $ignore_no_medium_warnings = sub { + my $line = shift; + # ignore those, most of the time they're from (virtual) IPMI/iKVM devices + # and just spam the log.. + if ($line !~ /open failed: No medium found/) { + print STDERR "$line\n"; + } +}; + +=pod + +=head3 lvm_pv_info + + $pvinfo = lvm_pv_info($device) + +Returns a hash containing information for a I specified +by C<$device>, which must be a valid device path under C. + +The returned hash has the following structure: + + { + pvname => "some-pv-name", + size => 15728640, # size in kibibytes! + vgname => "some-vg-name", + uuid => "1ba3cb42-5407-4cd5-9754-7060dc36ce6d", + } + +This function will die if no C<$device> is specified of if multiple PV entries +exist for C<$device>. + +Should the C<$device> not have an C label, this function will return +C instead. + +=cut + +sub lvm_pv_info : prototype($) { + my ($device) = @_; + + die "no device specified" if !$device; + + my $has_label = 0; + + my $cmd = ['/usr/bin/file', '-L', '-s', $device]; + run_command($cmd, outfunc => sub { + my $line = shift; + $has_label = 1 if $line =~ m/LVM2/; + }); + + return undef if !$has_label; + + $cmd = ['/sbin/pvs', '--separator', ':', '--noheadings', '--units', 'k', + '--unbuffered', '--nosuffix', '--options', + 'pv_name,pv_size,vg_name,pv_uuid', $device]; + + my $pvinfo; + run_command($cmd, outfunc => sub { + my $line = shift; + + $line = trim($line); + + my ($pvname, $size, $vgname, $uuid) = split(':', $line); + + die "found multiple pvs entries for device '$device'\n" + if $pvinfo; + + $pvinfo = { + pvname => $pvname, + size => int($size), + vgname => $vgname, + uuid => $uuid, + }; + }); + + return $pvinfo; +} + +=pod + +=head3 lvm_clear_first_sector + + lvm_clear_first_sector($device) + +Clears the first sector (first 512 bits) of the given block device C<$device>. + +B Use with caution. This function does not actually check whether +a valid device is passed or not. + +=cut + +sub lvm_clear_first_sector : prototype($) { + my ($dev) = shift; + + if (my $fh = IO::File->new($dev, "w")) { + my $buf = 0 x 512; + syswrite $fh, $buf; + $fh->close(); + } +} + +=pod + +=head3 lvm_create_volume_group + + lvm_create_volume_group($device, $vgname, $shared) + +Creates a I for the block device C<$device> with the name +C<$vgname>. The C<$shared> parameter is currently unused. + +Dies if C<$device> is already part of a volume group. + +If C<$device> is already part of a volume group with the exact same name as in +C<$vgname>, nothing will be done and the function returns early. + +=cut + +sub lvm_create_volume_group : prototype($$$) { + my ($device, $vgname, $shared) = @_; + + my $res = lvm_pv_info($device); + + if ($res->{vgname}) { + return if $res->{vgname} eq $vgname; # already created + die "device '$device' is already used by volume group '$res->{vgname}'\n"; + } + + lvm_clear_first_sector($device); # else pvcreate fails + + # we use --metadatasize 250k, which reseults in "pe_start = 512" + # so pe_start is aligned on a 128k boundary (advantage for SSDs) + my $cmd = ['/sbin/pvcreate', '--metadatasize', '250k', $device]; + + run_command($cmd, errmsg => "pvcreate '$device' error"); + + $cmd = ['/sbin/vgcreate', $vgname, $device]; + # push @$cmd, '-c', 'y' if $shared; # we do not use this yet + + run_command($cmd, errmsg => "vgcreate $vgname $device error", errfunc => $ignore_no_medium_warnings, outfunc => $ignore_no_medium_warnings); +} + +=pod + +=head3 lvm_destroy_volume_group + + lvm_destroy_volume_group($vgname) + +Destroys the I with the name C<$vgname>. + +=cut + +sub lvm_destroy_volume_group : prototype($) { + my ($vgname) = @_; + + run_command( + ['vgremove', '-y', $vgname], + errmsg => "unable to remove volume group $vgname", + errfunc => $ignore_no_medium_warnings, + outfunc => $ignore_no_medium_warnings, + ); +} + +=pod + +=head3 lvm_vgs + + $vgs = lvm_vgs() + $vgs = lvm_vgs($includepvs) + $vgs = lvm_vgs(1) + +Returns a hash containing information of the host's I. If the +optional C<$includepvs> parameter is truthy or C<1>, the hash will also contain +extra data for the I in each volume group. + +The returned hash has the following structure: + + { + 'vg-name-00' => { + size => 16106127360, # sizes in bytes! + free => 10737418240, + lvcount => 2, + pvs => [ + { + name => 'vg-name-00--pv-00', + size => ..., + free => ..., + }, + { + name => 'vg-name-00--pv-01', + size => ..., + free => ..., + }, + ] + }, + 'vg-name-01' => { + size => 16106127360, + free => 10737418240, + lvcount => 1, + pvs => [ + { + name => 'vg-name-01--pv-00', + size => ..., + free => ..., + }, + ] + }, + } + +=cut + +sub lvm_vgs : prototype(;$) { + my ($includepvs) = @_; + + my $cmd = ['/sbin/vgs', '--separator', ':', '--noheadings', '--units', 'b', + '--unbuffered', '--nosuffix', '--options']; + + my $cols = [qw(vg_name vg_size vg_free lv_count)]; + + if ($includepvs) { + push @$cols, qw(pv_name pv_size pv_free); + } + + push @$cmd, join(',', @$cols); + + my $vgs = {}; + eval { + run_command($cmd, outfunc => sub { + my $line = shift; + $line = trim($line); + + my ($name, $size, $free, $lvcount, $pvname, $pvsize, $pvfree) = split (':', $line); + + $vgs->{$name} //= { + size => int ($size), + free => int ($free), + lvcount => int($lvcount) + }; + + if (defined($pvname) && defined($pvsize) && defined($pvfree)) { + push @{$vgs->{$name}->{pvs}}, { + name => $pvname, + size => int($pvsize), + free => int($pvfree), + }; + } + }, + errfunc => $ignore_no_medium_warnings, + ); + }; + my $err = $@; + + # just warn (vgs return error code 5 if clvmd does not run) + # but output is still OK (list without clustered VGs) + warn $err if $err; + + return $vgs; +} + +=pod + +=head3 lvm_list_volumes + + $lvs = lvm_list_volumes() + $lvs = lvm_list_volumes($vgname) + +Returns a hash with information of all I on the host. May +optionally be limited to a single I by providing its name +C<$vgname>. + +The returned hash has the following structure: + + { + 'vg-name-00' => { + 'lv-name-00' => { + lv_size => 10737418240, # sizes in bytes! + lv_state => '...', + lv_type => '...', + pool_lv => '...', # optional + tags => '...', # optional + ctime => '...', + }, + 'lv-name-01' => { + lv_size => 10737418240, + lv_state => '...', + lv_type => 't', + pool_lv => '...', # optional + tags => '...', # optional + ctime => '...', + # thinpool specific data + metadata_size => 29381237, # sizes in bytes! + metadata_used => 12917, + used => 3543348019, + }, + }, + 'vg-name-00' => { + ... + } + } + +=cut + +sub lvm_list_volumes : prototype(;$) { + my ($vgname) = @_; + + my $option_list = 'vg_name,lv_name,lv_size,lv_attr,pool_lv,data_percent,metadata_percent,snap_percent,uuid,tags,metadata_size,time'; + + my $cmd = [ + '/sbin/lvs', '--separator', ':', '--noheadings', '--units', 'b', + '--unbuffered', '--nosuffix', + '--config', 'report/time_format="%s"', + '--options', $option_list, + ]; + + push @$cmd, $vgname if $vgname; + + my $lvs = {}; + run_command($cmd, outfunc => sub { + my $line = shift; + + $line = trim($line); + + my ($vg_name, $lv_name, $lv_size, $lv_attr, $pool_lv, $data_percent, $meta_percent, $snap_percent, $uuid, $tags, $meta_size, $ctime) = split(':', $line); + return if !$vg_name; + return if !$lv_name; + + my $lv_type = substr($lv_attr, 0, 1); + + my $d = { + lv_size => int($lv_size), + lv_state => substr($lv_attr, 4, 1), + lv_type => $lv_type, + }; + $d->{pool_lv} = $pool_lv if $pool_lv; + $d->{tags} = $tags if $tags; + $d->{ctime} = $ctime; + + if ($lv_type eq 't') { + $data_percent ||= 0; + $meta_percent ||= 0; + $snap_percent ||= 0; + $d->{metadata_size} = int($meta_size); + $d->{metadata_used} = int(($meta_percent * $meta_size)/100); + $d->{used} = int(($data_percent * $lv_size)/100); + } + $lvs->{$vg_name}->{$lv_name} = $d; + }, + errfunc => $ignore_no_medium_warnings, + ); + + return $lvs; +} + +=head3 lvm_lvcreate + + lvm_lvcreate($vgname, $name, $size, $tags) + +Creates a new I named C<$name> for the I +C<$vgname>, with a size of C<$size> B per default. Optionally, +a list of tags for the new LV may be provided via C<$tags>. + +Alternatively, C<$size> may optionally also be expressed with a unit, e.g. +C<"50g"> (50 gibibytes), C<"1T"> (1 terabyte), etc. + +=cut + +sub lvm_lvcreate : prototype($$$;$) { + my ($vg, $name, $size, $tags) = @_; + + if ($size =~ m/\d$/) { # no unit is given + $size .= "k"; # default to kilobytes + } + + my $cmd = ['/sbin/lvcreate', '-aly', '-Wy', '--yes', '--size', $size, '--name', $name]; + for my $tag (@$tags) { + push @$cmd, '--addtag', $tag; + } + push @$cmd, $vg; + + run_command($cmd, errmsg => "lvcreate '$vg/$name' error"); +} + +=pod + +=head3 lvm_lvrename + + lvm_lvrename($vgname, $oldname, $newname) + +Renames a I of a I C<$vgname> from C<$oldname> +to C<$newname>. + +=cut + +sub lvm_lvrename : prototype($$$) { + my ($vg, $oldname, $newname) = @_; + + run_command( + ['/sbin/lvrename', $vg, $oldname, $newname], + errmsg => "lvrename '${vg}/${oldname}' to '${newname}' error", + ); +} + +1; diff --git a/src/PVE/Storage/Common/Makefile b/src/PVE/Storage/Common/Makefile index 9455b81..863f7c7 100644 --- a/src/PVE/Storage/Common/Makefile +++ b/src/PVE/Storage/Common/Makefile @@ -1,4 +1,5 @@ SOURCES = \ + LVM.pm \ Path.pm \ diff --git a/src/PVE/Storage/LVMPlugin.pm b/src/PVE/Storage/LVMPlugin.pm index 4b951e7..a9bc178 100644 --- a/src/PVE/Storage/LVMPlugin.pm +++ b/src/PVE/Storage/LVMPlugin.pm @@ -6,207 +6,98 @@ use warnings; use IO::File; use PVE::Tools qw(run_command trim); +use PVE::Storage::Common qw(get_deprecation_warning); use PVE::Storage::Plugin; +use PVE::Storage::Common::LVM; use PVE::JSONSchema qw(get_standard_option); use base qw(PVE::Storage::Plugin); # lvm helper functions -my $ignore_no_medium_warnings = sub { - my $line = shift; - # ignore those, most of the time they're from (virtual) IPMI/iKVM devices - # and just spam the log.. - if ($line !~ /open failed: No medium found/) { - print STDERR "$line\n"; - } -}; - sub lvm_pv_info { - my ($device) = @_; - - die "no device specified" if !$device; - - my $has_label = 0; - - my $cmd = ['/usr/bin/file', '-L', '-s', $device]; - run_command($cmd, outfunc => sub { - my $line = shift; - $has_label = 1 if $line =~ m/LVM2/; - }); - - return undef if !$has_label; - - $cmd = ['/sbin/pvs', '--separator', ':', '--noheadings', '--units', 'k', - '--unbuffered', '--nosuffix', '--options', - 'pv_name,pv_size,vg_name,pv_uuid', $device]; - - my $pvinfo; - run_command($cmd, outfunc => sub { - my $line = shift; - - $line = trim($line); - - my ($pvname, $size, $vgname, $uuid) = split(':', $line); - - die "found multiple pvs entries for device '$device'\n" - if $pvinfo; + warn get_deprecation_warning( + 'PVE::Storage::Common::LVM::lvm_pv_info' + ); - $pvinfo = { - pvname => $pvname, - size => int($size), - vgname => $vgname, - uuid => $uuid, - }; - }); + my ($device) = @_; - return $pvinfo; + return PVE::Storage::Common::LVM::lvm_pv_info($device); } sub clear_first_sector { - my ($dev) = shift; + warn get_depreciation_warning( + 'PVE::Storage::Common::LVM::lvm_clear_first_sector' + ); - if (my $fh = IO::File->new($dev, "w")) { - my $buf = 0 x 512; - syswrite $fh, $buf; - $fh->close(); - } + my ($dev) = @_; + + PVE::Storage::Common::LVM::lvm_clear_first_sector($dev); } sub lvm_create_volume_group { - my ($device, $vgname, $shared) = @_; - - my $res = lvm_pv_info($device); - - if ($res->{vgname}) { - return if $res->{vgname} eq $vgname; # already created - die "device '$device' is already used by volume group '$res->{vgname}'\n"; - } - - clear_first_sector($device); # else pvcreate fails - - # we use --metadatasize 250k, which reseults in "pe_start = 512" - # so pe_start is aligned on a 128k boundary (advantage for SSDs) - my $cmd = ['/sbin/pvcreate', '--metadatasize', '250k', $device]; - - run_command($cmd, errmsg => "pvcreate '$device' error"); + warn get_depreciation_warning( + 'PVE::Storage::Common::LVM::lvm_create_volume_group' + ); - $cmd = ['/sbin/vgcreate', $vgname, $device]; - # push @$cmd, '-c', 'y' if $shared; # we do not use this yet + my ($device, $vgname, $shared) = @_; - run_command($cmd, errmsg => "vgcreate $vgname $device error", errfunc => $ignore_no_medium_warnings, outfunc => $ignore_no_medium_warnings); + PVE::Storage::Common::LVM::lvm_create_volume_group( + $device, $vgname, $shared + ); } sub lvm_destroy_volume_group { + warn get_depreciation_warning( + 'PVE::Storage::Common::LVM::lvm_destroy_volume_group' + ); + my ($vgname) = @_; - run_command( - ['vgremove', '-y', $vgname], - errmsg => "unable to remove volume group $vgname", - errfunc => $ignore_no_medium_warnings, - outfunc => $ignore_no_medium_warnings, - ); + PVE::Storage::Common::LVM::lvm_destroy_volume_group($vgname); } sub lvm_vgs { - my ($includepvs) = @_; - - my $cmd = ['/sbin/vgs', '--separator', ':', '--noheadings', '--units', 'b', - '--unbuffered', '--nosuffix', '--options']; - - my $cols = [qw(vg_name vg_size vg_free lv_count)]; + warn get_depreciation_warning( + 'PVE::Storage::Common::LVM::lvm_vgs' + ); - if ($includepvs) { - push @$cols, qw(pv_name pv_size pv_free); - } + my ($includepvs) = @_; - push @$cmd, join(',', @$cols); + return PVE::Storage::Common::LVM::lvm_vgs($includepvs); +} - my $vgs = {}; - eval { - run_command($cmd, outfunc => sub { - my $line = shift; - $line = trim($line); +sub lvm_list_volumes { + warn get_depreciation_warning( + 'PVE::Storage::Common::LVM::lvm_list_volumes' + ); - my ($name, $size, $free, $lvcount, $pvname, $pvsize, $pvfree) = split (':', $line); + my ($vgname) = @_; - $vgs->{$name} //= { - size => int ($size), - free => int ($free), - lvcount => int($lvcount) - }; + return PVE::Storage::Common::LVM::lvm_list_volumes($vgname); +} - if (defined($pvname) && defined($pvsize) && defined($pvfree)) { - push @{$vgs->{$name}->{pvs}}, { - name => $pvname, - size => int($pvsize), - free => int($pvfree), - }; - } - }, - errfunc => $ignore_no_medium_warnings, - ); - }; - my $err = $@; +sub lvcreate { + warn get_deprecation_warning( + 'PVE::Storage::Common::LVM::lvm_lvcreate' + ); - # just warn (vgs return error code 5 if clvmd does not run) - # but output is still OK (list without clustered VGs) - warn $err if $err; + my ($vgname, $name, $size, $tags) = @_; - return $vgs; + PVE::Storage::Common::LVM::lvm_lvcreate($vgname, $name, $size, $tags); } -sub lvm_list_volumes { - my ($vgname) = @_; - - my $option_list = 'vg_name,lv_name,lv_size,lv_attr,pool_lv,data_percent,metadata_percent,snap_percent,uuid,tags,metadata_size,time'; - - my $cmd = [ - '/sbin/lvs', '--separator', ':', '--noheadings', '--units', 'b', - '--unbuffered', '--nosuffix', - '--config', 'report/time_format="%s"', - '--options', $option_list, - ]; - - push @$cmd, $vgname if $vgname; - - my $lvs = {}; - run_command($cmd, outfunc => sub { - my $line = shift; - - $line = trim($line); - - my ($vg_name, $lv_name, $lv_size, $lv_attr, $pool_lv, $data_percent, $meta_percent, $snap_percent, $uuid, $tags, $meta_size, $ctime) = split(':', $line); - return if !$vg_name; - return if !$lv_name; - - my $lv_type = substr($lv_attr, 0, 1); - - my $d = { - lv_size => int($lv_size), - lv_state => substr($lv_attr, 4, 1), - lv_type => $lv_type, - }; - $d->{pool_lv} = $pool_lv if $pool_lv; - $d->{tags} = $tags if $tags; - $d->{ctime} = $ctime; - - if ($lv_type eq 't') { - $data_percent ||= 0; - $meta_percent ||= 0; - $snap_percent ||= 0; - $d->{metadata_size} = int($meta_size); - $d->{metadata_used} = int(($meta_percent * $meta_size)/100); - $d->{used} = int(($data_percent * $lv_size)/100); - } - $lvs->{$vg_name}->{$lv_name} = $d; - }, - errfunc => $ignore_no_medium_warnings, +sub lvrename { + warn get_deprecation_warning( + 'PVE::Storage::Common::LVM::lvm_lvrename' ); - return $lvs; + my ($vgname, $oldname, $newname) = @_; + + PVE::Storage::Common::LVM::lvm_lvrename($vgname, $oldname, $newname); } + # Configuration sub type { @@ -279,7 +170,7 @@ sub on_add_hook { PVE::Storage::activate_storage($cfg, $baseid); - lvm_create_volume_group($path, $scfg->{vgname}, $scfg->{shared}); + PVE::Storage::Common::LVM::lvm_create_volume_group($path, $scfg->{vgname}, $scfg->{shared}); } return; @@ -328,38 +219,13 @@ sub find_free_diskname { my $vg = $scfg->{vgname}; - my $lvs = lvm_list_volumes($vg); + my $lvs = PVE::Storage::Common::LVM::lvm_list_volumes($vg); my $disk_list = [ keys %{$lvs->{$vg}} ]; return PVE::Storage::Plugin::get_next_vm_diskname($disk_list, $storeid, $vmid, undef, $scfg); } -sub lvcreate { - my ($vg, $name, $size, $tags) = @_; - - if ($size =~ m/\d$/) { # no unit is given - $size .= "k"; # default to kilobytes - } - - my $cmd = ['/sbin/lvcreate', '-aly', '-Wy', '--yes', '--size', $size, '--name', $name]; - for my $tag (@$tags) { - push @$cmd, '--addtag', $tag; - } - push @$cmd, $vg; - - run_command($cmd, errmsg => "lvcreate '$vg/$name' error"); -} - -sub lvrename { - my ($vg, $oldname, $newname) = @_; - - run_command( - ['/sbin/lvrename', $vg, $oldname, $newname], - errmsg => "lvrename '${vg}/${oldname}' to '${newname}' error", - ); -} - sub alloc_image { my ($class, $storeid, $scfg, $vmid, $fmt, $name, $size) = @_; @@ -368,7 +234,7 @@ sub alloc_image { die "illegal name '$name' - should be 'vm-$vmid-*'\n" if $name && $name !~ m/^vm-$vmid-/; - my $vgs = lvm_vgs(); + my $vgs = PVE::Storage::Common::LVM::lvm_vgs(); my $vg = $scfg->{vgname}; @@ -381,7 +247,7 @@ sub alloc_image { $name = $class->find_free_diskname($storeid, $scfg, $vmid) if !$name; - lvcreate($vg, $name, $size, ["pve-vm-$vmid"]); + PVE::Storage::Common::LVM::lvcreate($vg, $name, $size, ["pve-vm-$vmid"]); return $name; } @@ -452,7 +318,7 @@ sub list_images { my $vgname = $scfg->{vgname}; - $cache->{lvs} = lvm_list_volumes() if !$cache->{lvs}; + $cache->{lvs} = PVE::Storage::Common::LVM::lvm_list_volumes() if !$cache->{lvs}; my $res = []; @@ -492,7 +358,7 @@ sub list_images { sub status { my ($class, $storeid, $scfg, $cache) = @_; - $cache->{vgs} = lvm_vgs() if !$cache->{vgs}; + $cache->{vgs} = PVE::Storage::Common::LVM::lvm_vgs() if !$cache->{vgs}; my $vgname = $scfg->{vgname}; @@ -506,7 +372,7 @@ sub status { sub activate_storage { my ($class, $storeid, $scfg, $cache) = @_; - $cache->{vgs} = lvm_vgs() if !$cache->{vgs}; + $cache->{vgs} = PVE::Storage::Common::LVM::lvm_vgs() if !$cache->{vgs}; # In LVM2, vgscans take place automatically; # this is just to be sure @@ -669,7 +535,7 @@ sub volume_import { if $file_format ne 'raw'; my $vg = $scfg->{vgname}; - my $lvs = lvm_list_volumes($vg); + my $lvs = PVE::Storage::Common::LVM::lvm_list_volumes($vg); if ($lvs->{$vg}->{$volname}) { die "volume $vg/$volname already exists\n" if !$allow_rename; warn "volume $vg/$volname already exists - importing with a different name\n"; @@ -730,7 +596,7 @@ sub rename_volume { if !$target_volname; my $vg = $scfg->{vgname}; - my $lvs = lvm_list_volumes($vg); + my $lvs = PVE::Storage::Common::LVM::lvm_list_volumes($vg); die "target volume '${target_volname}' already exists\n" if ($lvs->{$vg}->{$target_volname}); -- 2.39.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel