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 {