tape: make it possible to abort tape backup tasks (check_abort)
Also use task_log makro instead of worker.log.
This commit is contained in:
parent
52f7a73009
commit
271764deb9
|
@ -14,6 +14,7 @@ use proxmox::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
task_log,
|
||||||
config::{
|
config::{
|
||||||
self,
|
self,
|
||||||
drive::check_drive_exists,
|
drive::check_drive_exists,
|
||||||
|
@ -31,6 +32,7 @@ use crate::{
|
||||||
MediaPoolConfig,
|
MediaPoolConfig,
|
||||||
},
|
},
|
||||||
server::WorkerTask,
|
server::WorkerTask,
|
||||||
|
task::TaskState,
|
||||||
tape::{
|
tape::{
|
||||||
TAPE_STATUS_DIR,
|
TAPE_STATUS_DIR,
|
||||||
Inventory,
|
Inventory,
|
||||||
|
@ -122,7 +124,7 @@ fn backup_worker(
|
||||||
|
|
||||||
let _lock = MediaPool::lock(status_path, &pool_config.name)?;
|
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 has_changer = update_media_online_status(&pool_config.drive)?;
|
||||||
|
|
||||||
let use_offline_media = !has_changer;
|
let use_offline_media = !has_changer;
|
||||||
|
@ -143,7 +145,7 @@ fn backup_worker(
|
||||||
if pool_writer.contains_snapshot(&info.backup_dir.to_string()) {
|
if pool_writer.contains_snapshot(&info.backup_dir.to_string()) {
|
||||||
continue;
|
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)?;
|
backup_snapshot(worker, &mut pool_writer, datastore.clone(), info.backup_dir)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,13 +195,15 @@ pub fn backup_snapshot(
|
||||||
snapshot: BackupDir,
|
snapshot: BackupDir,
|
||||||
) -> Result<(), Error> {
|
) -> 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 snapshot_reader = SnapshotReader::new(datastore.clone(), snapshot.clone())?;
|
||||||
|
|
||||||
let mut chunk_iter = snapshot_reader.chunk_iterator()?.peekable();
|
let mut chunk_iter = snapshot_reader.chunk_iterator()?.peekable();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
worker.check_abort()?;
|
||||||
|
|
||||||
// test is we have remaining chunks
|
// test is we have remaining chunks
|
||||||
if chunk_iter.peek().is_none() {
|
if chunk_iter.peek().is_none() {
|
||||||
break;
|
break;
|
||||||
|
@ -214,6 +218,8 @@ pub fn backup_snapshot(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
worker.check_abort()?;
|
||||||
|
|
||||||
let uuid = pool_writer.load_writable_media(worker)?;
|
let uuid = pool_writer.load_writable_media(worker)?;
|
||||||
|
|
||||||
let (done, _bytes) = pool_writer.append_snapshot_archive(worker, &snapshot_reader)?;
|
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
|
// does not fit on tape, so we try on next volume
|
||||||
pool_writer.set_media_status_full(&uuid)?;
|
pool_writer.set_media_status_full(&uuid)?;
|
||||||
|
|
||||||
|
worker.check_abort()?;
|
||||||
|
|
||||||
pool_writer.load_writable_media(worker)?;
|
pool_writer.load_writable_media(worker)?;
|
||||||
let (done, _bytes) = pool_writer.append_snapshot_archive(worker, &snapshot_reader)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,8 @@ use proxmox::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
task_log,
|
||||||
|
task::TaskState,
|
||||||
backup::{
|
backup::{
|
||||||
Fingerprint,
|
Fingerprint,
|
||||||
KeyConfig,
|
KeyConfig,
|
||||||
|
@ -314,11 +316,13 @@ pub fn request_and_load_media(
|
||||||
|
|
||||||
let check_label = |handle: &mut dyn TapeDriver, uuid: &proxmox::tools::Uuid| {
|
let check_label = |handle: &mut dyn TapeDriver, uuid: &proxmox::tools::Uuid| {
|
||||||
if let Ok((Some(media_id), _)) = handle.read_label() {
|
if let Ok((Some(media_id), _)) = handle.read_label() {
|
||||||
worker.log(format!(
|
task_log!(
|
||||||
|
worker,
|
||||||
"found media label {} ({})",
|
"found media label {} ({})",
|
||||||
media_id.label.label_text,
|
media_id.label.label_text,
|
||||||
media_id.label.uuid.to_string(),
|
media_id.label.uuid,
|
||||||
));
|
);
|
||||||
|
|
||||||
if media_id.label.uuid == *uuid {
|
if media_id.label.uuid == *uuid {
|
||||||
return Ok(media_id);
|
return Ok(media_id);
|
||||||
}
|
}
|
||||||
|
@ -359,7 +363,7 @@ pub fn request_and_load_media(
|
||||||
return Ok((handle, media_id));
|
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
|
let to = "root@localhost"; // fixme
|
||||||
|
|
||||||
|
@ -369,15 +373,20 @@ pub fn request_and_load_media(
|
||||||
let mut last_error = None;
|
let mut last_error = None;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
worker.check_abort()?;
|
||||||
|
|
||||||
let mut handle = match drive_config.open() {
|
let mut handle = match drive_config.open() {
|
||||||
Ok(handle) => handle,
|
Ok(handle) => handle,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let err = err.to_string();
|
let err = err.to_string();
|
||||||
if Some(err.clone()) != last_error {
|
if Some(err.clone()) != last_error {
|
||||||
worker.log(format!("tape open failed - {}", err));
|
task_log!(worker, "tape open failed - {}", err);
|
||||||
last_error = Some(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;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -385,38 +394,43 @@ pub fn request_and_load_media(
|
||||||
match handle.read_label() {
|
match handle.read_label() {
|
||||||
Ok((Some(media_id), _)) => {
|
Ok((Some(media_id), _)) => {
|
||||||
if media_id.label.uuid == label.uuid {
|
if media_id.label.uuid == label.uuid {
|
||||||
worker.log(format!(
|
task_log!(
|
||||||
|
worker,
|
||||||
"found media label {} ({})",
|
"found media label {} ({})",
|
||||||
media_id.label.label_text,
|
media_id.label.label_text,
|
||||||
media_id.label.uuid.to_string(),
|
media_id.label.uuid.to_string(),
|
||||||
));
|
);
|
||||||
return Ok((Box::new(handle), media_id));
|
return Ok((Box::new(handle), media_id));
|
||||||
} else if Some(media_id.label.uuid.clone()) != last_media_uuid {
|
} else if Some(media_id.label.uuid.clone()) != last_media_uuid {
|
||||||
worker.log(format!(
|
task_log!(
|
||||||
|
worker,
|
||||||
"wrong media label {} ({})",
|
"wrong media label {} ({})",
|
||||||
media_id.label.label_text,
|
media_id.label.label_text,
|
||||||
media_id.label.uuid.to_string(),
|
media_id.label.uuid.to_string(),
|
||||||
));
|
);
|
||||||
last_media_uuid = Some(media_id.label.uuid);
|
last_media_uuid = Some(media_id.label.uuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok((None, _)) => {
|
Ok((None, _)) => {
|
||||||
if last_media_uuid.is_some() {
|
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;
|
last_media_uuid = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let err = err.to_string();
|
let err = err.to_string();
|
||||||
if Some(err.clone()) != last_error {
|
if Some(err.clone()) != last_error {
|
||||||
worker.log(format!("tape open failed - {}", err));
|
task_log!(worker, "tape open failed - {}", err);
|
||||||
last_error = Some(err);
|
last_error = Some(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// eprintln!("read label failed - test again in 5 secs");
|
// 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!"),
|
_ => bail!("drive type '{}' not implemented!"),
|
||||||
|
|
Loading…
Reference in New Issue