all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Hannes Laimer <h.laimer@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox-backup v5 02/22] datastore: add cache entry flag for droping it after last task
Date: Wed, 17 Apr 2024 14:23:42 +0200	[thread overview]
Message-ID: <20240417122402.51956-3-h.laimer@proxmox.com> (raw)
In-Reply-To: <20240417122402.51956-1-h.laimer@proxmox.com>

... this allows us to keep track of which datastores are in the
process of being removed. Also, let's us avoid reading the config on
every drop of a DataStore reference.

Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
---
 pbs-datastore/src/datastore.rs | 60 +++++++++++++++-------------------
 src/api2/config/datastore.rs   |  8 +++--
 2 files changed, 31 insertions(+), 37 deletions(-)

diff --git a/pbs-datastore/src/datastore.rs b/pbs-datastore/src/datastore.rs
index 0685cc84..a7fe3b8c 100644
--- a/pbs-datastore/src/datastore.rs
+++ b/pbs-datastore/src/datastore.rs
@@ -34,7 +34,7 @@ use crate::task_tracking::{self, update_active_operations};
 use crate::DataBlob;
 
 lazy_static! {
-    static ref DATASTORE_MAP: Mutex<HashMap<String, Arc<DataStoreImpl>>> =
+    static ref DATASTORE_MAP: Mutex<HashMap<String, (Arc<DataStoreImpl>, bool)>> =
         Mutex::new(HashMap::new());
 }
 
@@ -111,24 +111,15 @@ impl Drop for DataStore {
                     last_task = updated_operations.read + updated_operations.write == 0;
                 }
             }
-
-            // remove datastore from cache iff
-            //  - last task finished, and
-            //  - datastore is in a maintenance mode that mandates it
-            let remove_from_cache = last_task
-                && pbs_config::datastore::config()
-                    .and_then(|(s, _)| s.lookup::<DataStoreConfig>("datastore", self.name()))
-                    .map_or(false, |c| {
-                        c.get_maintenance_mode().map_or(false, |m| m.is_offline())
-                    });
-
-            if remove_from_cache {
-                DATASTORE_MAP.lock().unwrap().remove(self.name());
+            if last_task {
+                let mut cache = DATASTORE_MAP.lock().unwrap();
+                if let Some((_, true)) = cache.get(self.name()) {
+                    cache.remove(self.name());
+                }
             }
         }
     }
 }
