tape: implement format/erase

This commit is contained in:
Dietmar Maurer
2021-03-31 09:19:19 +02:00
parent a79082a0dd
commit e29f456efc
10 changed files with 108 additions and 38 deletions

View File

@ -179,6 +179,10 @@ impl LtoTapeHandle {
Ok(status)
}
pub fn erase_media(&mut self, fast: bool) -> Result<(), Error> {
self.sg_tape.erase_media(fast)
}
pub fn load(&mut self) -> Result<(), Error> {
self.sg_tape.load()
}
@ -223,9 +227,8 @@ impl TapeDriver for LtoTapeHandle {
self.sg_tape.current_file_number()
}
fn erase_media(&mut self, fast: bool) -> Result<(), Error> {
self.rewind()?; // important - erase from BOT
self.sg_tape.erase_media(fast)
fn format_media(&mut self, fast: bool) -> Result<(), Error> {
self.sg_tape.format_media(fast)
}
fn read_next_file<'a>(&'a mut self) -> Result<Option<Box<dyn TapeRead + 'a>>, std::io::Error> {

View File

@ -100,9 +100,48 @@ impl SgTape {
scsi_inquiry(&mut self.file)
}
pub fn erase_media(&mut self, _fast: bool) -> Result<(), Error> {
// fixme:
unimplemented!();
/// Erase medium.
///
/// EOD is written at the current position, which marks it as end
/// of data. After the command is successfully completed, the
/// drive is positioned immediately before End Of Data (not End Of
/// Tape).
pub fn erase_media(&mut self, fast: bool) -> Result<(), Error> {
let mut sg_raw = SgRaw::new(&mut self.file, 16)?;
sg_raw.set_timeout(Self::SCSI_TAPE_DEFAULT_TIMEOUT);
let mut cmd = Vec::new();
cmd.push(0x19);
if fast {
cmd.push(0); // LONG=0
} else {
cmd.push(1); // LONG=1
}
cmd.extend(&[0, 0, 0, 0]);
sg_raw.do_command(&cmd)
.map_err(|err| format_err!("erase failed - {}", err))?;
Ok(())
}
/// Format media, single partition
pub fn format_media(&mut self, fast: bool) -> Result<(), Error> {
self.rewind()?;
let mut sg_raw = SgRaw::new(&mut self.file, 16)?;
sg_raw.set_timeout(Self::SCSI_TAPE_DEFAULT_TIMEOUT);
let mut cmd = Vec::new();
cmd.extend(&[0x04, 0, 0, 0, 0, 0]);
sg_raw.do_command(&cmd)
.map_err(|err| format_err!("erase failed - {}", err))?;
if !fast {
self.erase_media(false)?; // overwrite everything
}
Ok(())
}
pub fn rewind(&mut self) -> Result<(), Error> {

View File

@ -111,7 +111,7 @@ pub trait TapeDriver {
fn current_file_number(&mut self) -> Result<u64, Error>;
/// Completely erase the media
fn erase_media(&mut self, fast: bool) -> Result<(), Error>;
fn format_media(&mut self, fast: bool) -> Result<(), Error>;
/// Read/Open the next file
fn read_next_file<'a>(&'a mut self) -> Result<Option<Box<dyn TapeRead + 'a>>, std::io::Error>;
@ -122,11 +122,9 @@ pub trait TapeDriver {
/// Write label to tape (erase tape content)
fn label_tape(&mut self, label: &MediaLabel) -> Result<(), Error> {
self.rewind()?;
self.set_encryption(None)?;
self.erase_media(true)?;
self.format_media(true)?; // this rewinds the tape
let raw = serde_json::to_string_pretty(&serde_json::to_value(&label)?)?;

View File

@ -360,7 +360,7 @@ impl TapeDriver for VirtualTapeHandle {
}
}
fn erase_media(&mut self, _fast: bool) -> Result<(), Error> {
fn format_media(&mut self, _fast: bool) -> Result<(), Error> {
let mut status = self.load_status()?;
match status.current_tape {
Some(VirtualTapeStatus { ref name, ref mut pos }) => {