[pve-devel] [RFC pve-storage 7/7] stats: api: cache storage plugin status

Lukas Wagner l.wagner at proxmox.com
Mon Aug 21 15:44:44 CEST 2023


Cache storage plugin status so that pvestatd and API calls can use the
cached results, without having to query all storage plugins again.

Signed-off-by: Lukas Wagner <l.wagner at proxmox.com>
---
 src/PVE/API2/Storage/Config.pm | 10 +++++++++
 src/PVE/Storage.pm             | 40 ++++++++++++++++++++++++----------
 2 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/src/PVE/API2/Storage/Config.pm b/src/PVE/API2/Storage/Config.pm
index e04b6ab..8c3df99 100755
--- a/src/PVE/API2/Storage/Config.pm
+++ b/src/PVE/API2/Storage/Config.pm
@@ -16,6 +16,7 @@ use PVE::JSONSchema qw(get_standard_option);
 use PVE::RPCEnvironment;
 
 use PVE::RESTHandler;
+use PVE::RS::Cache;
 
 use base qw(PVE::RESTHandler);
 
@@ -274,6 +275,9 @@ __PACKAGE__->register_method ({
 		die $err;
 	    }
 
+	    # Remove cached plugin status on configuration changes.
+	    PVE::RS::Cache->pvestatd_cache()->delete("storage_plugin_status");
+
 	    PVE::Storage::write_config($cfg);
 
 	}, "create storage failed");
@@ -373,6 +377,9 @@ __PACKAGE__->register_method ({
 		    ." in Proxmox VE 9. Use 'create-base-path' or 'create-subdirs' instead.\n"
 	    }
 
+	    # Remove cached plugin status on configuration changes.
+	    PVE::RS::Cache->pvestatd_cache()->delete("storage_plugin_status");
+
 	    PVE::Storage::write_config($cfg);
 
 	}, "update storage failed");
@@ -422,6 +429,9 @@ __PACKAGE__->register_method ({
 
 	    delete $cfg->{ids}->{$storeid};
 
+	    # Remove cached plugin status on configuration changes.
+	    PVE::RS::Cache->pvestatd_cache()->delete("storage_plugin_status");
+
 	    PVE::Storage::write_config($cfg);
 
 	}, "delete storage failed");
diff --git a/src/PVE/Storage.pm b/src/PVE/Storage.pm
index a4d85e1..7aa3b2e 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::RESTEnvironment qw(log_warn);
+use PVE::RS::Cache;
 
 use PVE::Storage::Plugin;
 use PVE::Storage::DirPlugin;
@@ -1276,6 +1277,10 @@ sub storage_info {
 
     my $cache = {};
 
+    my $status_cache = PVE::RS::Cache->pvestatd_cache();
+    my $cached_status = $status_cache->get("storage_plugin_status");
+    my $refresh_status = !$cached_status;
+
     foreach my $storeid (keys %$ids) {
 	my $scfg = $ids->{$storeid};
 
@@ -1291,21 +1296,34 @@ sub storage_info {
 		if $pd->{select_existing};
 	}
 
-	eval { activate_storage($cfg, $storeid, $cache); };
-	if (my $err = $@) {
-	    warn $err;
-	    next;
+	if ($refresh_status) {
+	    eval { activate_storage($cfg, $storeid, $cache); };
+	    if (my $err = $@) {
+		warn $err;
+		next;
+	    }
+	    $cached_status->{$storeid} = eval { $plugin->status($storeid, $scfg, $cache); };
+
+	    my ($total, $avail, $used, $active) = eval { $plugin->status($storeid, $scfg, $cache); };
+	    warn $@ if $@;
+	    $cached_status->{$storeid} = {};
+
+	    $cached_status->{$storeid}->{total} = int($total);
+	    $cached_status->{$storeid}->{avail} = int($avail);
+	    $cached_status->{$storeid}->{used} = int($used);
+	    $cached_status->{$storeid}->{active} = $active;
+	    next if !$active;
 	}
 
-	my ($total, $avail, $used, $active) = eval { $plugin->status($storeid, $scfg, $cache); };
-	warn $@ if $@;
-	next if !$active;
-	$info->{$storeid}->{total} = int($total);
-	$info->{$storeid}->{avail} = int($avail);
-	$info->{$storeid}->{used} = int($used);
-	$info->{$storeid}->{active} = $active;
+	$info->{$storeid}->{total} = $cached_status->{$storeid}->{total};
+	$info->{$storeid}->{avail} = $cached_status->{$storeid}->{avail};
+	$info->{$storeid}->{used} = $cached_status->{$storeid}->{used};
+	$info->{$storeid}->{active} = $cached_status->{$storeid}->{active};
     }
 
+    # TODO: How long should status results be valid?
+    $status_cache->set('storage_plugin_status', $cached_status, 30) if $refresh_status;
+
     return $info;
 }
 
-- 
2.39.2






More information about the pve-devel mailing list