diff --git a/src/bin/sg-tape-cmd.rs b/src/bin/sg-tape-cmd.rs index 5e1ff5dd..dcc26f6d 100644 --- a/src/bin/sg-tape-cmd.rs +++ b/src/bin/sg-tape-cmd.rs @@ -95,6 +95,33 @@ fn cartridge_memory( Ok(()) } +#[api( + input: { + properties: { + device: { + schema: LINUX_DRIVE_PATH_SCHEMA, + optional: true, + }, + }, + }, +)] +/// Read Tape Alert Flags +fn tape_alert_flags( + device: Option, +) -> Result<(), Error> { + + let result = proxmox::try_block!({ + let mut handle = get_tape_handle(device)?; + + let flags = handle.tape_alert_flags()?; + Ok(flags.bits()) + }).map_err(|err: Error| err.to_string()); + + println!("{}", serde_json::to_string_pretty(&result)?); + + Ok(()) +} + fn main() -> Result<(), Error> { // check if we are user root or backup @@ -126,6 +153,10 @@ fn main() -> Result<(), Error> { "cartridge-memory", CliCommand::new(&API_METHOD_CARTRIDGE_MEMORY) ) + .insert( + "tape-alert-flags", + CliCommand::new(&API_METHOD_TAPE_ALERT_FLAGS) + ) ; let mut rpcenv = CliEnvironment::new(); diff --git a/src/tape/drive/linux_tape.rs b/src/tape/drive/linux_tape.rs index 42b5fd78..fcf4c7ef 100644 --- a/src/tape/drive/linux_tape.rs +++ b/src/tape/drive/linux_tape.rs @@ -18,8 +18,10 @@ use crate::{ tape::{ TapeRead, TapeWrite, + TapeAlertFlags, read_mam_attributes, mam_extract_media_usage, + read_tape_alert_flags, drive::{ LinuxTapeDrive, TapeDriver, @@ -294,6 +296,27 @@ impl LinuxTapeHandle { let result: Result, String> = serde_json::from_str(&output)?; 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 { + + 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 = serde_json::from_str(&output)?; + result + .map_err(|err| format_err!("{}", err)) + .map(|bits| TapeAlertFlags::from_bits_truncate(bits)) + } } diff --git a/src/tape/drive/mam.rs b/src/tape/drive/mam.rs index c4f31155..1153863e 100644 --- a/src/tape/drive/mam.rs +++ b/src/tape/drive/mam.rs @@ -10,7 +10,7 @@ use proxmox::tools::io::ReadExt; use crate::{ api2::types::MamAttribute, tape::{ - tape_alert_flags::TapeAlertFlags, + TapeAlertFlags, sgutils2::SgRaw, }, }; diff --git a/src/tape/drive/mod.rs b/src/tape/drive/mod.rs index 75a690bb..7c4262c2 100644 --- a/src/tape/drive/mod.rs +++ b/src/tape/drive/mod.rs @@ -1,7 +1,9 @@ mod virtual_tape; mod linux_mtio; -pub mod tape_alert_flags; +mod tape_alert_flags; +pub use tape_alert_flags::*; + pub mod linux_tape; mod mam;