From 271764deb9cadcc55d2e2c31a959263dcf6e96f0 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Fri, 29 Jan 2021 09:07:55 +0100 Subject: [PATCH] tape: make it possible to abort tape backup tasks (check_abort) Also use task_log makro instead of worker.log. --- src/api2/tape/backup.rs | 16 ++++++++++++---- src/tape/drive/mod.rs | 40 +++++++++++++++++++++++++++------------- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/api2/tape/backup.rs b/src/api2/tape/backup.rs index 6aa12d56..84d3851c 100644 --- a/src/api2/tape/backup.rs +++ b/src/api2/tape/backup.rs @@ -14,6 +14,7 @@ use proxmox::{ }; use crate::{ + task_log, config::{ self, drive::check_drive_exists, @@ -31,6 +32,7 @@ use crate::{ MediaPoolConfig, }, server::WorkerTask, + task::TaskState, tape::{ TAPE_STATUS_DIR, Inventory, @@ -122,7 +124,7 @@ fn backup_worker( let _lock = MediaPool::lock(status_path, &pool_config.name)?; - worker.log("update media online status"); + task_log!(worker, "update media online status"); let has_changer = update_media_online_status(&pool_config.drive)?; let use_offline_media = !has_changer; @@ -143,7 +145,7 @@ fn backup_worker( if pool_writer.contains_snapshot(&info.backup_dir.to_string()) { continue; } - worker.log(format!("backup snapshot {}", info.backup_dir)); + task_log!(worker, "backup snapshot {}", info.backup_dir); backup_snapshot(worker, &mut pool_writer, datastore.clone(), info.backup_dir)?; } } @@ -193,13 +195,15 @@ pub fn backup_snapshot( snapshot: BackupDir, ) -> Result<(), Error> { - worker.log(format!("start backup {}:{}", datastore.name(), snapshot)); + task_log!(worker, "start backup {}:{}", datastore.name(), snapshot); let snapshot_reader = SnapshotReader::new(datastore.clone(), snapshot.clone())?; let mut chunk_iter = snapshot_reader.chunk_iterator()?.peekable(); loop { + worker.check_abort()?; + // test is we have remaining chunks if chunk_iter.peek().is_none() { break; @@ -214,6 +218,8 @@ pub fn backup_snapshot( } } + worker.check_abort()?; + let uuid = pool_writer.load_writable_media(worker)?; let (done, _bytes) = pool_writer.append_snapshot_archive(worker, &snapshot_reader)?; @@ -222,6 +228,8 @@ pub fn backup_snapshot( // does not fit on tape, so we try on next volume pool_writer.set_media_status_full(&uuid)?; + worker.check_abort()?; + pool_writer.load_writable_media(worker)?; let (done, _bytes) = pool_writer.append_snapshot_archive(worker, &snapshot_reader)?; @@ -230,7 +238,7 @@ pub fn backup_snapshot( } } - worker.log(format!("end backup {}:{}", datastore.name(), snapshot)); + task_log!(worker, "end backup {}:{}", datastore.name(), snapshot); Ok(()) } diff --git a/src/tape/drive/mod.rs b/src/tape/drive/mod.rs index 864658c8..1e994844 100644 --- a/src/tape/drive/mod.rs +++ b/src/tape/drive/mod.rs @@ -31,6 +31,8 @@ use proxmox::{ }; use crate::{ + task_log, + task::TaskState, backup::{ Fingerprint, KeyConfig, @@ -314,11 +316,13 @@ pub fn request_and_load_media( let check_label = |handle: &mut dyn TapeDriver, uuid: &proxmox::tools::Uuid| { if let Ok((Some(media_id), _)) = handle.read_label() { - worker.log(format!( + task_log!( + worker, "found media label {} ({})", media_id.label.label_text, - media_id.label.uuid.to_string(), - )); + media_id.label.uuid, + ); + if media_id.label.uuid == *uuid { return Ok(media_id); } @@ -359,7 +363,7 @@ pub fn request_and_load_media( return Ok((handle, media_id)); } - worker.log(format!("Please insert media '{}' into drive '{}'", label_text, drive)); + task_log!(worker, "Please insert media '{}' into drive '{}'", label_text, drive); let to = "root@localhost"; // fixme @@ -369,15 +373,20 @@ pub fn request_and_load_media( let mut last_error = None; loop { + worker.check_abort()?; + let mut handle = match drive_config.open() { Ok(handle) => handle, Err(err) => { let err = err.to_string(); if Some(err.clone()) != last_error { - worker.log(format!("tape open failed - {}", err)); + task_log!(worker, "tape open failed - {}", err); last_error = Some(err); } - std::thread::sleep(std::time::Duration::from_millis(5_000)); + for _ in 0..50 { // delay 5 seconds + worker.check_abort()?; + std::thread::sleep(std::time::Duration::from_millis(100)); + } continue; } }; @@ -385,38 +394,43 @@ pub fn request_and_load_media( match handle.read_label() { Ok((Some(media_id), _)) => { if media_id.label.uuid == label.uuid { - worker.log(format!( + task_log!( + worker, "found media label {} ({})", media_id.label.label_text, media_id.label.uuid.to_string(), - )); + ); return Ok((Box::new(handle), media_id)); } else if Some(media_id.label.uuid.clone()) != last_media_uuid { - worker.log(format!( + task_log!( + worker, "wrong media label {} ({})", media_id.label.label_text, media_id.label.uuid.to_string(), - )); + ); last_media_uuid = Some(media_id.label.uuid); } } Ok((None, _)) => { if last_media_uuid.is_some() { - worker.log("found empty media without label (please label all tapes first)".to_string()); + task_log!(worker, "found empty media without label (please label all tapes first)"); last_media_uuid = None; } } Err(err) => { let err = err.to_string(); if Some(err.clone()) != last_error { - worker.log(format!("tape open failed - {}", err)); + task_log!(worker, "tape open failed - {}", err); last_error = Some(err); } } } // eprintln!("read label failed - test again in 5 secs"); - std::thread::sleep(std::time::Duration::from_millis(5_000)); + for _ in 0..50 { // delay 5 seconds + worker.check_abort()?; + std::thread::sleep(std::time::Duration::from_millis(100)); + } } } _ => bail!("drive type '{}' not implemented!"),