tape: abort backup when we detect critical tape alert flags

This commit is contained in:
Dietmar Maurer 2021-01-09 12:34:00 +01:00
parent 7273ba3de2
commit 5843268c47
4 changed files with 40 additions and 21 deletions

View File

@ -23,6 +23,7 @@ use proxmox_backup::{
LINUX_DRIVE_PATH_SCHEMA,
},
tape::{
TapeDriver,
linux_tape::{
LinuxTapeHandle,
open_linux_tape_device,

View File

@ -317,27 +317,6 @@ impl LinuxTapeHandle {
result.map_err(|err| format_err!("{}", err))
}
/// Read Tape Alert Flags
///
/// Note: Only 'root' user may run RAW SG commands, so we need to
/// spawn setuid binary 'sg-tape-cmd'.
pub fn tape_alert_flags(&mut self) -> Result<TapeAlertFlags, Error> {
if nix::unistd::Uid::effective().is_root() {
return read_tape_alert_flags(&mut self.file);
}
let mut command = std::process::Command::new(
"/usr/lib/x86_64-linux-gnu/proxmox-backup/sg-tape-cmd");
command.args(&["tape-alert-flags"]);
command.stdin(unsafe { std::process::Stdio::from_raw_fd(self.file.as_raw_fd())});
let output = run_command(command, None)?;
let result: Result<u64, String> = serde_json::from_str(&output)?;
result
.map_err(|err| format_err!("{}", err))
.map(|bits| TapeAlertFlags::from_bits_truncate(bits))
}
/// Read Volume Statistics
///
/// Note: Only 'root' user may run RAW SG commands, so we need to
@ -479,6 +458,27 @@ impl TapeDriver for LinuxTapeHandle {
Ok(())
}
/// Read Tape Alert Flags
///
/// Note: Only 'root' user may run RAW SG commands, so we need to
/// spawn setuid binary 'sg-tape-cmd'.
fn tape_alert_flags(&mut self) -> Result<TapeAlertFlags, Error> {
if nix::unistd::Uid::effective().is_root() {
return read_tape_alert_flags(&mut self.file);
}
let mut command = std::process::Command::new(
"/usr/lib/x86_64-linux-gnu/proxmox-backup/sg-tape-cmd");
command.args(&["tape-alert-flags"]);
command.stdin(unsafe { std::process::Stdio::from_raw_fd(self.file.as_raw_fd())});
let output = run_command(command, None)?;
let result: Result<u64, String> = serde_json::from_str(&output)?;
result
.map_err(|err| format_err!("{}", err))
.map(|bits| TapeAlertFlags::from_bits_truncate(bits))
}
}
/// Write a single EOF mark without flushing buffers

View File

@ -151,6 +151,14 @@ pub trait TapeDriver {
/// Eject media
fn eject_media(&mut self) -> Result<(), Error>;
/// Read Tape Alert Flags
///
/// This make only sense for real LTO drives. Virtual tape drives should
/// simply return empty flags (default).
fn tape_alert_flags(&mut self) -> Result<TapeAlertFlags, Error> {
Ok(TapeAlertFlags::empty())
}
}
/// Get the media changer (MediaChange + name) associated with a tape drive.

View File

@ -25,6 +25,7 @@ use crate::{
MediaSetCatalog,
tape_write_snapshot_archive,
request_and_load_media,
tape_alert_flags_critical,
file_formats::MediaSetLabel,
},
};
@ -150,6 +151,15 @@ impl PoolWriter {
let (mut drive, old_media_id) =
request_and_load_media(worker, &drive_config, &self.drive_name, media.label())?;
// test for critical tape alert flags
let alert_flags = drive.tape_alert_flags()?;
if !alert_flags.is_empty() {
worker.log(format!("TapeAlertFlags: {:?}", alert_flags));
if tape_alert_flags_critical(alert_flags) {
bail!("aborting due to critical tape alert flags: {:?}", alert_flags);
}
}
let catalog = update_media_set_label(
worker,
drive.as_mut(),