TapeRead: add skip_data()

This commit is contained in:
Dietmar Maurer 2021-04-13 13:11:44 +02:00
parent 629103d60c
commit 90461b76fb
4 changed files with 40 additions and 10 deletions

View File

@ -525,7 +525,7 @@ fn restore_archive<'a>(
} }
} }
reader.skip_to_end()?; // read all data reader.skip_data()?; // read all data
if let Ok(false) = reader.is_incomplete() { if let Ok(false) = reader.is_incomplete() {
catalog.register_snapshot(Uuid::from(header.uuid), current_file_number, &datastore_name, &snapshot)?; catalog.register_snapshot(Uuid::from(header.uuid), current_file_number, &datastore_name, &snapshot)?;
catalog.commit_if_large()?; catalog.commit_if_large()?;
@ -566,7 +566,7 @@ fn restore_archive<'a>(
task_log!(worker, "skipping..."); task_log!(worker, "skipping...");
} }
reader.skip_to_end()?; // read all data reader.skip_data()?; // read all data
} }
PROXMOX_BACKUP_CATALOG_ARCHIVE_MAGIC_1_0 => { PROXMOX_BACKUP_CATALOG_ARCHIVE_MAGIC_1_0 => {
let header_data = reader.read_exact_allocated(header.size as usize)?; let header_data = reader.read_exact_allocated(header.size as usize)?;
@ -576,7 +576,7 @@ fn restore_archive<'a>(
task_log!(worker, "File {}: skip catalog '{}'", current_file_number, archive_header.uuid); task_log!(worker, "File {}: skip catalog '{}'", current_file_number, archive_header.uuid);
reader.skip_to_end()?; // read all data reader.skip_data()?; // read all data
} }
_ => bail!("unknown content magic {:?}", header.content_magic), _ => bail!("unknown content magic {:?}", header.content_magic),
} }
@ -849,7 +849,7 @@ pub fn fast_catalog_restore(
if &archive_header.media_set_uuid != media_set.uuid() { if &archive_header.media_set_uuid != media_set.uuid() {
task_log!(worker, "skipping unrelated catalog at pos {}", current_file_number); task_log!(worker, "skipping unrelated catalog at pos {}", current_file_number);
reader.skip_to_end()?; // read all data reader.skip_data()?; // read all data
continue; continue;
} }
@ -868,7 +868,7 @@ pub fn fast_catalog_restore(
if !wanted { if !wanted {
task_log!(worker, "skip catalog because media '{}' not inventarized", catalog_uuid); task_log!(worker, "skip catalog because media '{}' not inventarized", catalog_uuid);
reader.skip_to_end()?; // read all data reader.skip_data()?; // read all data
continue; continue;
} }
@ -878,7 +878,7 @@ pub fn fast_catalog_restore(
// only restore if catalog does not exist // only restore if catalog does not exist
if MediaCatalog::exists(status_path, catalog_uuid) { if MediaCatalog::exists(status_path, catalog_uuid) {
task_log!(worker, "catalog for media '{}' already exists", catalog_uuid); task_log!(worker, "catalog for media '{}' already exists", catalog_uuid);
reader.skip_to_end()?; // read all data reader.skip_data()?; // read all data
continue; continue;
} }
} }

View File

@ -622,8 +622,15 @@ fn debug_scan(mut param: Value) -> Result<(), Error> {
println!("unable to read content header - {}", err); println!("unable to read content header - {}", err);
} }
} }
let bytes = reader.skip_to_end()?; let bytes = reader.skip_data()?;
println!("skipped {}", HumanByte::from(bytes)); println!("skipped {}", HumanByte::from(bytes));
if let Ok(true) = reader.has_end_marker() {
if reader.is_incomplete()? {
println!("WARNING: file is incomplete");
}
} else {
println!("WARNING: file without end marker");
}
} }
} }
} }

View File

@ -129,14 +129,14 @@ impl <R: BlockRead> BlockedReader<R> {
} }
} }
fn read_block(&mut self) -> Result<usize, std::io::Error> { fn read_block(&mut self, check_end_marker: bool) -> Result<usize, std::io::Error> {
match Self::read_block_frame(&mut self.buffer, &mut self.reader) { match Self::read_block_frame(&mut self.buffer, &mut self.reader) {
Ok(()) => { /* ok */ } Ok(()) => { /* ok */ }
Err(BlockReadError::EndOfFile) => { Err(BlockReadError::EndOfFile) => {
self.got_eod = true; self.got_eod = true;
self.read_pos = self.buffer.payload.len(); self.read_pos = self.buffer.payload.len();
if !self.found_end_marker { if !self.found_end_marker && check_end_marker {
proxmox::io_bail!("detected tape stream without end marker"); proxmox::io_bail!("detected tape stream without end marker");
} }
return Ok(0); // EOD return Ok(0); // EOD
@ -185,6 +185,23 @@ impl <R: BlockRead> TapeRead for BlockedReader<R> {
Ok(self.found_end_marker) Ok(self.found_end_marker)
} }
// like ReadExt::skip_to_end(), but does not raise an error if the
// stream has no end marker.
fn skip_data(&mut self) -> Result<usize, std::io::Error> {
let mut bytes = 0;
let buffer_size = self.buffer.size();
let rest = (buffer_size as isize) - (self.read_pos as isize);
if rest > 0 {
bytes = rest as usize;
}
loop {
if self.got_eod {
return Ok(bytes);
}
bytes += self.read_block(false)?;
}
}
} }
impl <R: BlockRead> Read for BlockedReader<R> { impl <R: BlockRead> Read for BlockedReader<R> {
@ -199,7 +216,7 @@ impl <R: BlockRead> Read for BlockedReader<R> {
let mut rest = (buffer_size as isize) - (self.read_pos as isize); let mut rest = (buffer_size as isize) - (self.read_pos as isize);
if rest <= 0 && !self.got_eod { // try to refill buffer if rest <= 0 && !self.got_eod { // try to refill buffer
buffer_size = match self.read_block() { buffer_size = match self.read_block(true) {
Ok(len) => len, Ok(len) => len,
err => { err => {
self.read_error = true; self.read_error = true;

View File

@ -13,6 +13,12 @@ pub trait TapeRead: Read {
/// ///
/// Raises an error if you query this flag before reaching EOF. /// Raises an error if you query this flag before reaching EOF.
fn has_end_marker(&self) -> Result<bool, std::io::Error>; fn has_end_marker(&self) -> Result<bool, std::io::Error>;
/// Skip data by reading to EOF (position after EOF marker)
///
// Returns the number of bytes skipped. This does not raise an
// error if the stream has no end marker.
fn skip_data(&mut self) -> Result<usize, std::io::Error>;
} }
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]