tape: implement format/erase
This commit is contained in:
@ -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> {
|
||||
|
@ -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> {
|
||||
|
@ -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)?)?;
|
||||
|
||||
|
@ -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 }) => {
|
||||
|
Reference in New Issue
Block a user