use anyhow::{bail, Error};
-use proxmox::tools::Uuid;
+use proxmox_uuid::Uuid;
+use proxmox_sys::{task_log, task_warn};
+
+use pbs_config::tape_encryption_keys::load_key_configs;
+use pbs_tape::{
+ TapeWrite,
+ sg_tape::tape_alert_flags_critical,
+};
+use pbs_datastore::{DataStore, SnapshotReader};
+use proxmox_rest_server::WorkerTask;
use crate::{
- task_log,
- backup::{
- DataStore,
- },
- server::WorkerTask,
tape::{
TAPE_STATUS_DIR,
MAX_CHUNK_ARCHIVE_SIZE,
COMMIT_BLOCK_SIZE,
- TapeWrite,
- SnapshotReader,
MediaPool,
MediaId,
MediaCatalog,
drive::{
TapeDriver,
request_and_load_media,
- tape_alert_flags_critical,
media_changer,
},
},
- config::tape_encryption_keys::load_key_configs,
};
drive_name: &str,
worker: &WorkerTask,
notify_email: Option<String>,
+ force_media_set: bool,
) -> Result<Self, Error> {
- let current_time = proxmox::tools::time::epoch_i64();
+ let current_time = proxmox_time::epoch_i64();
- let new_media_set_reason = pool.start_write_session(current_time)?;
+ let new_media_set_reason = pool.start_write_session(current_time, force_media_set)?;
if let Some(reason) = new_media_set_reason {
task_log!(
worker,
/// Set media status to FULL (persistent - stores pool status)
pub fn set_media_status_full(&mut self, uuid: &Uuid) -> Result<(), Error> {
- self.pool.set_media_status_full(&uuid)?;
+ self.pool.set_media_status_full(uuid)?;
Ok(())
}
None => return Ok(()), // no media loaded
};
- let (drive_config, _digest) = crate::config::drive::config()?;
+ let (drive_config, _digest) = pbs_config::drive::config()?;
if let Some((mut changer, _)) = media_changer(&drive_config, &self.drive_name)? {
- worker.log("eject media");
+ task_log!(worker, "eject media");
status.drive.eject_media()?; // rewind and eject early, so that unload_media is faster
drop(status); // close drive
- worker.log("unload media");
+ task_log!(worker, "unload media");
changer.unload_media(None)?; //eject and unload
} else {
- worker.log("standalone drive - ejecting media");
+ task_log!(worker, "standalone drive - ejecting media");
status.drive.eject_media()?;
}
pub fn export_media_set(&mut self, worker: &WorkerTask) -> Result<(), Error> {
let mut status = self.status.take();
- let (drive_config, _digest) = crate::config::drive::config()?;
+ let (drive_config, _digest) = pbs_config::drive::config()?;
if let Some((mut changer, _)) = media_changer(&drive_config, &self.drive_name)? {
if let Some(ref mut status) = status {
- worker.log("eject media");
- status.drive.eject_media()?; // rewind and eject early, so that unload_media is faster
+ task_log!(worker, "rewind media");
+ // rewind first so that the unload command later does not run into a timeout
+ status.drive.rewind()?;
}
drop(status); // close drive
- worker.log("unload media");
- changer.unload_media(None)?;
-
for media_uuid in self.pool.current_media_list()? {
let media = self.pool.lookup_media(media_uuid)?;
let label_text = media.label_text();
if let Some(slot) = changer.export_media(label_text)? {
- worker.log(format!("exported media '{}' to import/export slot {}", label_text, slot));
+ task_log!(worker, "exported media '{}' to import/export slot {}", label_text, slot);
} else {
- worker.warn(format!("export failed - media '{}' is not online", label_text));
+ task_warn!(worker, "export failed - media '{}' is not online or in different drive", label_text);
}
}
} else if let Some(mut status) = status {
- worker.log("standalone drive - ejecting media instead of export");
+ task_log!(worker, "standalone drive - ejecting media instead of export");
status.drive.eject_media()?;
}
None => None,
};
- let current_time = proxmox::tools::time::epoch_i64();
+ let current_time = proxmox_time::epoch_i64();
let media_uuid = self.pool.alloc_writable_media(current_time)?;
let media = self.pool.lookup_media(&media_uuid).unwrap();
}
}
- let (drive_config, _digest) = crate::config::drive::config()?;
+ let (drive_config, _digest) = pbs_config::drive::config()?;
let (mut drive, old_media_id) =
request_and_load_media(worker, &drive_config, &self.drive_name, media.label(), &self.notify_email)?;
// test for critical tape alert flags
if let Ok(alert_flags) = drive.tape_alert_flags() {
if !alert_flags.is_empty() {
- worker.log(format!("TapeAlertFlags: {:?}", alert_flags));
+ task_log!(worker, "TapeAlertFlags: {:?}", alert_flags);
if tape_alert_flags_critical(alert_flags) {
self.pool.set_media_status_damaged(&media_uuid)?;
bail!("aborting due to critical tape alert flags: {:?}", alert_flags);
) -> Result<u64, Error> {
if !status.at_eom {
- worker.log(String::from("moving to end of media"));
- status.drive.move_to_eom()?;
+ task_log!(worker, "moving to end of media");
+ status.drive.move_to_eom(true)?;
status.at_eom = true;
}
status.bytes_written += bytes_written;
let elapsed = start_time.elapsed()?.as_secs_f64();
- worker.log(format!(
+ task_log!(
+ worker,
"wrote {} chunks ({:.2} MB at {:.2} MB/s)",
saved_chunks.len(),
bytes_written as f64 /1_000_000.0,
(bytes_written as f64)/(1_000_000.0*elapsed),
- ));
+ );
let request_sync = status.bytes_written >= COMMIT_BLOCK_SIZE;
Some(Err(err)) => bail!("{}", err),
};
- //println!("CHUNK {} size {}", proxmox::tools::digest_to_hex(digest), blob.raw_size());
+ //println!("CHUNK {} size {}", hex::encode(digest), blob.raw_size());
- match writer.try_write_chunk(&digest, &blob) {
+ match writer.try_write_chunk(digest, blob) {
Ok(true) => {
chunk_list.push(*digest);
chunk_iter.next(); // consume
}
if writer.bytes_written() > max_size {
- //worker.log("Chunk Archive max size reached, closing archive".to_string());
+ //task_log!(worker, "Chunk Archive max size reached, closing archive");
break;
}
}
let new_media = match old_set {
None => {
- worker.log("wrinting new media set label".to_string());
+ task_log!(worker, "writing new media set label");
drive.write_media_set_label(new_set, key_config.as_ref())?;
media_catalog = MediaCatalog::overwrite(status_path, media_id, false)?;
true
if new_set.encryption_key_fingerprint != media_set_label.encryption_key_fingerprint {
bail!("detected changed encryption fingerprint - internal error");
}
- media_catalog = MediaCatalog::open(status_path, &media_id, true, false)?;
+ media_catalog = MediaCatalog::open(status_path, media_id, true, false)?;
// todo: verify last content/media_catalog somehow?
false
} else {
- worker.log(
- format!("wrinting new media set label (overwrite '{}/{}')",
- media_set_label.uuid.to_string(), media_set_label.seq_nr)
+ task_log!(
+ worker,
+ "writing new media set label (overwrite '{}/{}')",
+ media_set_label.uuid.to_string(),
+ media_set_label.seq_nr,
);
drive.write_media_set_label(new_set, key_config.as_ref())?;