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:
		| @ -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<RwLock<RRDMap>>, | ||||
| ) -> 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 | ||||
|     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()?; | ||||
|  | ||||
							
								
								
									
										31
									
								
								proxmox-rrd/src/cache/rrd_map.rs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										31
									
								
								proxmox-rrd/src/cache/rrd_map.rs
									
									
									
									
										vendored
									
									
								
							| @ -60,27 +60,24 @@ impl RRDMap { | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     pub fn flush_rrd_files(&self) -> Result<usize, Error> { | ||||
|         let mut rrd_file_count = 0; | ||||
|     pub fn file_list(&self) -> Vec<String> { | ||||
|         let mut list = Vec::new(); | ||||
|  | ||||
|         let mut errors = 0; | ||||
|         for (rel_path, rrd) in self.map.iter() { | ||||
|             rrd_file_count += 1; | ||||
|         for rel_path in self.map.keys() { | ||||
|             list.push(rel_path.clone()); | ||||
|         } | ||||
|  | ||||
|         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(); | ||||
|             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); | ||||
|             } | ||||
|             path.push(rel_path); | ||||
|             rrd.save(&path, self.config.file_options.clone()) | ||||
|         } else { | ||||
|             bail!("rrd file {} not loaded", rel_path); | ||||
|         } | ||||
|  | ||||
|         if errors != 0 { | ||||
|             bail!("errors during rrd flush - unable to commit rrd journal"); | ||||
|         } | ||||
|  | ||||
|         Ok(rrd_file_count) | ||||
|     } | ||||
|  | ||||
|     pub fn extract_cached_data( | ||||
|  | ||||
		Reference in New Issue
	
	Block a user