From 54f4ecd46a42bab09f7ad862bb5e3d7cf53a7a0f Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Fri, 1 Jan 2021 10:03:59 +0100 Subject: [PATCH] tape: implement MediaPool flag to consider offline media For standalone tape drives. --- src/api2/tape/backup.rs | 14 ++++++++++---- src/api2/tape/media.rs | 3 ++- src/tape/media_pool.rs | 27 ++++++++++++++++++++++----- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/api2/tape/backup.rs b/src/api2/tape/backup.rs index 56667ad7..afb3f392 100644 --- a/src/api2/tape/backup.rs +++ b/src/api2/tape/backup.rs @@ -109,9 +109,11 @@ fn backup_worker( let _lock = MediaPool::lock(status_path, &pool_config.name)?; worker.log("update media online status"); - update_media_online_status(&pool_config.drive)?; + let has_changer = update_media_online_status(&pool_config.drive)?; - let pool = MediaPool::with_config(status_path, &pool_config)?; + let use_offline_media = !has_changer; + + let pool = MediaPool::with_config(status_path, &pool_config, use_offline_media)?; let mut pool_writer = PoolWriter::new(pool, &pool_config.drive)?; @@ -138,12 +140,16 @@ fn backup_worker( } // Try to update the the media online status -fn update_media_online_status(drive: &str) -> Result<(), Error> { +fn update_media_online_status(drive: &str) -> Result { let (config, _digest) = config::drive::config()?; + let mut has_changer = false; + if let Ok(Some((changer, changer_name))) = media_changer(&config, drive) { + has_changer = true; + let changer_id_list = changer.list_media_changer_ids()?; let status_path = Path::new(TAPE_STATUS_DIR); @@ -159,7 +165,7 @@ fn update_media_online_status(drive: &str) -> Result<(), Error> { )?; } - Ok(()) + Ok(has_changer) } pub fn backup_snapshot( diff --git a/src/api2/tape/media.rs b/src/api2/tape/media.rs index 02c9e843..805b82ac 100644 --- a/src/api2/tape/media.rs +++ b/src/api2/tape/media.rs @@ -81,7 +81,8 @@ pub async fn list_media(pool: Option) -> Result, Err let config: MediaPoolConfig = config.lookup("pool", pool_name)?; - let pool = MediaPool::with_config(status_path, &config)?; + let use_offline_media = true; // does not matter here + let pool = MediaPool::with_config(status_path, &config, use_offline_media)?; let current_time = proxmox::tools::time::epoch_i64(); diff --git a/src/tape/media_pool.rs b/src/tape/media_pool.rs index b4a11e77..8c7f2cc3 100644 --- a/src/tape/media_pool.rs +++ b/src/tape/media_pool.rs @@ -44,6 +44,7 @@ pub struct MediaPool { media_set_policy: MediaSetPolicy, retention: RetentionPolicy, + use_offline_media: bool, inventory: Inventory, state_db: MediaStateDatabase, @@ -59,6 +60,7 @@ impl MediaPool { state_path: &Path, media_set_policy: MediaSetPolicy, retention: RetentionPolicy, + use_offline_media: bool, ) -> Result { let inventory = Inventory::load(state_path)?; @@ -74,6 +76,7 @@ impl MediaPool { name: String::from(name), media_set_policy, retention, + use_offline_media, inventory, state_db, current_media_set, @@ -84,13 +87,14 @@ impl MediaPool { pub fn with_config( state_path: &Path, config: &MediaPoolConfig, + use_offline_media: bool, ) -> Result { let allocation = config.allocation.clone().unwrap_or(String::from("continue")).parse()?; let retention = config.retention.clone().unwrap_or(String::from("keep")).parse()?; - MediaPool::new(&config.name, state_path, allocation, retention) + MediaPool::new(&config.name, state_path, allocation, retention, use_offline_media) } /// Returns the pool name @@ -272,7 +276,14 @@ impl MediaPool { // check if media is on site match media.location() { - MediaLocation::Online(_) | MediaLocation::Offline => { /* OK */ }, + MediaLocation::Online(_) => { /* OK */ }, + MediaLocation::Offline => { + if self.use_offline_media { + /* OK */ + } else { + continue; + } + }, MediaLocation::Vault(_) => continue, } @@ -380,9 +391,15 @@ impl MediaPool { match media.status() { MediaStatus::Full => { /* OK */ }, MediaStatus::Writable if (seq + 1) == media_count => { - last_is_writable = true; match media.location() { - MediaLocation::Online(_) | MediaLocation::Offline => { /* OK */ }, + MediaLocation::Online(_) => { + last_is_writable = true; + }, + MediaLocation::Offline => { + if self.use_offline_media { + last_is_writable = true; + } + } MediaLocation::Vault(vault) => { bail!("writable media offsite in vault '{}'", vault); } @@ -465,7 +482,7 @@ impl BackupMedia { pub fn set_media_set_label(&mut self, set_label: MediaSetLabel) { self.id.media_set_label = Some(set_label); } - + /// Returns the drive label pub fn label(&self) -> &MediaLabel { &self.id.label