From 5f34d69bcc354623800c95957f315068ebb2aef1 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Fri, 22 Jan 2021 08:45:35 +0100 Subject: [PATCH] tape: add volume-statistics api/command --- src/api2/tape/drive.rs | 29 +++++++++++++++++++ src/bin/proxmox-tape.rs | 43 +++++++++++++++++++++++++++++ src/tape/drive/volume_statistics.rs | 35 +++++++++++++++++++++-- 3 files changed, 104 insertions(+), 3 deletions(-) diff --git a/src/api2/tape/drive.rs b/src/api2/tape/drive.rs index 1ffa6613..97c28344 100644 --- a/src/api2/tape/drive.rs +++ b/src/api2/tape/drive.rs @@ -55,6 +55,7 @@ use crate::{ drive::{ TapeDriver, LinuxTapeHandle, + Lp17VolumeStatistics, open_linux_tape_device, media_changer, required_media_changer, @@ -934,6 +935,29 @@ pub fn cartridge_memory(drive: String) -> Result, Error> { handle.cartridge_memory() } +#[api( + input: { + properties: { + drive: { + schema: DRIVE_NAME_SCHEMA, + }, + }, + }, + returns: { + type: Lp17VolumeStatistics, + }, +)] +/// Read Volume Statistics (SCSI log page 17h) +pub fn volume_statistics(drive: String) -> Result { + + let (config, _digest) = config::drive::config()?; + + let drive_config: LinuxTapeDrive = config.lookup("linux", &drive)?; + let mut handle = drive_config.open()?; + + handle.volume_statistics() +} + #[api( input: { properties: { @@ -1120,6 +1144,11 @@ pub const SUBDIRS: SubdirMap = &sorted!([ &Router::new() .put(&API_METHOD_CARTRIDGE_MEMORY) ), + ( + "volume-statistics", + &Router::new() + .put(&API_METHOD_VOLUME_STATISTICS) + ), ( "read-label", &Router::new() diff --git a/src/bin/proxmox-tape.rs b/src/bin/proxmox-tape.rs index c86b93d3..8322a918 100644 --- a/src/bin/proxmox-tape.rs +++ b/src/bin/proxmox-tape.rs @@ -664,6 +664,44 @@ fn cartridge_memory( Ok(()) } +#[api( + input: { + properties: { + drive: { + schema: DRIVE_NAME_SCHEMA, + optional: true, + }, + "output-format": { + schema: OUTPUT_FORMAT, + optional: true, + }, + }, + }, +)] +/// Read Volume Statistics (SCSI log page 17h) +fn volume_statistics( + mut param: Value, + rpcenv: &mut dyn RpcEnvironment, +) -> Result<(), Error> { + + let (config, _digest) = config::drive::config()?; + + param["drive"] = lookup_drive_name(¶m, &config)?.into(); + + let output_format = get_output_format(¶m); + let info = &api2::tape::drive::API_METHOD_VOLUME_STATISTICS; + + let mut data = match info.handler { + ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, + _ => unreachable!(), + }; + + let options = default_table_format_options(); + + format_and_print_result_full(&mut data, &info.returns, &output_format, &options); + Ok(()) +} + #[api( input: { properties: { @@ -943,6 +981,11 @@ fn main() { CliCommand::new(&API_METHOD_CARTRIDGE_MEMORY) .completion_cb("drive", complete_drive_name) ) + .insert( + "volume-statistics", + CliCommand::new(&API_METHOD_VOLUME_STATISTICS) + .completion_cb("drive", complete_drive_name) + ) .insert( "clean", CliCommand::new(&API_METHOD_CLEAN_DRIVE) diff --git a/src/tape/drive/volume_statistics.rs b/src/tape/drive/volume_statistics.rs index f9fe6550..1a2a6f90 100644 --- a/src/tape/drive/volume_statistics.rs +++ b/src/tape/drive/volume_statistics.rs @@ -5,7 +5,10 @@ use anyhow::{bail, format_err, Error}; use serde::{Serialize, Deserialize}; use endian_trait::Endian; -use proxmox::tools::io::ReadExt; +use proxmox::{ + api::api, + tools::io::ReadExt, +}; use crate::tools::sgutils2::SgRaw; @@ -55,39 +58,65 @@ struct LpParameterHeader { } +#[api()] /// Volume statistics from SCSI log page 17h #[derive(Default, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] pub struct Lp17VolumeStatistics { + /// Volume mounts (thread count) pub volume_mounts: u64, + /// Total data sets written pub volume_datasets_written: u64, + /// Write retries pub volume_recovered_write_data_errors: u64, + /// Total unrecovered write errors pub volume_unrecovered_write_data_errors: u64, + /// Total suspended writes pub volume_write_servo_errors: u64, + /// Total fatal suspended writes pub volume_unrecovered_write_servo_errors: u64, + /// Total datasets read pub volume_datasets_read: u64, + /// Total read retries pub volume_recovered_read_errors: u64, + /// Total unrecovered read errors pub volume_unrecovered_read_errors: u64, + /// Last mount unrecovered write errors pub last_mount_unrecovered_write_errors: u64, + /// Last mount unrecovered read errors pub last_mount_unrecovered_read_errors: u64, + /// Last mount bytes written pub last_mount_bytes_written: u64, + /// Last mount bytes read pub last_mount_bytes_read: u64, + /// Lifetime bytes written pub lifetime_bytes_written: u64, + /// Lifetime bytes read pub lifetime_bytes_read: u64, + /// Last load write compression ratio pub last_load_write_compression_ratio: u64, + /// Last load read compression ratio pub last_load_read_compression_ratio: u64, + /// Medium mount time pub medium_mount_time: u64, + /// Medium ready time pub medium_ready_time: u64, + /// Total native capacity pub total_native_capacity: u64, + /// Total used native capacity pub total_used_native_capacity: u64, + /// Write protect pub write_protect: bool, + /// Volume is WORM pub worm: bool, + /// Beginning of medium passes pub beginning_of_medium_passes: u64, + /// Middle of medium passes pub middle_of_tape_passes: u64, + /// Volume serial number pub serial: String, } -//impl Default for Lp17VolumeStatistics { - fn decode_volume_statistics(data: &[u8]) -> Result {