tape: abort backup when we detect critical tape alert flags
This commit is contained in:
parent
7273ba3de2
commit
5843268c47
@ -23,6 +23,7 @@ use proxmox_backup::{
|
|||||||
LINUX_DRIVE_PATH_SCHEMA,
|
LINUX_DRIVE_PATH_SCHEMA,
|
||||||
},
|
},
|
||||||
tape::{
|
tape::{
|
||||||
|
TapeDriver,
|
||||||
linux_tape::{
|
linux_tape::{
|
||||||
LinuxTapeHandle,
|
LinuxTapeHandle,
|
||||||
open_linux_tape_device,
|
open_linux_tape_device,
|
||||||
|
@ -317,27 +317,6 @@ impl LinuxTapeHandle {
|
|||||||
result.map_err(|err| format_err!("{}", err))
|
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
|
/// Read Volume Statistics
|
||||||
///
|
///
|
||||||
/// Note: Only 'root' user may run RAW SG commands, so we need to
|
/// Note: Only 'root' user may run RAW SG commands, so we need to
|
||||||
@ -479,6 +458,27 @@ impl TapeDriver for LinuxTapeHandle {
|
|||||||
|
|
||||||
Ok(())
|
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
|
/// Write a single EOF mark without flushing buffers
|
||||||
|
@ -151,6 +151,14 @@ pub trait TapeDriver {
|
|||||||
|
|
||||||
/// Eject media
|
/// Eject media
|
||||||
fn eject_media(&mut self) -> Result<(), Error>;
|
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.
|
/// Get the media changer (MediaChange + name) associated with a tape drive.
|
||||||
|
@ -25,6 +25,7 @@ use crate::{
|
|||||||
MediaSetCatalog,
|
MediaSetCatalog,
|
||||||
tape_write_snapshot_archive,
|
tape_write_snapshot_archive,
|
||||||
request_and_load_media,
|
request_and_load_media,
|
||||||
|
tape_alert_flags_critical,
|
||||||
file_formats::MediaSetLabel,
|
file_formats::MediaSetLabel,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -150,6 +151,15 @@ impl PoolWriter {
|
|||||||
let (mut drive, old_media_id) =
|
let (mut drive, old_media_id) =
|
||||||
request_and_load_media(worker, &drive_config, &self.drive_name, media.label())?;
|
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(
|
let catalog = update_media_set_label(
|
||||||
worker,
|
worker,
|
||||||
drive.as_mut(),
|
drive.as_mut(),
|
||||||
|
Loading…
Reference in New Issue
Block a user