mirror of
https://git.proxmox.com/git/proxmox-backup
synced 2025-08-05 20:18:41 +00:00
tape: provide 'open_lto_drive' methods for LtoTapeHandle and SgTape
Prepares for the use in sg-tape-cmd, since we want to use the SgTape directly instead of LtoTapeHandle. Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
parent
8cc8aa510f
commit
b5f8626706
@ -26,8 +26,11 @@ pub use report_density::*;
|
||||
use proxmox_io::{ReadExt, WriteExt};
|
||||
use proxmox_sys::error::SysResult;
|
||||
|
||||
use pbs_api_types::{Lp17VolumeStatistics, LtoDriveAndMediaStatus, MamAttribute, TapeDensity};
|
||||
use pbs_api_types::{
|
||||
Lp17VolumeStatistics, LtoDriveAndMediaStatus, LtoTapeDrive, MamAttribute, TapeDensity,
|
||||
};
|
||||
|
||||
use crate::linux_list_drives::open_lto_tape_device;
|
||||
use crate::{
|
||||
sgutils2::{
|
||||
alloc_page_aligned_buffer, scsi_cmd_mode_select10, scsi_cmd_mode_select6, scsi_inquiry,
|
||||
@ -129,6 +132,43 @@ impl SgTape {
|
||||
})
|
||||
}
|
||||
|
||||
/// 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_drive(config: &LtoTapeDrive) -> Result<Self, Error> {
|
||||
proxmox_lang::try_block!({
|
||||
let file = open_lto_tape_device(&config.path)?;
|
||||
|
||||
let mut handle = SgTape::new(file)?;
|
||||
|
||||
if handle.test_unit_ready().is_err() {
|
||||
// for autoloader only, try to reload ejected tapes
|
||||
if config.changer.is_some() {
|
||||
let _ = handle.load(); // just try, ignore error
|
||||
}
|
||||
}
|
||||
|
||||
handle.wait_until_ready(None)?;
|
||||
|
||||
handle.set_default_options()?;
|
||||
|
||||
Ok(handle)
|
||||
})
|
||||
.map_err(|err: Error| {
|
||||
format_err!(
|
||||
"open drive '{}' ({}) failed - {}",
|
||||
config.name,
|
||||
config.path,
|
||||
err
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Access to file descriptor - useful for testing
|
||||
pub fn file_mut(&mut self) -> &mut File {
|
||||
&mut self.file
|
||||
|
@ -36,8 +36,7 @@ use crate::{
|
||||
changer::update_changer_online_status,
|
||||
drive::{
|
||||
get_tape_device_state, lock_tape_device, media_changer, open_drive,
|
||||
open_lto_tape_drive, required_media_changer, set_tape_device_state, LtoTapeHandle,
|
||||
TapeDriver,
|
||||
required_media_changer, set_tape_device_state, LtoTapeHandle, TapeDriver,
|
||||
},
|
||||
encryption_keys::insert_key,
|
||||
file_formats::{MediaLabel, MediaSetLabel},
|
||||
@ -1192,7 +1191,7 @@ pub async fn cartridge_memory(drive: String) -> Result<Vec<MamAttribute>, Error>
|
||||
"reading cartridge memory".to_string(),
|
||||
move |config| {
|
||||
let drive_config: LtoTapeDrive = config.lookup("lto", &drive)?;
|
||||
let mut handle = open_lto_tape_drive(&drive_config)?;
|
||||
let mut handle = LtoTapeHandle::open_lto_drive(&drive_config)?;
|
||||
|
||||
handle.cartridge_memory()
|
||||
},
|
||||
@ -1222,7 +1221,7 @@ pub async fn volume_statistics(drive: String) -> Result<Lp17VolumeStatistics, Er
|
||||
"reading volume statistics".to_string(),
|
||||
move |config| {
|
||||
let drive_config: LtoTapeDrive = config.lookup("lto", &drive)?;
|
||||
let mut handle = open_lto_tape_drive(&drive_config)?;
|
||||
let mut handle = LtoTapeHandle::open_lto_drive(&drive_config)?;
|
||||
|
||||
handle.volume_statistics()
|
||||
},
|
||||
|
@ -19,14 +19,14 @@ use pbs_api_types::{
|
||||
|
||||
use pbs_tape::linux_list_drives::{check_tape_is_lto_tape_device, open_lto_tape_device};
|
||||
|
||||
use proxmox_backup::tape::drive::{open_lto_tape_drive, LtoTapeHandle, TapeDriver};
|
||||
use proxmox_backup::tape::drive::{LtoTapeHandle, TapeDriver};
|
||||
|
||||
fn get_tape_handle(param: &Value) -> Result<LtoTapeHandle, Error> {
|
||||
let handle = if let Some(name) = param["drive"].as_str() {
|
||||
let (config, _digest) = pbs_config::drive::config()?;
|
||||
let drive: LtoTapeDrive = config.lookup("lto", name)?;
|
||||
log::info!("using device {}", drive.path);
|
||||
open_lto_tape_drive(&drive)?
|
||||
LtoTapeHandle::open_lto_drive(&drive)?
|
||||
} else if let Some(device) = param["device"].as_str() {
|
||||
log::info!("using device {}", device);
|
||||
LtoTapeHandle::new(open_lto_tape_device(device)?)?
|
||||
@ -40,7 +40,7 @@ fn get_tape_handle(param: &Value) -> Result<LtoTapeHandle, Error> {
|
||||
let (config, _digest) = pbs_config::drive::config()?;
|
||||
let drive: LtoTapeDrive = config.lookup("lto", &name)?;
|
||||
log::info!("using device {}", drive.path);
|
||||
open_lto_tape_drive(&drive)?
|
||||
LtoTapeHandle::open_lto_drive(&drive)?
|
||||
} else {
|
||||
let (config, _digest) = pbs_config::drive::config()?;
|
||||
|
||||
@ -56,7 +56,7 @@ fn get_tape_handle(param: &Value) -> Result<LtoTapeHandle, Error> {
|
||||
let name = drive_names[0];
|
||||
let drive: LtoTapeDrive = config.lookup("lto", name)?;
|
||||
log::info!("using device {}", drive.path);
|
||||
open_lto_tape_drive(&drive)?
|
||||
LtoTapeHandle::open_lto_drive(&drive)?
|
||||
} else {
|
||||
bail!("no drive/device specified");
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ use pbs_api_types::{
|
||||
};
|
||||
use pbs_key_config::KeyConfig;
|
||||
use pbs_tape::{
|
||||
linux_list_drives::open_lto_tape_device,
|
||||
sg_tape::{SgTape, TapeAlertFlags},
|
||||
BlockReadError, MediaContentHeader, TapeRead, TapeWrite,
|
||||
};
|
||||
@ -34,43 +33,6 @@ use crate::tape::{
|
||||
file_formats::{MediaSetLabel, PROXMOX_BACKUP_MEDIA_SET_LABEL_MAGIC_1_0},
|
||||
};
|
||||
|
||||
/// 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_lang::try_block!({
|
||||
let file = open_lto_tape_device(&config.path)?;
|
||||
|
||||
let mut handle = LtoTapeHandle::new(file)?;
|
||||
|
||||
if handle.sg_tape.test_unit_ready().is_err() {
|
||||
// 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(None)?;
|
||||
|
||||
handle.set_default_options()?;
|
||||
|
||||
Ok(handle)
|
||||
})
|
||||
.map_err(|err: Error| {
|
||||
format_err!(
|
||||
"open drive '{}' ({}) failed - {}",
|
||||
config.name,
|
||||
config.path,
|
||||
err
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Lto Tape device handle
|
||||
pub struct LtoTapeHandle {
|
||||
sg_tape: SgTape,
|
||||
@ -83,6 +45,18 @@ impl LtoTapeHandle {
|
||||
Ok(Self { sg_tape })
|
||||
}
|
||||
|
||||
/// Open a tape device
|
||||
///
|
||||
/// since this calls [SgTape::open_lto_drive], it does some internal checks.
|
||||
/// See [SgTape] docs for details.
|
||||
pub fn open_lto_drive(config: &LtoTapeDrive) -> Result<Self, Error> {
|
||||
let sg_tape = SgTape::open_lto_drive(config)?;
|
||||
|
||||
let handle = Self { sg_tape };
|
||||
|
||||
Ok(handle)
|
||||
}
|
||||
|
||||
/// Set all options we need/want
|
||||
pub fn set_default_options(&mut self) -> Result<(), Error> {
|
||||
self.sg_tape.set_default_options()?;
|
||||
|
@ -280,7 +280,7 @@ pub fn open_drive(config: &SectionConfigData, drive: &str) -> Result<Box<dyn Tap
|
||||
}
|
||||
"lto" => {
|
||||
let tape = LtoTapeDrive::deserialize(config)?;
|
||||
let handle = open_lto_tape_drive(&tape)?;
|
||||
let handle = LtoTapeHandle::open_lto_drive(&tape)?;
|
||||
Ok(Box::new(handle))
|
||||
}
|
||||
ty => bail!("unknown drive type '{}' - internal error", ty),
|
||||
@ -449,7 +449,7 @@ pub fn request_and_load_media(
|
||||
}
|
||||
}
|
||||
|
||||
let mut handle = match open_lto_tape_drive(&drive_config) {
|
||||
let mut handle = match LtoTapeHandle::open_lto_drive(&drive_config) {
|
||||
Ok(handle) => handle,
|
||||
Err(err) => {
|
||||
update_and_log_request_error(
|
||||
|
Loading…
Reference in New Issue
Block a user