tape: sg-tape-cmd - add more ways to specify devices
This commit is contained in:
parent
781da7f6f0
commit
2d50a6192f
@ -8,7 +8,8 @@
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::os::unix::io::{AsRawFd, FromRawFd};
|
use std::os::unix::io::{AsRawFd, FromRawFd};
|
||||||
|
|
||||||
use anyhow::{bail, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
use proxmox::{
|
use proxmox::{
|
||||||
api::{
|
api::{
|
||||||
@ -19,8 +20,11 @@ use proxmox::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use proxmox_backup::{
|
use proxmox_backup::{
|
||||||
|
config,
|
||||||
api2::types::{
|
api2::types::{
|
||||||
LINUX_DRIVE_PATH_SCHEMA,
|
LINUX_DRIVE_PATH_SCHEMA,
|
||||||
|
DRIVE_NAME_SCHEMA,
|
||||||
|
LinuxTapeDrive,
|
||||||
},
|
},
|
||||||
tape::{
|
tape::{
|
||||||
TapeDriver,
|
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 {
|
let handle = if let Some(name) = param["drive"].as_str() {
|
||||||
open_linux_tape_device(&device)?
|
let (config, _digest) = config::drive::config()?;
|
||||||
} else {
|
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 fd = std::io::stdin().as_raw_fd();
|
||||||
let file = unsafe { File::from_raw_fd(fd) };
|
let file = unsafe { File::from_raw_fd(fd) };
|
||||||
check_tape_is_linux_tape_device(&file)?;
|
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(
|
#[api(
|
||||||
input: {
|
input: {
|
||||||
properties: {
|
properties: {
|
||||||
|
drive: {
|
||||||
|
schema: DRIVE_NAME_SCHEMA,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
device: {
|
device: {
|
||||||
schema: LINUX_DRIVE_PATH_SCHEMA,
|
schema: LINUX_DRIVE_PATH_SCHEMA,
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
stdin: {
|
||||||
|
description: "Use standard input as device handle.",
|
||||||
|
type: bool,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Tape/Media Status
|
/// Tape/Media Status
|
||||||
fn status(
|
fn status(
|
||||||
device: Option<String>,
|
param: Value,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
|
||||||
let result = proxmox::try_block!({
|
let result = proxmox::try_block!({
|
||||||
let mut handle = get_tape_handle(device)?;
|
let mut handle = get_tape_handle(¶m)?;
|
||||||
handle.get_drive_and_media_status()
|
handle.get_drive_and_media_status()
|
||||||
}).map_err(|err: Error| err.to_string());
|
}).map_err(|err: Error| err.to_string());
|
||||||
|
|
||||||
@ -73,20 +119,29 @@ fn status(
|
|||||||
#[api(
|
#[api(
|
||||||
input: {
|
input: {
|
||||||
properties: {
|
properties: {
|
||||||
|
drive: {
|
||||||
|
schema: DRIVE_NAME_SCHEMA,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
device: {
|
device: {
|
||||||
schema: LINUX_DRIVE_PATH_SCHEMA,
|
schema: LINUX_DRIVE_PATH_SCHEMA,
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
stdin: {
|
||||||
|
description: "Use standard input as device handle.",
|
||||||
|
type: bool,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Read Cartridge Memory (Medium auxiliary memory attributes)
|
/// Read Cartridge Memory (Medium auxiliary memory attributes)
|
||||||
fn cartridge_memory(
|
fn cartridge_memory(
|
||||||
device: Option<String>,
|
param: Value,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
|
||||||
let result = proxmox::try_block!({
|
let result = proxmox::try_block!({
|
||||||
let mut handle = get_tape_handle(device)?;
|
let mut handle = get_tape_handle(¶m)?;
|
||||||
|
|
||||||
handle.cartridge_memory()
|
handle.cartridge_memory()
|
||||||
}).map_err(|err| err.to_string());
|
}).map_err(|err| err.to_string());
|
||||||
@ -99,20 +154,29 @@ fn cartridge_memory(
|
|||||||
#[api(
|
#[api(
|
||||||
input: {
|
input: {
|
||||||
properties: {
|
properties: {
|
||||||
|
drive: {
|
||||||
|
schema: DRIVE_NAME_SCHEMA,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
device: {
|
device: {
|
||||||
schema: LINUX_DRIVE_PATH_SCHEMA,
|
schema: LINUX_DRIVE_PATH_SCHEMA,
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
stdin: {
|
||||||
|
description: "Use standard input as device handle.",
|
||||||
|
type: bool,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Read Tape Alert Flags
|
/// Read Tape Alert Flags
|
||||||
fn tape_alert_flags(
|
fn tape_alert_flags(
|
||||||
device: Option<String>,
|
param: Value,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
|
||||||
let result = proxmox::try_block!({
|
let result = proxmox::try_block!({
|
||||||
let mut handle = get_tape_handle(device)?;
|
let mut handle = get_tape_handle(¶m)?;
|
||||||
|
|
||||||
let flags = handle.tape_alert_flags()?;
|
let flags = handle.tape_alert_flags()?;
|
||||||
Ok(flags.bits())
|
Ok(flags.bits())
|
||||||
@ -126,20 +190,29 @@ fn tape_alert_flags(
|
|||||||
#[api(
|
#[api(
|
||||||
input: {
|
input: {
|
||||||
properties: {
|
properties: {
|
||||||
|
drive: {
|
||||||
|
schema: DRIVE_NAME_SCHEMA,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
device: {
|
device: {
|
||||||
schema: LINUX_DRIVE_PATH_SCHEMA,
|
schema: LINUX_DRIVE_PATH_SCHEMA,
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
stdin: {
|
||||||
|
description: "Use standard input as device handle.",
|
||||||
|
type: bool,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Read volume statistics
|
/// Read volume statistics
|
||||||
fn volume_statistics(
|
fn volume_statistics(
|
||||||
device: Option<String>,
|
param: Value,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
|
||||||
let result = proxmox::try_block!({
|
let result = proxmox::try_block!({
|
||||||
let mut handle = get_tape_handle(device)?;
|
let mut handle = get_tape_handle(¶m)?;
|
||||||
handle.volume_statistics()
|
handle.volume_statistics()
|
||||||
}).map_err(|err: Error| err.to_string());
|
}).map_err(|err: Error| err.to_string());
|
||||||
|
|
||||||
|
@ -331,6 +331,7 @@ impl LinuxTapeHandle {
|
|||||||
let mut command = std::process::Command::new(
|
let mut command = std::process::Command::new(
|
||||||
"/usr/lib/x86_64-linux-gnu/proxmox-backup/sg-tape-cmd");
|
"/usr/lib/x86_64-linux-gnu/proxmox-backup/sg-tape-cmd");
|
||||||
command.args(&["cartridge-memory"]);
|
command.args(&["cartridge-memory"]);
|
||||||
|
command.args(&["--stdin"]);
|
||||||
command.stdin(unsafe { std::process::Stdio::from_raw_fd(self.file.as_raw_fd())});
|
command.stdin(unsafe { std::process::Stdio::from_raw_fd(self.file.as_raw_fd())});
|
||||||
let output = run_command(command, None)?;
|
let output = run_command(command, None)?;
|
||||||
let result: Result<Vec<MamAttribute>, String> = serde_json::from_str(&output)?;
|
let result: Result<Vec<MamAttribute>, String> = serde_json::from_str(&output)?;
|
||||||
@ -350,6 +351,7 @@ impl LinuxTapeHandle {
|
|||||||
let mut command = std::process::Command::new(
|
let mut command = std::process::Command::new(
|
||||||
"/usr/lib/x86_64-linux-gnu/proxmox-backup/sg-tape-cmd");
|
"/usr/lib/x86_64-linux-gnu/proxmox-backup/sg-tape-cmd");
|
||||||
command.args(&["volume-statistics"]);
|
command.args(&["volume-statistics"]);
|
||||||
|
command.args(&["--stdin"]);
|
||||||
command.stdin(unsafe { std::process::Stdio::from_raw_fd(self.file.as_raw_fd())});
|
command.stdin(unsafe { std::process::Stdio::from_raw_fd(self.file.as_raw_fd())});
|
||||||
let output = run_command(command, None)?;
|
let output = run_command(command, None)?;
|
||||||
let result: Result<Lp17VolumeStatistics, String> = serde_json::from_str(&output)?;
|
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(
|
let mut command = std::process::Command::new(
|
||||||
"/usr/lib/x86_64-linux-gnu/proxmox-backup/sg-tape-cmd");
|
"/usr/lib/x86_64-linux-gnu/proxmox-backup/sg-tape-cmd");
|
||||||
command.args(&["tape-alert-flags"]);
|
command.args(&["tape-alert-flags"]);
|
||||||
|
command.args(&["--stdin"]);
|
||||||
command.stdin(unsafe { std::process::Stdio::from_raw_fd(self.file.as_raw_fd())});
|
command.stdin(unsafe { std::process::Stdio::from_raw_fd(self.file.as_raw_fd())});
|
||||||
let output = run_command(command, None)?;
|
let output = run_command(command, None)?;
|
||||||
let result: Result<u64, String> = serde_json::from_str(&output)?;
|
let result: Result<u64, String> = serde_json::from_str(&output)?;
|
||||||
|
Loading…
Reference in New Issue
Block a user