tape: factor out get_drive_and_media_status

This commit is contained in:
Dietmar Maurer 2020-12-29 08:39:06 +01:00
parent e0362b0d0f
commit 0993923ed5
4 changed files with 53 additions and 47 deletions

View File

@ -51,7 +51,10 @@ use crate::{
open_drive, open_drive,
media_changer, media_changer,
update_changer_online_status, update_changer_online_status,
mam_extract_media_usage, linux_tape::{
LinuxTapeHandle,
open_linux_tape_device,
},
file_formats::{ file_formats::{
MediaLabel, MediaLabel,
MediaSetLabel, MediaSetLabel,
@ -818,27 +821,13 @@ pub fn status(drive: String) -> Result<LinuxDriveAndMediaStatus, Error> {
let drive_config: LinuxTapeDrive = config.lookup("linux", &drive)?; let drive_config: LinuxTapeDrive = config.lookup("linux", &drive)?;
let mut handle = drive_config.open() // Note: use open_linux_tape_device, because this also works if no medium loaded
let file = open_linux_tape_device(&drive_config.path)
.map_err(|err| format_err!("open drive '{}' ({}) failed - {}", drive, drive_config.path, err))?; .map_err(|err| format_err!("open drive '{}' ({}) failed - {}", drive, drive_config.path, err))?;
let drive_status = handle.get_drive_status()?; let mut handle = LinuxTapeHandle::new(file);
let mam = handle.cartridge_memory()?; handle.get_drive_and_media_status()
let usage = mam_extract_media_usage(&mam)?;
let status = LinuxDriveAndMediaStatus {
blocksize: drive_status.blocksize,
density: drive_status.density,
status: format!("{:?}", drive_status.status),
file_number: drive_status.file_number,
block_number: drive_status.block_number,
manufactured: usage.manufactured,
bytes_read: usage.bytes_read,
bytes_written: usage.bytes_written,
};
Ok(status)
} }
#[sortable] #[sortable]

View File

@ -115,7 +115,7 @@ pub struct MamAttribute {
} }
#[api()] #[api()]
#[derive(Serialize,Deserialize,Debug)] #[derive(Serialize,Deserialize,Copy,Clone,Debug)]
pub enum TapeDensity { pub enum TapeDensity {
/// No tape loaded /// No tape loaded
None, None,
@ -182,9 +182,12 @@ pub struct LinuxDriveAndMediaStatus {
/// Current block number /// Current block number
pub block_number: i32, pub block_number: i32,
/// Medium Manufacture Date (epoch) /// Medium Manufacture Date (epoch)
pub manufactured: i64, #[serde(skip_serializing_if="Option::is_none")]
pub manufactured: Option<i64>,
/// Total Bytes Read in Medium Life /// Total Bytes Read in Medium Life
pub bytes_read: u64, #[serde(skip_serializing_if="Option::is_none")]
pub bytes_read: Option<u64>,
/// Total Bytes Written in Medium Life /// Total Bytes Written in Medium Life
pub bytes_written: u64, #[serde(skip_serializing_if="Option::is_none")]
pub bytes_written: Option<u64>,
} }

View File

@ -21,10 +21,8 @@ use proxmox::{
use proxmox_backup::{ use proxmox_backup::{
api2::types::{ api2::types::{
LINUX_DRIVE_PATH_SCHEMA, LINUX_DRIVE_PATH_SCHEMA,
LinuxDriveAndMediaStatus,
}, },
tape::{ tape::{
mam_extract_media_usage,
linux_tape::{ linux_tape::{
LinuxTapeHandle, LinuxTapeHandle,
open_linux_tape_device, open_linux_tape_device,
@ -63,24 +61,8 @@ fn status(
let result = proxmox::try_block!({ let result = proxmox::try_block!({
let mut handle = get_tape_handle(device)?; let mut handle = get_tape_handle(device)?;
handle.get_drive_and_media_status()
let drive_status = handle.get_drive_status()?; }).map_err(|err: Error| err.to_string());
let mam = handle.cartridge_memory()?;
let usage = mam_extract_media_usage(&mam)?;
Ok(LinuxDriveAndMediaStatus {
blocksize: drive_status.blocksize,
density: drive_status.density,
status: format!("{:?}", drive_status.status),
file_number: drive_status.file_number,
block_number: drive_status.block_number,
manufactured: usage.manufactured,
bytes_read: usage.bytes_read,
bytes_written: usage.bytes_written,
})
}).map_err(|err: Error| err.to_string());
println!("{}", serde_json::to_string_pretty(&result)?); println!("{}", serde_json::to_string_pretty(&result)?);

View File

@ -13,11 +13,13 @@ use crate::{
api2::types::{ api2::types::{
TapeDensity, TapeDensity,
MamAttribute, MamAttribute,
LinuxDriveAndMediaStatus,
}, },
tape::{ tape::{
TapeRead, TapeRead,
TapeWrite, TapeWrite,
read_mam_attributes, read_mam_attributes,
mam_extract_media_usage,
drive::{ drive::{
LinuxTapeDrive, LinuxTapeDrive,
TapeDriver, TapeDriver,
@ -65,7 +67,7 @@ impl LinuxTapeDrive {
let file = open_linux_tape_device(&self.path)?; let file = open_linux_tape_device(&self.path)?;
let handle = LinuxTapeHandle::new(file); let mut handle = LinuxTapeHandle::new(file);
let drive_status = handle.get_drive_status()?; let drive_status = handle.get_drive_status()?;
println!("drive status: {:?}", drive_status); println!("drive status: {:?}", drive_status);
@ -201,10 +203,40 @@ impl LinuxTapeHandle {
Ok(()) Ok(())
} }
/// Get Tape configuration with MTIOCGET ioctl /// Get Tape and Media status
pub fn get_drive_status(&self) -> Result<LinuxDriveStatus, Error> { pub fn get_drive_and_media_status(&mut self) -> Result<LinuxDriveAndMediaStatus, Error> {
self.mtnop()?; let drive_status = self.get_drive_status()?;
let mut status = LinuxDriveAndMediaStatus {
blocksize: drive_status.blocksize,
density: drive_status.density,
status: format!("{:?}", drive_status.status),
file_number: drive_status.file_number,
block_number: drive_status.block_number,
manufactured: None,
bytes_read: None,
bytes_written: None,
};
if drive_status.tape_is_ready() {
let mam = self.cartridge_memory()?;
let usage = mam_extract_media_usage(&mam)?;
status.manufactured = Some(usage.manufactured);
status.bytes_read = Some(usage.bytes_read);
status.bytes_written = Some(usage.bytes_written);
}
Ok(status)
}
/// Get Tape status/configuration with MTIOCGET ioctl
pub fn get_drive_status(&mut self) -> Result<LinuxDriveStatus, Error> {
let _ = self.mtnop(); // ignore errors (i.e. no tape loaded)
let mut status = mtget::default(); let mut status = mtget::default();