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)
This commit is contained in:
Dietmar Maurer 2021-10-18 14:52:27 +02:00
parent c17fbbbc07
commit 7f381a6246
2 changed files with 31 additions and 18 deletions

View File

@ -152,6 +152,7 @@ impl RRDCache {
let state = Arc::clone(&self.state); let state = Arc::clone(&self.state);
let rrd_map = Arc::clone(&self.rrd_map); let rrd_map = Arc::clone(&self.rrd_map);
let mut state_guard = self.state.write().unwrap(); let mut state_guard = self.state.write().unwrap();
let journal_applied = state_guard.journal_applied; let journal_applied = state_guard.journal_applied;
@ -372,8 +373,23 @@ fn commit_journal_impl(
rrd_map: Arc<RwLock<RRDMap>>, rrd_map: Arc<RwLock<RRDMap>>,
) -> Result<usize, Error> { ) -> Result<usize, Error> {
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 // 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 // if everything went ok, remove the old journal files
state.write().unwrap().remove_old_journals()?; state.write().unwrap().remove_old_journals()?;

View File

@ -60,29 +60,26 @@ impl RRDMap {
Ok(()) Ok(())
} }
pub fn flush_rrd_files(&self) -> Result<usize, Error> { pub fn file_list(&self) -> Vec<String> {
let mut rrd_file_count = 0; let mut list = Vec::new();
let mut errors = 0; for rel_path in self.map.keys() {
for (rel_path, rrd) in self.map.iter() { list.push(rel_path.clone());
rrd_file_count += 1; }
list
}
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(); let mut path = self.config.basedir.clone();
path.push(&rel_path); path.push(rel_path);
rrd.save(&path, self.config.file_options.clone())
if let Err(err) = rrd.save(&path, self.config.file_options.clone()) { } else {
errors += 1; bail!("rrd file {} not loaded", rel_path);
log::error!("unable to save {:?}: {}", path, err);
} }
} }
if errors != 0 {
bail!("errors during rrd flush - unable to commit rrd journal");
}
Ok(rrd_file_count)
}
pub fn extract_cached_data( pub fn extract_cached_data(
&self, &self,
base: &str, base: &str,