From 20cc25d74974a3dee998431702f96a6adb552f1f Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Tue, 23 Mar 2021 13:34:58 +0100 Subject: [PATCH] tape: add TapeDriver::move_to_last_file --- src/tape/drive/linux_tape.rs | 17 +++++++++++++++++ src/tape/drive/mod.rs | 3 +++ src/tape/drive/virtual_tape.rs | 23 +++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/src/tape/drive/linux_tape.rs b/src/tape/drive/linux_tape.rs index b5cded05..7f18295d 100644 --- a/src/tape/drive/linux_tape.rs +++ b/src/tape/drive/linux_tape.rs @@ -467,6 +467,23 @@ impl TapeDriver for LinuxTapeHandle { Ok(()) } + fn move_to_last_file(&mut self) -> Result<(), Error> { + + let cmd = mtop { mt_op: MTCmd::MTEOM, mt_count: 1, }; + + unsafe { + mtioctop(self.file.as_raw_fd(), &cmd) + }.map_err(|err| format_err!("MTEOM failed - {}", err))?; + + let cmd = mtop { mt_op: MTCmd::MTBSFM, mt_count: 2, }; + + unsafe { + mtioctop(self.file.as_raw_fd(), &cmd) + }.map_err(|err| format_err!("MTBSFM failed - {}", err))?; + + Ok(()) + } + fn rewind(&mut self) -> Result<(), Error> { let cmd = mtop { mt_op: MTCmd::MTREW, mt_count: 1, }; diff --git a/src/tape/drive/mod.rs b/src/tape/drive/mod.rs index 1267a481..afc0218c 100644 --- a/src/tape/drive/mod.rs +++ b/src/tape/drive/mod.rs @@ -87,6 +87,9 @@ pub trait TapeDriver { /// We assume this flushes the tape write buffer. fn move_to_eom(&mut self) -> Result<(), Error>; + /// Move to last file + fn move_to_last_file(&mut self) -> Result<(), Error>; + /// Current file number fn current_file_number(&mut self) -> Result; diff --git a/src/tape/drive/virtual_tape.rs b/src/tape/drive/virtual_tape.rs index 6dcf31fb..7617c062 100644 --- a/src/tape/drive/virtual_tape.rs +++ b/src/tape/drive/virtual_tape.rs @@ -305,6 +305,29 @@ impl TapeDriver for VirtualTapeHandle { } } + fn move_to_last_file(&mut self) -> Result<(), Error> { + let mut status = self.load_status()?; + match status.current_tape { + Some(VirtualTapeStatus { ref name, ref mut pos }) => { + + let index = self.load_tape_index(name) + .map_err(|err| io::Error::new(io::ErrorKind::Other, err.to_string()))?; + + if index.files == 0 { + bail!("move_to_last_file failed - media contains no data"); + } + + *pos = index.files - 1; + + self.store_status(&status) + .map_err(|err| io::Error::new(io::ErrorKind::Other, err.to_string()))?; + + Ok(()) + } + None => bail!("drive is empty (no tape loaded)."), + } + } + fn rewind(&mut self) -> Result<(), Error> { let mut status = self.load_status()?; match status.current_tape {