sys::error::SysResult,
};
+use pbs_api_types::Fingerprint;
+use pbs_config::key_config::KeyConfig;
+use pbs_tools::run_command;
+
use crate::{
config,
- tools::run_command,
- backup::{
- Fingerprint,
- KeyConfig,
- },
api2::types::{
MamAttribute,
LtoDriveAndMediaStatus,
LtoTapeDrive,
+ Lp17VolumeStatistics,
},
tape::{
TapeRead,
TapeWrite,
+ BlockReadError,
drive::{
TapeDriver,
- TapeAlertFlags,
- Lp17VolumeStatistics,
- mam_extract_media_usage,
},
file_formats::{
PROXMOX_BACKUP_MEDIA_SET_LABEL_MAGIC_1_0,
},
};
-impl LtoTapeDrive {
-
- /// Open a tape device
- ///
- /// This does additional checks:
- ///
- /// - check if it is a non-rewinding tape device
- /// - check if drive is ready (tape loaded)
- /// - check block size
- /// - for autoloader only, try to reload ejected tapes
- pub fn open(&self) -> Result<LtoTapeHandle, Error> {
+/// Open a tape device
+///
+/// This does additional checks:
+///
+/// - check if it is a non-rewinding tape device
+/// - check if drive is ready (tape loaded)
+/// - check block size
+/// - for autoloader only, try to reload ejected tapes
+pub fn open_lto_tape_drive(config: &LtoTapeDrive) -> Result<LtoTapeHandle, Error> {
- proxmox::try_block!({
- let file = open_lto_tape_device(&self.path)?;
+ proxmox::try_block!({
+ let file = open_lto_tape_device(&config.path)?;
- let mut handle = LtoTapeHandle::new(file)?;
+ let mut handle = LtoTapeHandle::new(file)?;
- if !handle.sg_tape.test_unit_ready().is_ok() {
- // for autoloader only, try to reload ejected tapes
- if self.changer.is_some() {
- let _ = handle.sg_tape.load(); // just try, ignore error
- }
+ if !handle.sg_tape.test_unit_ready().is_ok() {
+ // for autoloader only, try to reload ejected tapes
+ if config.changer.is_some() {
+ let _ = handle.sg_tape.load(); // just try, ignore error
}
+ }
- handle.sg_tape.wait_until_ready()?;
+ handle.sg_tape.wait_until_ready()?;
- handle.set_default_options()?;
+ handle.set_default_options()?;
- Ok(handle)
- }).map_err(|err: Error| format_err!("open drive '{}' ({}) failed - {}", self.name, self.path, err))
- }
+ Ok(handle)
+ }).map_err(|err: Error| format_err!("open drive '{}' ({}) failed - {}", config.name, config.path, err))
}
/// Lto Tape device handle
.ok();
let mut status = LtoDriveAndMediaStatus {
+ vendor: self.sg_tape.info().vendor.clone(),
+ product: self.sg_tape.info().product.clone(),
+ revision: self.sg_tape.info().revision.clone(),
blocksize: drive_status.block_length,
compression: drive_status.compression,
buffer_mode: drive_status.buffer_mode,
}
/// Position the tape after filemark count. Count 0 means BOT.
- ///
- /// Note: we dont use LOCATE(10), because that needs LTO5
pub fn locate_file(&mut self, position: u64) -> Result<(), Error> {
-
- if position == 0 {
- return self.rewind();
- }
-
- let current_position = self.current_file_number()?;
-
- if current_position == position {
- // make sure we are immediated afer the filemark
- self.sg_tape.space_filemarks(-1)?;
- self.sg_tape.space_filemarks(1)?;
- } else if current_position < position {
- let diff = position - current_position;
- self.sg_tape.space_filemarks(diff.try_into()?)?;
- } else {
- let diff = current_position - position + 1;
- self.sg_tape.space_filemarks(-diff.try_into()?)?;
- // move to EOT side of filemark
- self.sg_tape.space_filemarks(1)?;
- }
-
- Ok(())
+ self.sg_tape.locate_file(position)
}
pub fn erase_media(&mut self, fast: bool) -> Result<(), Error> {
Ok(())
}
+ fn move_to_file(&mut self, file: u64) -> Result<(), Error> {
+ self.locate_file(file)
+ }
+
fn rewind(&mut self) -> Result<(), Error> {
self.sg_tape.rewind()
}
self.sg_tape.format_media(fast)
}
- fn read_next_file<'a>(&'a mut self) -> Result<Option<Box<dyn TapeRead + 'a>>, std::io::Error> {
+ fn read_next_file<'a>(&'a mut self) -> Result<Box<dyn TapeRead + 'a>, BlockReadError> {
let reader = self.sg_tape.open_reader()?;
- let handle = match reader {
- Some(reader) => {
- let reader: Box<dyn TapeRead> = Box::new(reader);
- Some(reader)
- }
- None => None,
- };
-
+ let handle: Box<dyn TapeRead> = Box::new(reader);
Ok(handle)
}
}
let output = if let Some((fingerprint, uuid)) = key_fingerprint {
- let fingerprint = crate::tools::format::as_fingerprint(fingerprint.bytes());
+ let fingerprint = pbs_tools::format::as_fingerprint(fingerprint.bytes());
run_sg_tape_cmd("encryption", &[
"--fingerprint", &fingerprint,
"--uuid", &uuid.to_string(),