From: Wolfgang Bumiller <w.bumiller@proxmox.com>
To: "Max R. Carrara" <m.carrara@proxmox.com>
Cc: pve-devel@lists.proxmox.com
Subject: Re: [PATCH pve-storage v1 16/54] storage: clean up code that was moved into helper in path_to_volume_id
Date: Tue, 28 Apr 2026 17:08:05 +0200 [thread overview]
Message-ID: <j5ygsulsykpaevszwpuv2726r7ogzz6wd2346telm7szlqmbwl@opm2banmchnp> (raw)
In-Reply-To: <20260422111322.257380-17-m.carrara@proxmox.com>
On Wed, Apr 22, 2026 at 01:12:42PM +0200, Max R. Carrara wrote:
> In order to make the parsing logic in `path_to_volume_id()` both
> simpler and more manageable for future changes, do the following:
>
> 1. Iterate over a list of vtypes that store their contents in
> subdirectories and fetch said subdirectories dynamically instead of
> hardcoding them.
>
> 2. Explicitly exclude the `rootdir` vtype in this list of vtypes, as
> its subdirectory is currently not used.
>
> 3. Strip the vtype subdirectory from the beginning of the path in
> order to make matching on the file name easier. Return early as a
> safeguard if this fails.
>
> 4. Adapt the original regexes in the parsing helper to not include the
> vtype subdir anymore, since this is now being stripped.
>
> 5. Instead of returning a 2-element array, return `undef` if the path
> fails to parse, and the volume ID (volid) alone if parsing
> succeeds. Since the caller is now passing along the vtype, it does
> not need to be returned anymore.
>
> Note that the parsing logic of the `parse_volid_from_file_path()`
> helper inside `path_to_volume_id()` now is very similar to the parsing
> logic of the `get_subdir_file_info()` closure in the
> `get_subdir_files()` helper inside `Plugin.pm`. This opens up further
> simplification / code de-duplication in the future, so that our
> parsing logic can eventually be kept in one place only.
>
> Signed-off-by: Max R. Carrara <m.carrara@proxmox.com>
> ---
> src/PVE/Storage.pm | 73 +++++++++++++++++++++++++++++++---------------
> 1 file changed, 50 insertions(+), 23 deletions(-)
>
> diff --git a/src/PVE/Storage.pm b/src/PVE/Storage.pm
> index 2886ab9e..1b0569dd 100755
> --- a/src/PVE/Storage.pm
> +++ b/src/PVE/Storage.pm
> @@ -23,6 +23,7 @@ use PVE::INotify;
> use PVE::RPCEnvironment;
> use PVE::SSHInfo;
> use PVE::Storage::Common qw(
> + plugin_get_default_vtype_subdirs
> plugin_get_vtype_subdir
> );
> use PVE::RESTEnvironment qw(log_warn);
> @@ -712,17 +713,31 @@ sub path_to_volume_id {
> # for example when nfs storage is not mounted
> $path = abs_path($path) || $path;
>
> + my $get_vtypes_to_check = sub {
> + my $default_vtype_subdirs = plugin_get_default_vtype_subdirs();
> +
> + # TODO: vtype split: handle directory for 'rootdir' type.
> + # CTs currently use the same dir as VMs --> the dir for the 'images' type.
> + # Directory is therefore unused right now, so exclude it.
> + delete $default_vtype_subdirs->{rootdir};
> +
> + return [sort keys $default_vtype_subdirs->%*];
> + };
> +
> my $parse_volid_from_file_path = sub {
> - my ($plugin, $sid, $scfg) = @_;
> + my ($plugin, $sid, $scfg, $vtype) = @_;
>
> - my $imagedir = plugin_get_vtype_subdir($scfg, 'images');
> - my $isodir = plugin_get_vtype_subdir($scfg, 'iso');
> - my $tmpldir = plugin_get_vtype_subdir($scfg, 'vztmpl');
> - my $backupdir = plugin_get_vtype_subdir($scfg, 'backup');
> - my $snippetsdir = plugin_get_vtype_subdir($scfg, 'snippets');
> - my $importdir = plugin_get_vtype_subdir($scfg, 'import');
> + my $vtype_subdir = plugin_get_vtype_subdir($scfg, $vtype);
>
> - if ($path =~ m!^\Q$imagedir\E/(\d+)/([^/\s]+)$!) {
> + # Strip the vtype subdir from beginning of the current path
> + # so that we don't have to take it into account when parsing the file name
> + my $filename = $path;
> + if ($filename !~ s!^\Q$vtype_subdir\E!!) {
Same as in 9/54 - lookahead for a slash may be useful.
> + return;
> + }
> +
> + if ($vtype eq 'images') {
> + return if $filename !~ m!/(\d+)/([^/\s]+)$!;
> my $vmid = $1;
> my $name = $2;
>
> @@ -731,48 +746,60 @@ sub path_to_volume_id {
> my ($storeid, $volname) = parse_volume_id($info->{volid});
> my $volpath = $plugin->path($scfg, $volname, $storeid);
> if ($volpath eq $path) {
> - return ('images', $info->{volid});
> + return $info->{volid};
> }
> }
>
> - return ('');
> + return;
> }
>
> - if ($path =~ m!^\Q$isodir\E/([^/]+$ISO_EXT_RE_0)$!) {
> + if ($vtype eq 'iso') {
> + return if $filename !~ m!/([^/]+$ISO_EXT_RE_0)$!;
> my $name = $1;
> - return ('iso', "$sid:iso/$name");
> + return "$sid:iso/$name";
> }
>
> - if ($path =~ m!^\Q$tmpldir\E/([^/]+$VZTMPL_EXT_RE_1)$!) {
> + if ($vtype eq 'vztmpl') {
> + return if $filename !~ m!/([^/]+$VZTMPL_EXT_RE_1)$!;
> my $name = $1;
> - return ('vztmpl', "$sid:vztmpl/$name");
> + return "$sid:vztmpl/$name";
> }
>
> - if ($path =~ m!^\Q$backupdir\E/([^/]+$BACKUP_EXT_RE_2)$!) {
> + if ($vtype eq 'backup') {
> + return if $filename !~ m!/([^/]+$BACKUP_EXT_RE_2)$!;
> my $name = $1;
> - return ('backup', "$sid:backup/$name");
> + return "$sid:backup/$name";
> }
>
> - if ($path =~ m!^\Q$snippetsdir\E/([^/]+)$!) {
> + if ($vtype eq 'snippets') {
> + return if $filename !~ m!/([^/]+)$!;
> my $name = $1;
> - return ('snippets', "$sid:snippets/$name");
> + return "$sid:snippets/$name";
> }
>
> - if ($path =~ m!^\Q$importdir\E/(${SAFE_CHAR_CLASS_RE}+${IMPORT_EXT_RE_1})$!) {
> + if ($vtype eq 'import') {
> + return if $filename !~ m!/(${SAFE_CHAR_CLASS_RE}+${IMPORT_EXT_RE_1})$!;
> my $name = $1;
> - return ('import', "$sid:import/$name");
> + return "$sid:import/$name";
> }
>
> - return ('');
> + return;
> };
>
> + my $vtypes_to_check = $get_vtypes_to_check->();
> +
> for my $sid (keys $ids->%*) {
> my $scfg = $ids->{$sid};
> next if !$scfg->{path};
> my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
>
> - my ($vtype, $volid) = $parse_volid_from_file_path->($plugin, $sid, $scfg);
> - return ($vtype, $volid) if $vtype;
> + for my $vtype ($vtypes_to_check->@*) {
> + my $volid = $parse_volid_from_file_path->($plugin, $sid, $scfg, $vtype);
> +
> + if (defined($volid)) {
> + return ($vtype, $volid);
> + }
> + }
> }
>
> # can't map path to volume id
> --
> 2.47.3
>
>
>
>
>
--
next prev parent reply other threads:[~2026-04-28 15:08 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-22 11:12 [PATCH pve-storage, pve-manager v1 00/54] Fix #2884: Implement Subdirectory Scanning for Dir-Based Storage Types Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 01/54] test: plugin tests: run tests with at most 4 jobs Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 02/54] plugin, common: remove superfluous use of =pod command paragraph Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 03/54] common: add POD headings for groups of helpers Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 04/54] common: use Exporter module for PVE::Storage::Common Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 05/54] plugin: make get_subdir_files a proper subroutine and update style Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 06/54] plugin api: replace helpers w/ standalone subs, bump API version & age Max R. Carrara
2026-04-28 15:01 ` Wolfgang Bumiller
2026-04-22 11:12 ` [PATCH pve-storage v1 07/54] common: prevent autovivification in plugin_get_vtype_subdir helper Max R. Carrara
2026-04-28 15:02 ` Wolfgang Bumiller
2026-04-22 11:12 ` [PATCH pve-storage v1 08/54] plugin: break up needless if-elsif chain into separate if-blocks Max R. Carrara
2026-04-28 15:04 ` Wolfgang Bumiller
2026-04-22 11:12 ` [PATCH pve-storage v1 09/54] plugin: adapt get_subdir_files helper of list_volumes API method Max R. Carrara
2026-04-28 15:07 ` Wolfgang Bumiller
2026-04-22 11:12 ` [PATCH pve-storage v1 10/54] plugin: update code style of list_volumes plugin " Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 11/54] plugin: use closure for obtaining raw volume data in list_volumes Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 12/54] plugin: use closure for inner loop logic " Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 13/54] storage: update code style in function path_to_volume_id Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 14/54] storage: break up needless if-elsif chain in path_to_volume_id Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 15/54] storage: heave vtype file path parsing logic inside loop into helper Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 16/54] storage: clean up code that was moved into helper in path_to_volume_id Max R. Carrara
2026-04-28 15:08 ` Wolfgang Bumiller [this message]
2026-04-22 11:12 ` [PATCH pve-storage v1 17/54] api: status: move content type assert for up-/downloads into helper Max R. Carrara
2026-04-28 15:10 ` Wolfgang Bumiller
2026-04-22 11:12 ` [PATCH pve-storage v1 18/54] api: status: use helper from common module to get content directory Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 19/54] api: status: move up-/download file path parsing code into helper Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 20/54] api: status: simplify file content assertion logic for up-/download Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 21/54] test: guest import: add tests for PVE::GuestImport Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 22/54] tree-wide: introduce parsing module and replace usages of ISO_EXT_RE_0 Max R. Carrara
2026-04-28 15:20 ` Wolfgang Bumiller
2026-04-22 11:12 ` [PATCH pve-storage v1 23/54] common: test: set up parser testing code, add tests for 'iso' vtype Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 24/54] tree-wide: replace usages of VZTMPL_EXT_RE_1 with parsing functions Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 25/54] tree-wide: replace usages of BACKUP_EXT_RE_2 " Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 26/54] tree-wide: replace usages of inline regexes for snippets with parsers Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 27/54] tree-wide: partially replace usages of regexes for 'import' vtype Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 28/54] tree-wide: replace remaining " Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 29/54] plugin: simplify recently refactored logic in parse_volname method Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 30/54] plugin: simplify recently refactored logic in get_subdir_files helper Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 31/54] storage: simplify recently refactored logic in path_to_volume_id sub Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 32/54] api: status: simplify recently added parsing helper for file transfers Max R. Carrara
2026-04-22 11:12 ` [PATCH pve-storage v1 33/54] plugin: use parsing helper in parse_volume_id sub Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 34/54] test: list volumes: reorganize and modernize test running code Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 35/54] test: list volumes: fix broken test checking for vmlist modifications Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 36/54] test: list volumes: introduce new format for test cases Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 37/54] test: list volumes: remove legacy code and migrate cases to new format Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 38/54] test: list volumes: document behavior wrt. undeclared content types Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 39/54] plugin: correct comment in get_subdir_files helper Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 40/54] test: parse volname: modernize code Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 41/54] test: parse volname: adapt tests regarding 'import' volume type Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 42/54] test: parse volname: move VM disk test creation into separate block Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 43/54] test: parse volname: move backup file test creation into sep. block Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 44/54] test: parse volname: parameterize test case creation for some vtypes Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 45/54] test: volume id: modernize code Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 46/54] test: volume id: rename 'volname' test case parameter to 'file' Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 47/54] test: filesystem path: modernize code Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 48/54] fix #2884: implement nested subdir scanning and support 'iso' vtype Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 49/54] fix #2884: support nested subdir scanning for 'vztmpl' volume type Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 50/54] fix #2884: support nested subdir scanning for 'snippets' vtype Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 51/54] test: add more tests for 'import' vtype & guard against nested subdirs Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 52/54] test: add tests guarding against subdir scanning for vtypes Max R. Carrara
2026-04-22 11:13 ` [PATCH pve-storage v1 53/54] storage api: mark old public regexes for removal, bump APIVER & APIAGE Max R. Carrara
2026-04-28 15:22 ` Wolfgang Bumiller
2026-04-22 11:13 ` [PATCH pve-manager v1 54/54] fix #2884: ui: storage: add field for 'max-scan-depth' property Max R. Carrara
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=j5ygsulsykpaevszwpuv2726r7ogzz6wd2346telm7szlqmbwl@opm2banmchnp \
--to=w.bumiller@proxmox.com \
--cc=m.carrara@proxmox.com \
--cc=pve-devel@lists.proxmox.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox