[thin_check (rust)] factor out spawn_progress_thread

This commit is contained in:
Joe Thornber
2020-08-18 09:48:51 +01:00
parent e8d7e5cf1e
commit 239ae6b6ec
2 changed files with 48 additions and 40 deletions

View File

@@ -91,7 +91,7 @@ fn main() {
report report
}; };
if let Err(reason) = check(&opts) { if let Err(reason) = check(opts) {
println!("Application error: {}", reason); println!("Application error: {}", reason);
process::exit(1); process::exit(1);
} }

View File

@@ -2,7 +2,7 @@ use anyhow::{anyhow, Result};
use nom::{number::complete::*, IResult}; use nom::{number::complete::*, IResult};
use std::path::Path; use std::path::Path;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::thread; use std::thread::{self, JoinHandle};
use threadpool::ThreadPool; use threadpool::ThreadPool;
use crate::checksum; use crate::checksum;
@@ -191,7 +191,7 @@ fn check_space_map(
for n in 0..entries.len() { for n in 0..entries.len() {
let b = &blocks[n]; let b = &blocks[n];
if checksum::metadata_block_type(&b.get_data()) != checksum::BT::BITMAP { if checksum::metadata_block_type(&b.get_data()) != checksum::BT::BITMAP {
return Err(anyhow!( report.fatal(&format!(
"Index entry points to block ({}) that isn't a bitmap", "Index entry points to block ({}) that isn't a bitmap",
b.loc b.loc
)); ));
@@ -234,9 +234,6 @@ fn check_space_map(
)); ));
} }
if fail {
return Err(anyhow!("Inconsistent data space map"));
}
Ok(()) Ok(())
} }
@@ -260,11 +257,50 @@ pub struct ThinCheckOptions<'a> {
pub report: Arc<Report>, pub report: Arc<Report>,
} }
pub fn check(opts: &ThinCheckOptions) -> Result<()> { fn spawn_progress_thread(
let report = opts.report.clone(); sm: Arc<Mutex<SpaceMap + Send>>,
let engine: Arc<dyn IoEngine + Send + Sync>; nr_allocated_metadata: u64,
report: Arc<Report>,
) -> Result<(JoinHandle<()>, Arc<Mutex<bool>>)> {
let tid;
let stop_progress = Arc::new(Mutex::new(false));
{
let stop_progress = stop_progress.clone();
tid = thread::spawn(move || {
let interval = std::time::Duration::from_millis(250);
loop {
{
let stop_progress = stop_progress.lock().unwrap();
if *stop_progress {
break;
}
}
let sm = sm.lock().unwrap();
let mut n = sm.get_nr_allocated().unwrap();
drop(sm);
n *= 100;
n /= nr_allocated_metadata;
let _r = report.progress(n as u8);
thread::sleep(interval);
}
});
}
Ok((tid, stop_progress))
}
pub fn check(opts: ThinCheckOptions) -> Result<()> {
let report = opts.report;
report.set_title("Checking thin metadata");
let engine: Arc<dyn IoEngine + Send + Sync>;
let nr_threads; let nr_threads;
if opts.async_io { if opts.async_io {
nr_threads = std::cmp::min(4, num_cpus::get()); nr_threads = std::cmp::min(4, num_cpus::get());
engine = Arc::new(AsyncIoEngine::new(opts.dev, MAX_CONCURRENT_IO)?); engine = Arc::new(AsyncIoEngine::new(opts.dev, MAX_CONCURRENT_IO)?);
@@ -289,37 +325,9 @@ pub fn check(opts: &ThinCheckOptions) -> Result<()> {
let nr_devs = devs.len(); let nr_devs = devs.len();
let metadata_sm = core_sm(engine.get_nr_blocks(), nr_devs as u32); let metadata_sm = core_sm(engine.get_nr_blocks(), nr_devs as u32);
report.set_title("Checking thin metadata"); // Kick off the thread that updates the progress
let (tid, stop_progress) =
let tid; spawn_progress_thread(metadata_sm.clone(), nr_allocated_metadata, report.clone())?;
let stop_progress = Arc::new(Mutex::new(false));
{
let report = report.clone();
let sm = metadata_sm.clone();
let stop_progress = stop_progress.clone();
tid = thread::spawn(move || {
let interval = std::time::Duration::from_millis(250);
loop {
{
let stop_progress = stop_progress.lock().unwrap();
if *stop_progress {
break;
}
}
let sm = sm.lock().unwrap();
let mut n = sm.get_nr_allocated().unwrap();
drop(sm);
n *= 100;
n /= nr_allocated_metadata;
let _r = report.progress(n as u8);
thread::sleep(interval);
}
});
}
report.set_sub_title("device details tree"); report.set_sub_title("device details tree");
let _devs = btree_to_map_with_sm::<DeviceDetail>( let _devs = btree_to_map_with_sm::<DeviceDetail>(