tape/changer: refactor marking of import/export slots from config

we did this for 'mtx', but missed it for the sg_pt_changer code
refactor it into the MtxStatus strut, and call it from both
code paths

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
Dominik Csapak 2021-01-28 12:59:54 +01:00 committed by Dietmar Maurer
parent 2da7aca8e8
commit 4be4736603
3 changed files with 51 additions and 38 deletions

View File

@ -10,10 +10,16 @@ pub mod mtx;
mod online_status_map;
pub use online_status_map::*;
use std::collections::HashSet;
use anyhow::{bail, Error};
use serde::{Serialize, Deserialize};
use serde_json::Value;
use proxmox::api::schema::parse_property_string;
use crate::api2::types::{
SLOT_ARRAY_SCHEMA,
ScsiTapeChanger,
LinuxTapeDrive,
};
@ -124,6 +130,29 @@ impl MtxStatus {
}
free_slot
}
pub fn mark_import_export_slots(&mut self, config: &ScsiTapeChanger) -> Result<(), Error>{
let mut export_slots: HashSet<u64> = HashSet::new();
if let Some(slots) = &config.export_slots {
let slots: Value = parse_property_string(&slots, &SLOT_ARRAY_SCHEMA)?;
export_slots = slots
.as_array()
.unwrap()
.iter()
.filter_map(|v| v.as_u64())
.collect();
}
for (i, entry) in self.slots.iter_mut().enumerate() {
let slot = i as u64 + 1;
if export_slots.contains(&slot) {
entry.import_export = true; // mark as IMPORT/EXPORT
}
}
Ok(())
}
}
/// Interface to SCSI changer devices
@ -373,8 +402,7 @@ impl ScsiMediaChange for ScsiTapeChanger {
if USE_MTX {
mtx::mtx_status(&self)
} else {
let mut file = sg_pt_changer::open(&self.path)?;
sg_pt_changer::read_element_status(&mut file)
sg_pt_changer::status(&self)
}
}

View File

@ -1,45 +1,19 @@
use std::collections::HashSet;
use anyhow::Error;
use serde_json::Value;
use proxmox::{
api::schema::parse_property_string,
};
use crate::{
tools::run_command,
api2::types::{
SLOT_ARRAY_SCHEMA,
ScsiTapeChanger,
},
tape::{
changer::{
MtxStatus,
mtx::{
parse_mtx_status,
},
},
api2::types::ScsiTapeChanger,
tape::changer::{
MtxStatus,
mtx::parse_mtx_status,
},
};
/// Run 'mtx status' and return parsed result.
pub fn mtx_status(config: &ScsiTapeChanger) -> Result<MtxStatus, Error> {
let path = &config.path;
let mut export_slots: HashSet<u64> = HashSet::new();
if let Some(slots) = &config.export_slots {
let slots: Value = parse_property_string(&slots, &SLOT_ARRAY_SCHEMA)?;
export_slots = slots
.as_array()
.unwrap()
.iter()
.filter_map(|v| v.as_u64())
.collect();
}
let mut command = std::process::Command::new("mtx");
command.args(&["-f", path, "status"]);
@ -47,12 +21,7 @@ pub fn mtx_status(config: &ScsiTapeChanger) -> Result<MtxStatus, Error> {
let mut status = parse_mtx_status(&output)?;
for (i, entry) in status.slots.iter_mut().enumerate() {
let slot = i as u64 + 1;
if export_slots.contains(&slot) {
entry.import_export = true; // mark as IMPORT/EXPORT
}
}
status.mark_import_export_slots(&config)?;
Ok(status)
}

View File

@ -31,6 +31,7 @@ use crate::{
scsi_ascii_to_string,
scsi_inquiry,
},
api2::types::ScsiTapeChanger,
};
const SCSI_CHANGER_DEFAULT_TIMEOUT: usize = 60*5; // 5 minutes
@ -397,6 +398,21 @@ pub fn read_element_status<F: AsRawFd>(file: &mut F) -> Result<MtxStatus, Error>
Ok(status)
}
/// Read status and map import-export slots from config
pub fn status(config: &ScsiTapeChanger) -> Result<MtxStatus, Error> {
let path = &config.path;
let mut file = open(path)
.map_err(|err| format_err!("error opening '{}': {}", path, err))?;
let mut status = read_element_status(&mut file)
.map_err(|err| format_err!("error reading element status: {}", err))?;
status.mark_import_export_slots(&config)?;
Ok(status)
}
#[repr(C, packed)]
#[derive(Endian)]
struct ElementStatusHeader {