From e9573e1db57d802d7106d064e8ff8c0f53549992 Mon Sep 17 00:00:00 2001 From: Friedrich Weber Date: Fri, 31 Oct 2025 11:36:08 +0100 Subject: [PATCH] plugin: introduce hints for activating and mapping volumes Currently, when a storage plugin activates or maps a guest volume, it has no information about the respective guest. This is by design to reduce coupling between the storage layer and the upper layers. However, in some cases, storage plugins may need to activate volumes differently based on certain features of the guest. An example is the RBD plugin with KRBD enabled, where guest volumes of Windows VMs have to be mapped with the rxbounce option. Introduce "hints" as a mechanism that allows the upper layers to pass down well-defined information to the storage plugins on volume activation/mapping. The storage plugin can make adjustments to its volume activation/mapping based on the hints. The supported hints are specified by a JSON schema and may be extended in the future. Add a subroutine that checks whether a particular hint is supported (may be used by the storage plugin as well as upper layers). This allows to add further hints without having to bump pve-storage, since upper layers can just check whether the current pve-storage supports a particular hint. The Boolean 'guest-is-windows' hint denotes that the to-be-activated/mapped volume belongs to a Windows VM. It is not guaranteed that the volume is inactive when {activate,map}_volume are called, and it is not guaranteed that hints are passed on every storage activation. Hence, it can happen that a volume is already active but applying the hint would require unmapping the volume and mapping it again with the hint applied (this is the case for rxbounce). To cover such cases, the Boolean hint 'plugin-may-deactivate-volume' denotes whether unmapping the volume is currently safe. Only if this hint is true, the plugin may deactivate the volume and map it again with the hint applied. Signed-off-by: Friedrich Weber Link: https://lore.proxmox.com/20251031103709.60233-2-f.weber@proxmox.com --- src/PVE/Storage/Plugin.pm | 43 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/PVE/Storage/Plugin.pm b/src/PVE/Storage/Plugin.pm index 83c3980..d05c8db 100644 --- a/src/PVE/Storage/Plugin.pm +++ b/src/PVE/Storage/Plugin.pm @@ -59,6 +59,25 @@ cfs_register_file( sub { __PACKAGE__->write_config(@_); }, ); +our $hints_properties = { + 'guest-is-windows' => { + type => 'boolean', + optional => 1, + description => "true if the volume belongs to a Windows VM guest", + }, + 'plugin-may-deactivate-volume' => { + type => 'boolean', + optional => 1, + description => "true if the plugin may deactivate the volume in order to apply a hint", + }, +}; + +our $hints_format = { + type => 'object', + additionalProperties => 0, + properties => $hints_properties, +}; + my %prune_option = ( optional => 1, type => 'integer', @@ -614,6 +633,26 @@ sub preallocation_cmd_opt { return; } +sub is_hint_supported { + my ($hint) = @_; + + return defined($hints_properties->{$hint}); +} + +sub verify_hints { + my ($hints, $noerr) = @_; + + return if !defined($hints); + + eval { PVE::JSONSchema::validate($hints, $hints_format); }; + my $err = $@; + + return $hints if !$err; + return if $noerr; + + die "internal error - hints are not valid: $@"; +} + # Storage implementation =head3 get_formats @@ -1871,7 +1910,7 @@ sub deactivate_storage { } sub map_volume { - my ($class, $storeid, $scfg, $volname, $snapname) = @_; + my ($class, $storeid, $scfg, $volname, $snapname, $hints) = @_; my ($path) = $class->path($scfg, $volname, $storeid, $snapname); return $path; @@ -1884,7 +1923,7 @@ sub unmap_volume { } sub activate_volume { - my ($class, $storeid, $scfg, $volname, $snapname, $cache) = @_; + my ($class, $storeid, $scfg, $volname, $snapname, $cache, $hints) = @_; my $path = $class->filesystem_path($scfg, $volname, $snapname);