From 77c2e4668b9aefcb817d2164d3a4bd4df7a2bd39 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Mon, 18 Oct 2021 14:52:27 +0200 Subject: [PATCH] proxmox-rrd: use fine grained locking in commit_journal_impl Aquire the rrd_map lock for each file (else we block access for a long time) --- proxmox-rrd/src/cache.rs | 18 +++++++++++++++++- proxmox-rrd/src/cache/rrd_map.rs | 31 ++++++++++++++----------------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/proxmox-rrd/src/cache.rs b/proxmox-rrd/src/cache.rs index 0fd49d72..faeae89f 100644 --- a/proxmox-rrd/src/cache.rs +++ b/proxmox-rrd/src/cache.rs @@ -152,6 +152,7 @@ impl RRDCache { let state = Arc::clone(&self.state); let rrd_map = Arc::clone(&self.rrd_map); + let mut state_guard = self.state.write().unwrap(); let journal_applied = state_guard.journal_applied; @@ -372,8 +373,23 @@ fn commit_journal_impl( rrd_map: Arc>, ) -> Result { + let files = rrd_map.read().unwrap().file_list(); + + let mut rrd_file_count = 0; + let mut errors = 0; + // save all RRDs - we only need a read lock here - let rrd_file_count = rrd_map.read().unwrap().flush_rrd_files()?; + for rel_path in files.iter() { + rrd_file_count += 1; + if let Err(err) = rrd_map.read().unwrap().flush_rrd_file(&rel_path) { + errors += 1; + log::error!("unable to save rrd {}: {}", rel_path, err); + } + } + + if errors != 0 { + bail!("errors during rrd flush - unable to commit rrd journal"); + } // if everything went ok, remove the old journal files state.write().unwrap().remove_old_journals()?; diff --git a/proxmox-rrd/src/cache/rrd_map.rs b/proxmox-rrd/src/cache/rrd_map.rs index 27c5ae1c..c271c075 100644 --- a/proxmox-rrd/src/cache/rrd_map.rs +++ b/proxmox-rrd/src/cache/rrd_map.rs @@ -60,27 +60,24 @@ impl RRDMap { Ok(()) } - pub fn flush_rrd_files(&self) -> Result { - let mut rrd_file_count = 0; + pub fn file_list(&self) -> Vec { + let mut list = Vec::new(); - let mut errors = 0; - for (rel_path, rrd) in self.map.iter() { - rrd_file_count += 1; - - let mut path = self.config.basedir.clone(); - path.push(&rel_path); - - if let Err(err) = rrd.save(&path, self.config.file_options.clone()) { - errors += 1; - log::error!("unable to save {:?}: {}", path, err); - } + for rel_path in self.map.keys() { + list.push(rel_path.clone()); } - if errors != 0 { - bail!("errors during rrd flush - unable to commit rrd journal"); - } + list + } - Ok(rrd_file_count) + pub fn flush_rrd_file(&self, rel_path: &str) -> Result<(), Error> { + if let Some(rrd) = self.map.get(rel_path) { + let mut path = self.config.basedir.clone(); + path.push(rel_path); + rrd.save(&path, self.config.file_options.clone()) + } else { + bail!("rrd file {} not loaded", rel_path); + } } pub fn extract_cached_data( -- 2.39.5