1 //! Types for tape drive API
2 use std
::convert
::TryFrom
;
4 use anyhow
::{bail, Error}
;
5 use serde
::{Deserialize, Serialize}
;
9 schema
::{Schema, IntegerSchema, StringSchema, Updater}
,
12 use crate::api2
::types
::{
13 PROXMOX_SAFE_ID_FORMAT
,
15 OptionalDeviceIdentification
,
18 pub const DRIVE_NAME_SCHEMA
: Schema
= StringSchema
::new("Drive Identifier.")
19 .format(&PROXMOX_SAFE_ID_FORMAT
)
24 pub const LTO_DRIVE_PATH_SCHEMA
: Schema
= StringSchema
::new(
25 "The path to a LTO SCSI-generic tape device (i.e. '/dev/sg0')")
28 pub const CHANGER_DRIVENUM_SCHEMA
: Schema
= IntegerSchema
::new(
29 "Associated changer drive number (requires option changer)")
38 schema
: DRIVE_NAME_SCHEMA
,
42 #[derive(Serialize,Deserialize)]
43 /// Simulate tape drives (only for test and debug)
44 #[serde(rename_all = "kebab-case")]
45 pub struct VirtualTapeDrive
{
50 #[serde(skip_serializing_if="Option::is_none")]
51 pub max_size
: Option
<usize>,
57 schema
: DRIVE_NAME_SCHEMA
,
60 schema
: LTO_DRIVE_PATH_SCHEMA
,
63 schema
: CHANGER_NAME_SCHEMA
,
67 schema
: CHANGER_DRIVENUM_SCHEMA
,
72 #[derive(Serialize,Deserialize,Updater)]
73 #[serde(rename_all = "kebab-case")]
74 /// Lto SCSI tape driver
75 pub struct LtoTapeDrive
{
79 #[serde(skip_serializing_if="Option::is_none")]
80 pub changer
: Option
<String
>,
81 #[serde(skip_serializing_if="Option::is_none")]
82 pub changer_drivenum
: Option
<u64>,
91 type: OptionalDeviceIdentification
,
95 #[derive(Serialize,Deserialize)]
96 #[serde(rename_all = "kebab-case")]
98 pub struct DriveListEntry
{
100 pub config
: LtoTapeDrive
,
102 pub info
: OptionalDeviceIdentification
,
103 /// the state of the drive if locked
104 #[serde(skip_serializing_if="Option::is_none")]
105 pub state
: Option
<String
>,
109 #[derive(Serialize,Deserialize)]
110 /// Medium auxiliary memory attributes (MAM)
111 pub struct MamAttribute
{
121 #[derive(Serialize,Deserialize,Copy,Clone,Debug)]
122 pub enum TapeDensity
{
123 /// Unknown (no media loaded)
145 impl TryFrom
<u8> for TapeDensity
{
148 fn try_from(value
: u8) -> Result
<Self, Self::Error
> {
149 let density
= match value
{
150 0x00 => TapeDensity
::Unknown
,
151 0x40 => TapeDensity
::LTO1
,
152 0x42 => TapeDensity
::LTO2
,
153 0x44 => TapeDensity
::LTO3
,
154 0x46 => TapeDensity
::LTO4
,
155 0x58 => TapeDensity
::LTO5
,
156 0x5a => TapeDensity
::LTO6
,
157 0x5c => TapeDensity
::LTO7
,
158 0x5d => TapeDensity
::LTO7M8
,
159 0x5e => TapeDensity
::LTO8
,
160 _
=> bail
!("unknown tape density code 0x{:02x}", value
),
174 #[derive(Serialize,Deserialize)]
175 #[serde(rename_all = "kebab-case")]
176 /// Drive/Media status for Lto SCSI drives.
178 /// Media related data is optional - only set if there is a medium
180 pub struct LtoDriveAndMediaStatus
{
186 pub revision
: String
,
187 /// Block size (0 is variable size)
189 /// Compression enabled
190 pub compression
: bool
,
191 /// Drive buffer mode
194 pub density
: TapeDensity
,
195 /// Media is write protected
196 #[serde(skip_serializing_if="Option::is_none")]
197 pub write_protect
: Option
<bool
>,
199 #[serde(skip_serializing_if="Option::is_none")]
200 pub alert_flags
: Option
<String
>,
201 /// Current file number
202 #[serde(skip_serializing_if="Option::is_none")]
203 pub file_number
: Option
<u64>,
204 /// Current block number
205 #[serde(skip_serializing_if="Option::is_none")]
206 pub block_number
: Option
<u64>,
207 /// Medium Manufacture Date (epoch)
208 #[serde(skip_serializing_if="Option::is_none")]
209 pub manufactured
: Option
<i64>,
210 /// Total Bytes Read in Medium Life
211 #[serde(skip_serializing_if="Option::is_none")]
212 pub bytes_read
: Option
<u64>,
213 /// Total Bytes Written in Medium Life
214 #[serde(skip_serializing_if="Option::is_none")]
215 pub bytes_written
: Option
<u64>,
216 /// Number of mounts for the current volume (i.e., Thread Count)
217 #[serde(skip_serializing_if="Option::is_none")]
218 pub volume_mounts
: Option
<u64>,
219 /// Count of the total number of times the medium has passed over
221 #[serde(skip_serializing_if="Option::is_none")]
222 pub medium_passes
: Option
<u64>,
223 /// Estimated tape wearout factor (assuming max. 16000 end-to-end passes)
224 #[serde(skip_serializing_if="Option::is_none")]
225 pub medium_wearout
: Option
<f64>,
229 /// Volume statistics from SCSI log page 17h
230 #[derive(Default, Serialize, Deserialize)]
231 #[serde(rename_all = "kebab-case")]
232 pub struct Lp17VolumeStatistics
{
233 /// Volume mounts (thread count)
234 pub volume_mounts
: u64,
235 /// Total data sets written
236 pub volume_datasets_written
: u64,
238 pub volume_recovered_write_data_errors
: u64,
239 /// Total unrecovered write errors
240 pub volume_unrecovered_write_data_errors
: u64,
241 /// Total suspended writes
242 pub volume_write_servo_errors
: u64,
243 /// Total fatal suspended writes
244 pub volume_unrecovered_write_servo_errors
: u64,
245 /// Total datasets read
246 pub volume_datasets_read
: u64,
247 /// Total read retries
248 pub volume_recovered_read_errors
: u64,
249 /// Total unrecovered read errors
250 pub volume_unrecovered_read_errors
: u64,
251 /// Last mount unrecovered write errors
252 pub last_mount_unrecovered_write_errors
: u64,
253 /// Last mount unrecovered read errors
254 pub last_mount_unrecovered_read_errors
: u64,
255 /// Last mount bytes written
256 pub last_mount_bytes_written
: u64,
257 /// Last mount bytes read
258 pub last_mount_bytes_read
: u64,
259 /// Lifetime bytes written
260 pub lifetime_bytes_written
: u64,
261 /// Lifetime bytes read
262 pub lifetime_bytes_read
: u64,
263 /// Last load write compression ratio
264 pub last_load_write_compression_ratio
: u64,
265 /// Last load read compression ratio
266 pub last_load_read_compression_ratio
: u64,
267 /// Medium mount time
268 pub medium_mount_time
: u64,
269 /// Medium ready time
270 pub medium_ready_time
: u64,
271 /// Total native capacity
272 pub total_native_capacity
: u64,
273 /// Total used native capacity
274 pub total_used_native_capacity
: u64,
276 pub write_protect
: bool
,
279 /// Beginning of medium passes
280 pub beginning_of_medium_passes
: u64,
281 /// Middle of medium passes
282 pub middle_of_tape_passes
: u64,
283 /// Volume serial number