src/bin/proxmox-backup-client.rs: pass verbose flag to dump_image
And print some useful status to stderr.
This commit is contained in:
parent
2c2097ee75
commit
fd04ca7a5a
@ -936,6 +936,7 @@ fn dump_image<W: Write>(
|
|||||||
crypt_config: Option<Arc<CryptConfig>>,
|
crypt_config: Option<Arc<CryptConfig>>,
|
||||||
index: FixedIndexReader,
|
index: FixedIndexReader,
|
||||||
mut writer: W,
|
mut writer: W,
|
||||||
|
verbose: bool,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
|
||||||
let most_used = index.find_most_used_chunks(8);
|
let most_used = index.find_most_used_chunks(8);
|
||||||
@ -944,11 +945,33 @@ fn dump_image<W: Write>(
|
|||||||
|
|
||||||
// Note: we avoid using BufferedFixedReader, because that add an additional buffer/copy
|
// Note: we avoid using BufferedFixedReader, because that add an additional buffer/copy
|
||||||
// and thus slows down reading. Instead, directly use RemoteChunkReader
|
// and thus slows down reading. Instead, directly use RemoteChunkReader
|
||||||
|
let mut per = 0;
|
||||||
|
let mut bytes = 0;
|
||||||
|
let start_time = std::time::Instant::now();
|
||||||
|
|
||||||
for pos in 0..index.index_count() {
|
for pos in 0..index.index_count() {
|
||||||
let digest = index.index_digest(pos).unwrap();
|
let digest = index.index_digest(pos).unwrap();
|
||||||
let raw_data = chunk_reader.read_chunk(&digest)?;
|
let raw_data = chunk_reader.read_chunk(&digest)?;
|
||||||
writer.write_all(&raw_data)?;
|
writer.write_all(&raw_data)?;
|
||||||
|
bytes += raw_data.len();
|
||||||
|
if verbose {
|
||||||
|
let next_per = ((pos+1)*100)/index.index_count();
|
||||||
|
if per != next_per {
|
||||||
|
eprintln!("progress {}% (read {} bytes, duration {} sec)",
|
||||||
|
next_per, bytes, start_time.elapsed().as_secs());
|
||||||
|
per = next_per;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let end_time = std::time::Instant::now();
|
||||||
|
let elapsed = end_time.duration_since(start_time);
|
||||||
|
eprintln!("restore image complete (bytes={}, duration={:.2}s, speed={:.2}MB/s)",
|
||||||
|
bytes,
|
||||||
|
elapsed.as_secs_f64(),
|
||||||
|
bytes as f64/(1024.0*1024.0*elapsed.as_secs_f64())
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1081,13 +1104,12 @@ async fn restore_do(param: Value) -> Result<Value, Error> {
|
|||||||
let feature_flags = pxar::flags::DEFAULT;
|
let feature_flags = pxar::flags::DEFAULT;
|
||||||
let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags, |path| {
|
let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags, |path| {
|
||||||
if verbose {
|
if verbose {
|
||||||
println!("{:?}", path);
|
eprintln!("{:?}", path);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
decoder.set_allow_existing_dirs(allow_existing_dirs);
|
decoder.set_allow_existing_dirs(allow_existing_dirs);
|
||||||
|
|
||||||
|
|
||||||
decoder.restore(Path::new(target), &Vec::new())?;
|
decoder.restore(Path::new(target), &Vec::new())?;
|
||||||
} else {
|
} else {
|
||||||
let mut writer = std::fs::OpenOptions::new()
|
let mut writer = std::fs::OpenOptions::new()
|
||||||
@ -1123,7 +1145,7 @@ async fn restore_do(param: Value) -> Result<Value, Error> {
|
|||||||
.map_err(|err| format_err!("unable to open /dev/stdout - {}", err))?
|
.map_err(|err| format_err!("unable to open /dev/stdout - {}", err))?
|
||||||
};
|
};
|
||||||
|
|
||||||
dump_image(client.clone(), crypt_config.clone(), index, &mut writer)?;
|
dump_image(client.clone(), crypt_config.clone(), index, &mut writer, verbose)?;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
bail!("unknown archive file extension (expected .pxar of .img)");
|
bail!("unknown archive file extension (expected .pxar of .img)");
|
||||||
|
Loading…
Reference in New Issue
Block a user