diff --git a/src/bin/proxmox-tape.rs b/src/bin/proxmox-tape.rs index 3e41b2a2..d710f7a4 100644 --- a/src/bin/proxmox-tape.rs +++ b/src/bin/proxmox-tape.rs @@ -25,14 +25,19 @@ use proxmox_backup::{ MEDIA_POOL_NAME_SCHEMA, }, }, - tape::open_drive, config::{ self, drive::complete_drive_name, media_pool::complete_pool_name, }, tape::{ + open_drive, complete_media_changer_id, + file_formats::{ + PROXMOX_BACKUP_CONTENT_HEADER_MAGIC_1_0, + PROXMOX_BACKUP_CONTENT_NAME, + MediaContentHeader, + }, }, }; @@ -435,6 +440,64 @@ fn move_to_eom(param: Value) -> Result<(), Error> { Ok(()) } +#[api( + input: { + properties: { + drive: { + schema: DRIVE_NAME_SCHEMA, + optional: true, + }, + }, + }, +)] +/// Rewind, then read media contents and print debug info +fn debug_scan(param: Value) -> Result<(), Error> { + + use proxmox::tools::io::ReadExt; + + let (config, _digest) = config::drive::config()?; + + let drive = lookup_drive_name(¶m, &config)?; + let mut drive = open_drive(&config, &drive)?; + + println!("rewinding tape"); + drive.rewind()?; + + loop { + let file_number = drive.current_file_number()?; + + match drive.read_next_file()? { + None => { + println!("EOD"); + continue; + }, + Some(mut reader) => { + println!("got file number {}", file_number); + + let header: Result = unsafe { reader.read_le_value() }; + match header { + Ok(header) => { + if header.magic != PROXMOX_BACKUP_CONTENT_HEADER_MAGIC_1_0 { + println!("got MediaContentHeader with wrong magic: {:?}", header.magic); + } else { + if let Some(name) = PROXMOX_BACKUP_CONTENT_NAME.get(&header.content_magic) { + println!("got content header: {}", name); + } else { + println!("got unknown content header: {:?}", header.content_magic); + } + } + } + Err(err) => { + println!("unable to read content header - {}", err); + } + } + let bytes = reader.skip_to_end()?; + println!("skipped {} bytes", bytes); + } + } + } +} + fn main() { let cmd_def = CliCommandMap::new() @@ -449,6 +512,11 @@ fn main() { CliCommand::new(&API_METHOD_REWIND) .completion_cb("drive", complete_drive_name) ) + .insert( + "scan", + CliCommand::new(&API_METHOD_DEBUG_SCAN) + .completion_cb("drive", complete_drive_name) + ) .insert( "eod", CliCommand::new(&API_METHOD_MOVE_TO_EOM) diff --git a/src/tape/file_formats.rs b/src/tape/file_formats.rs index 727b0f26..21e513e6 100644 --- a/src/tape/file_formats.rs +++ b/src/tape/file_formats.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use anyhow::{bail, Error}; use ::serde::{Deserialize, Serialize}; use endian_trait::Endian; @@ -26,6 +28,17 @@ pub const PROXMOX_BACKUP_CHUNK_ARCHIVE_ENTRY_MAGIC_1_0: [u8; 8] = [72, 87, 109, // openssl::sha::sha256(b"Proxmox Backup Snapshot Archive v1.0")[0..8]; pub const PROXMOX_BACKUP_SNAPSHOT_ARCHIVE_MAGIC_1_0: [u8; 8] = [9, 182, 2, 31, 125, 232, 114, 133]; +lazy_static::lazy_static!{ + pub static ref PROXMOX_BACKUP_CONTENT_NAME: HashMap<&'static [u8;8], &'static str> = { + let mut map = HashMap::new(); + map.insert(&PROXMOX_BACKUP_DRIVE_LABEL_MAGIC_1_0, "Proxmox Backup Tape Label v1.0"); + map.insert(&PROXMOX_BACKUP_MEDIA_SET_LABEL_MAGIC_1_0, "Proxmox Backup MediaSet Label v1.0"); + map.insert(&PROXMOX_BACKUP_CHUNK_ARCHIVE_MAGIC_1_0, "Proxmox Backup Chunk Archive v1.0"); + map.insert(&PROXMOX_BACKUP_SNAPSHOT_ARCHIVE_MAGIC_1_0, "Proxmox Backup Snapshot Archive v1.0"); + map + }; +} + /// Tape Block Header with data payload /// /// Note: this struct is large, never put this on the stack!