[pve-devel] [RFC pve-storage 08/36] plugin: dir: move helper subs of directory plugin to common modules
Max Carrara
m.carrara at proxmox.com
Wed Jul 17 11:40:06 CEST 2024
Because the directory plugin's subroutines are frequently used by
other plugins, it's best to factor these helpers into the common
module. This is a first step in making other plugins not depend on the
directory plugin anymore.
Simultaneously this commit also introduces the `Common::Path` module,
which ought to provide shared subroutines for operations on paths.
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 <m.carrara at proxmox.com>
---
src/PVE/Storage/Common.pm | 31 ++++++++++++++++++++
src/PVE/Storage/Common/Makefile | 1 +
src/PVE/Storage/Common/Path.pm | 51 +++++++++++++++++++++++++++++++++
src/PVE/Storage/DirPlugin.pm | 38 ++++++++++++------------
4 files changed, 101 insertions(+), 20 deletions(-)
create mode 100644 src/PVE/Storage/Common/Path.pm
diff --git a/src/PVE/Storage/Common.pm b/src/PVE/Storage/Common.pm
index f828c8c..a2ae979 100644
--- a/src/PVE/Storage/Common.pm
+++ b/src/PVE/Storage/Common.pm
@@ -3,10 +3,13 @@ package PVE::Storage::Common;
use strict;
use warnings;
+use PVE::JSONSchema;
+
use parent qw(Exporter);
our @EXPORT_OK = qw(
get_deprecation_warning
+ storage_parse_is_mountpoint
);
=pod
@@ -29,10 +32,19 @@ be grouped in a submodule can also be found here.
=over
+=item C<PVE::Storage::Common::Path>
+
+Utilities concerned with working with paths.
+
=back
=head1 FUNCTIONS
+B<Note:> Functions prefixed with C<storage_> are related to the C<PVE::Storage>
+API and usually expect an C<$scfg> ("storage config") hash. This hash is
+expected to contain the configuration for I<one> storage, which is (usually)
+acquired via C<PVE::Storage::storage_config>.
+
=cut
=pod
@@ -56,4 +68,23 @@ sub get_deprecation_warning : prototype($) {
. "the future. Please use '$new_sub_name' instead.";
}
+=head3 storage_parse_is_mountpoint
+
+ $path = storage_parse_is_mountpoint($scfg)
+
+Helper that tries to return a path if the given I<storage config> hash C<$scfg>
+contains an C<is_mountpoint> property. Returns C<undef> if it can't.
+
+=cut
+
+sub storage_parse_is_mountpoint : prototype($) {
+ my ($scfg) = @_;
+ my $is_mp = $scfg->{is_mountpoint};
+ return undef if !defined $is_mp;
+ if (defined(my $bool = PVE::JSONSchema::parse_boolean($is_mp))) {
+ return $bool ? $scfg->{path} : undef;
+ }
+ return $is_mp; # contains a path
+}
+
1;
diff --git a/src/PVE/Storage/Common/Makefile b/src/PVE/Storage/Common/Makefile
index 0c4bba5..9455b81 100644
--- a/src/PVE/Storage/Common/Makefile
+++ b/src/PVE/Storage/Common/Makefile
@@ -1,4 +1,5 @@
SOURCES = \
+ Path.pm \
.PHONY: install
diff --git a/src/PVE/Storage/Common/Path.pm b/src/PVE/Storage/Common/Path.pm
new file mode 100644
index 0000000..7535dda
--- /dev/null
+++ b/src/PVE/Storage/Common/Path.pm
@@ -0,0 +1,51 @@
+package PVE::Storage::Common::Path;
+
+use strict;
+use warnings;
+
+use Cwd;
+
+use PVE::ProcFSTools;
+
+use parent qw(Exporter);
+
+our @EXPORT_OK = qw(
+ path_is_mounted
+);
+
+=pod
+
+=head1 NAME
+
+PVE::Storage::Common::Path - Shared functions and utilities for manipulating paths
+
+=head1 FUNCTIONS
+
+=cut
+
+=pod
+
+=head3 path_is_mounted
+
+ $is_mounted = path_is_mounted($mountpoint)
+ $is_mounted = path_is_mounted($mountpoint, $mountdata)
+
+Checks if the given path in C<$mountpoint> is actually mounted. Optionally takes
+a C<$mountdata> hash returned by C<PVE::ProcFSTools::parse_proc_mounts> in
+order to avoid repeatedly reading and parsing C</proc/mounts>.
+
+=cut
+
+# NOTE: should ProcFSTools::is_mounted accept an optional cache like this?
+sub path_is_mounted {
+ my ($mountpoint, $mountdata) = @_;
+
+ $mountpoint = Cwd::realpath($mountpoint); # symlinks
+ return 0 if !defined($mountpoint); # path does not exist
+
+ $mountdata = PVE::ProcFSTools::parse_proc_mounts() if !$mountdata;
+ return 1 if grep { $_->[1] eq $mountpoint } @$mountdata;
+ return undef;
+}
+
+1;
diff --git a/src/PVE/Storage/DirPlugin.pm b/src/PVE/Storage/DirPlugin.pm
index 2efa8d5..ac0d365 100644
--- a/src/PVE/Storage/DirPlugin.pm
+++ b/src/PVE/Storage/DirPlugin.pm
@@ -3,12 +3,16 @@ package PVE::Storage::DirPlugin;
use strict;
use warnings;
-use Cwd;
use Encode qw(decode encode);
use File::Path;
use IO::File;
use POSIX;
+use PVE::Storage::Common qw(
+ get_deprecation_warning
+ storage_parse_is_mountpoint
+);
+use PVE::Storage::Common::Path;
use PVE::Storage::Plugin;
use PVE::JSONSchema qw(get_standard_option);
@@ -86,26 +90,20 @@ sub options {
# Storage implementation
#
-# NOTE: should ProcFSTools::is_mounted accept an optional cache like this?
sub path_is_mounted {
- my ($mountpoint, $mountdata) = @_;
+ warn get_deprecation_warning(
+ "PVE::Storage::Common::Path::path_is_mounted"
+ );
- $mountpoint = Cwd::realpath($mountpoint); # symlinks
- return 0 if !defined($mountpoint); # path does not exist
-
- $mountdata = PVE::ProcFSTools::parse_proc_mounts() if !$mountdata;
- return 1 if grep { $_->[1] eq $mountpoint } @$mountdata;
- return undef;
+ return PVE::Storage::Common::Path::path_is_mounted(@_);
}
sub parse_is_mountpoint {
- my ($scfg) = @_;
- my $is_mp = $scfg->{is_mountpoint};
- return undef if !defined $is_mp;
- if (defined(my $bool = PVE::JSONSchema::parse_boolean($is_mp))) {
- return $bool ? $scfg->{path} : undef;
- }
- return $is_mp; # contains a path
+ warn get_deprecation_warning(
+ "PVE::Storage::Common::storage_parse_is_mountpoint"
+ );
+
+ return storage_parse_is_mountpoint(@_);
}
# FIXME move into 'get_volume_attribute' when removing 'get_volume_notes'
@@ -211,11 +209,11 @@ sub update_volume_attribute {
sub status {
my ($class, $storeid, $scfg, $cache) = @_;
- if (defined(my $mp = parse_is_mountpoint($scfg))) {
+ if (defined(my $mp = PVE::Storage::Common::storage_parse_is_mountpoint($scfg))) {
$cache->{mountdata} = PVE::ProcFSTools::parse_proc_mounts()
if !$cache->{mountdata};
- return undef if !path_is_mounted($mp, $cache->{mountdata});
+ return undef if !PVE::Storage::Common::Path::path_is_mounted($mp, $cache->{mountdata});
}
return $class->SUPER::status($storeid, $scfg, $cache);
@@ -227,8 +225,8 @@ sub activate_storage {
my $path = $scfg->{path};
- my $mp = parse_is_mountpoint($scfg);
- if (defined($mp) && !path_is_mounted($mp, $cache->{mountdata})) {
+ my $mp = storage_parse_is_mountpoint($scfg);
+ if (defined($mp) && !PVE::Storage::Common::Path::path_is_mounted($mp, $cache->{mountdata})) {
die "unable to activate storage '$storeid' - " .
"directory is expected to be a mount point but is not mounted: '$mp'\n";
}
--
2.39.2
More information about the pve-devel
mailing list