tape: sg-tape-cmd - add more ways to specify devices

This commit is contained in:
Dietmar Maurer 2021-01-14 13:05:26 +01:00
parent 781da7f6f0
commit 2d50a6192f
2 changed files with 91 additions and 15 deletions

View File

@ -8,7 +8,8 @@
use std::fs::File;
use std::os::unix::io::{AsRawFd, FromRawFd};
use anyhow::{bail, Error};
use anyhow::{bail, format_err, Error};
use serde_json::Value;
use proxmox::{
api::{
@ -19,8 +20,11 @@ use proxmox::{
};
use proxmox_backup::{
config,
api2::types::{
LINUX_DRIVE_PATH_SCHEMA,
DRIVE_NAME_SCHEMA,
LinuxTapeDrive,
},
tape::{
TapeDriver,
@ -32,36 +36,78 @@ use proxmox_backup::{
},
};
fn get_tape_handle(device: Option<String>) -> Result<LinuxTapeHandle, Error> {
fn get_tape_handle(param: &Value) -> Result<LinuxTapeHandle, Error> {
let file = if let Some(device) = device {
open_linux_tape_device(&device)?
} else {
let handle = if let Some(name) = param["drive"].as_str() {
let (config, _digest) = config::drive::config()?;
let drive: LinuxTapeDrive = config.lookup("linux", &name)?;
eprintln!("using device {}", drive.path);
drive.open()
.map_err(|err| format_err!("open drive '{}' ({}) failed - {}", name, drive.path, err))?
} else if let Some(device) = param["device"].as_str() {
eprintln!("using device {}", device);
LinuxTapeHandle::new(open_linux_tape_device(&device)?)
} else if let Some(true) = param["stdin"].as_bool() {
eprintln!("using stdin");
let fd = std::io::stdin().as_raw_fd();
let file = unsafe { File::from_raw_fd(fd) };
check_tape_is_linux_tape_device(&file)?;
file
LinuxTapeHandle::new(file)
} else if let Some(name) = std::env::var("PROXMOX_TAPE_DRIVE").ok() {
let (config, _digest) = config::drive::config()?;
let drive: LinuxTapeDrive = config.lookup("linux", &name)?;
eprintln!("using device {}", drive.path);
drive.open()
.map_err(|err| format_err!("open drive '{}' ({}) failed - {}", name, drive.path, err))?
} else {
let (config, _digest) = config::drive::config()?;
let mut drive_names = Vec::new();
for (name, (section_type, _)) in config.sections.iter() {
if section_type != "linux" { continue; }
drive_names.push(name);
}
if drive_names.len() == 1 {
let name = drive_names[0];
let drive: LinuxTapeDrive = config.lookup("linux", &name)?;
eprintln!("using device {}", drive.path);
drive.open()
.map_err(|err| format_err!("open drive '{}' ({}) failed - {}", name, drive.path, err))?
} else {
bail!("no drive/device specified");
}
};
Ok(LinuxTapeHandle::new(file))
Ok(handle)
}
#[api(
input: {
properties: {
drive: {
schema: DRIVE_NAME_SCHEMA,
optional: true,
},
device: {
schema: LINUX_DRIVE_PATH_SCHEMA,
optional: true,
},
stdin: {
description: "Use standard input as device handle.",
type: bool,
optional: true,
},
},
},
)]
/// Tape/Media Status
fn status(
device: Option<String>,
param: Value,
) -> Result<(), Error> {
let result = proxmox::try_block!({
let mut handle = get_tape_handle(device)?;
let mut handle = get_tape_handle(&param)?;
handle.get_drive_and_media_status()
}).map_err(|err: Error| err.to_string());
@ -73,20 +119,29 @@ fn status(
#[api(
input: {
properties: {
drive: {
schema: DRIVE_NAME_SCHEMA,
optional: true,
},
device: {
schema: LINUX_DRIVE_PATH_SCHEMA,
optional: true,
},
stdin: {
description: "Use standard input as device handle.",
type: bool,
optional: true,
},
},
},
)]
/// Read Cartridge Memory (Medium auxiliary memory attributes)
fn cartridge_memory(
device: Option<String>,
param: Value,
) -> Result<(), Error> {
let result = proxmox::try_block!({
let mut handle = get_tape_handle(device)?;
let mut handle = get_tape_handle(&param)?;
handle.cartridge_memory()
}).map_err(|err| err.to_string());
@ -99,20 +154,29 @@ fn cartridge_memory(
#[api(
input: {
properties: {
drive: {
schema: DRIVE_NAME_SCHEMA,
optional: true,
},
device: {
schema: LINUX_DRIVE_PATH_SCHEMA,
optional: true,
},
stdin: {
description: "Use standard input as device handle.",
type: bool,
optional: true,
},
},
},
)]
/// Read Tape Alert Flags
fn tape_alert_flags(
device: Option<String>,
param: Value,
) -> Result<(), Error> {
let result = proxmox::try_block!({
let mut handle = get_tape_handle(device)?;
let mut handle = get_tape_handle(&param)?;
let flags = handle.tape_alert_flags()?;
Ok(flags.bits())
@ -126,20 +190,29 @@ fn tape_alert_flags(
#[api(
input: {
properties: {
drive: {
schema: DRIVE_NAME_SCHEMA,
optional: true,
},
device: {
schema: LINUX_DRIVE_PATH_SCHEMA,
optional: true,
},
stdin: {
description: "Use standard input as device handle.",
type: bool,
optional: true,
},
},
},
)]
/// Read volume statistics
fn volume_statistics(
device: Option<String>,
param: Value,
) -> Result<(), Error> {
let result = proxmox::try_block!({
let mut handle = get_tape_handle(device)?;
let mut handle = get_tape_handle(&param)?;
handle.volume_statistics()
}).map_err(|err: Error| err.to_string());

View File

@ -331,6 +331,7 @@ impl LinuxTapeHandle {
let mut command = std::process::Command::new(
"/usr/lib/x86_64-linux-gnu/proxmox-backup/sg-tape-cmd");
command.args(&["cartridge-memory"]);
command.args(&["--stdin"]);
command.stdin(unsafe { std::process::Stdio::from_raw_fd(self.file.as_raw_fd())});
let output = run_command(command, None)?;
let result: Result<Vec<MamAttribute>, String> = serde_json::from_str(&output)?;
@ -350,6 +351,7 @@ impl LinuxTapeHandle {
let mut command = std::process::Command::new(
"/usr/lib/x86_64-linux-gnu/proxmox-backup/sg-tape-cmd");
command.args(&["volume-statistics"]);
command.args(&["--stdin"]);
command.stdin(unsafe { std::process::Stdio::from_raw_fd(self.file.as_raw_fd())});
let output = run_command(command, None)?;
let result: Result<Lp17VolumeStatistics, String> = serde_json::from_str(&output)?;
@ -492,6 +494,7 @@ impl TapeDriver for LinuxTapeHandle {
let mut command = std::process::Command::new(
"/usr/lib/x86_64-linux-gnu/proxmox-backup/sg-tape-cmd");
command.args(&["tape-alert-flags"]);
command.args(&["--stdin"]);
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)?;