-
 impl DataStore {
     // This one just panics on everything
     #[doc(hidden)]
@@ -169,7 +160,7 @@ impl DataStore {
         let entry = datastore_cache.get(name);
 
         // reuse chunk store so that we keep using the same process locker instance!
-        let chunk_store = if let Some(datastore) = &entry {
+        let (chunk_store, drop_from_cache) = if let Some((datastore, drop_from_cache)) = &entry {
             let last_digest = datastore.last_digest.as_ref();
             if let Some(true) = last_digest.map(|last_digest| last_digest == &digest) {
                 return Ok(Arc::new(Self {
@@ -177,23 +168,26 @@ impl DataStore {
                     operation,
                 }));
             }
-            Arc::clone(&datastore.chunk_store)
+            (Arc::clone(&datastore.chunk_store), *drop_from_cache)
         } else {
             let tuning: DatastoreTuning = serde_json::from_value(
                 DatastoreTuning::API_SCHEMA
                     .parse_property_string(config.tuning.as_deref().unwrap_or(""))?,
             )?;
-            Arc::new(ChunkStore::open(
-                name,
-                &config.path,
-                tuning.sync_level.unwrap_or_default(),
-            )?)
+            (
+                Arc::new(ChunkStore::open(
+                    name,
+                    &config.path,
+                    tuning.sync_level.unwrap_or_default(),
+                )?),
+                false,
+            )
         };
 
         let datastore = DataStore::with_store_and_config(chunk_store, config, Some(digest))?;
 
         let datastore = Arc::new(datastore);
-        datastore_cache.insert(name.to_string(), datastore.clone());
+        datastore_cache.insert(name.to_string(), (datastore.clone(), drop_from_cache));
 
         Ok(Arc::new(Self {
             inner: datastore,
@@ -211,20 +205,18 @@ impl DataStore {
         Ok(())
     }
 
-    /// trigger clearing cache entry based on maintenance mode. Entry will only
-    /// be cleared iff there is no other task running, if there is, the end of the
+    /// trigger clearing of cache entry. Entry will only be cleared iff
+    /// there is no other task running, if there is, the end of the
     /// last running task will trigger the clearing of the cache entry.
     pub fn update_datastore_cache(name: &str) -> Result<(), Error> {
-        let (config, _digest) = pbs_config::datastore::config()?;
-        let datastore: DataStoreConfig = config.lookup("datastore", name)?;
-        if datastore
-            .get_maintenance_mode()
-            .map_or(false, |m| m.is_offline())
-        {
-            // the datastore drop handler does the checking if tasks are running and clears the
-            // cache entry, so we just have to trigger it here
-            let _ = DataStore::lookup_datastore(name, Some(Operation::Lookup));
+        let _store = DataStore::lookup_datastore(name, Some(Operation::Lookup));
+
+        let mut datastore_cache = DATASTORE_MAP.lock().unwrap();
+        if let Some((_, drop_from_cache)) = datastore_cache.get_mut(name) {
+            *drop_from_cache = true;
         }
+        drop(datastore_cache);
+        drop(_store);
 
         Ok(())
     }
diff --git a/src/api2/config/datastore.rs b/src/api2/config/datastore.rs
index 3081e1f4..0b3d92f9 100644
--- a/src/api2/config/datastore.rs
+++ b/src/api2/config/datastore.rs
@@ -389,10 +389,12 @@ pub fn update_datastore(
         data.tuning = update.tuning;
     }
 
-    let mut maintenance_mode_changed = false;
+    let mut drop_store_from_cache = false;
     if update.maintenance_mode.is_some() {
-        maintenance_mode_changed = data.maintenance_mode != update.maintenance_mode;
         data.maintenance_mode = update.maintenance_mode;
+        drop_store_from_cache = data
+            .get_maintenance_mode()
+            .map_or(false, |m| m.is_offline());
     }
 
     config.set_data(&name, "datastore", &data)?;
@@ -406,7 +408,7 @@ pub fn update_datastore(
     }
 
     // tell the proxy it might have to clear a cache entry
-    if maintenance_mode_changed {
+    if drop_store_from_cache {
         tokio::spawn(async move {
             if let Ok(proxy_pid) =
                 proxmox_rest_server::read_pid(pbs_buildcfg::PROXMOX_BACKUP_PROXY_PID_FN)
-- 
2.39.2



_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel


  parent reply	other threads:[~2024-04-17 12:24 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-17 12:23 [pbs-devel] [PATCH proxmox-backup v5 00/22] add removable datastores Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 01/22] tools: add disks utility functions Hannes Laimer
2024-04-17 12:23 ` Hannes Laimer [this message]
2024-04-18  5:12   ` [pbs-devel] [PATCH proxmox-backup v5 02/22] datastore: add cache entry flag for droping it after last task Thomas Lamprecht
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 03/22] pbs-api-types: add backing-device to DataStoreConfig Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 04/22] disks: add UUID to partition info Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 05/22] add helper for checking if a removable datastore is available Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 06/22] api2: admin: add (un)mount endpoint for removable datastores Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 07/22] api2: removable datastore creation Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 08/22] api2: disks list: add only-unused flag Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 09/22] pbs-api-types: use SchemaDeserializer for maintenance mode Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 10/22] pbs-api-types: add removable/is-available flag to DataStoreListItem Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 11/22] bin: manager: add (un)mount command Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 12/22] add auto-mounting for removable datastores Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 13/22] datastore: handle deletion of removable datastore properly Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 14/22] docs: add removable datastores section Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 15/22] ui: add partition selector form Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 16/22] ui: add removable datastore creation support Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 17/22] ui: add (un)mount button to summary Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 18/22] ui: display removable datastores in list Hannes Laimer
2024-04-17 12:23 ` [pbs-devel] [PATCH proxmox-backup v5 19/22] ui: utils: render unplugged datastores correctly Hannes Laimer
2024-04-17 12:24 ` [pbs-devel] [PATCH proxmox-backup v5 20/22] ui: utils: make parseMaintenanceMode more robust Hannes Laimer
2024-04-17 12:24 ` [pbs-devel] [PATCH proxmox-backup v5 21/22] ui: add datastore status mask for unplugged removable datastores Hannes Laimer
2024-04-17 12:24 ` [pbs-devel] [PATCH proxmox-backup v5 22/22] ui: maintenance: fix disable msg field if no type is selected Hannes Laimer

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=20240417122402.51956-3-h.laimer@proxmox.com \
    --to=h.laimer@proxmox.com \
    --cc=pbs-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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal