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:
parent
2da7aca8e8
commit
4be4736603
@ -10,10 +10,16 @@ pub mod mtx;
|
|||||||
mod online_status_map;
|
mod online_status_map;
|
||||||
pub use online_status_map::*;
|
pub use online_status_map::*;
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use anyhow::{bail, Error};
|
use anyhow::{bail, Error};
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
|
use proxmox::api::schema::parse_property_string;
|
||||||
|
|
||||||
use crate::api2::types::{
|
use crate::api2::types::{
|
||||||
|
SLOT_ARRAY_SCHEMA,
|
||||||
ScsiTapeChanger,
|
ScsiTapeChanger,
|
||||||
LinuxTapeDrive,
|
LinuxTapeDrive,
|
||||||
};
|
};
|
||||||
@ -124,6 +130,29 @@ impl MtxStatus {
|
|||||||
}
|
}
|
||||||
free_slot
|
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
|
/// Interface to SCSI changer devices
|
||||||
@ -373,8 +402,7 @@ impl ScsiMediaChange for ScsiTapeChanger {
|
|||||||
if USE_MTX {
|
if USE_MTX {
|
||||||
mtx::mtx_status(&self)
|
mtx::mtx_status(&self)
|
||||||
} else {
|
} else {
|
||||||
let mut file = sg_pt_changer::open(&self.path)?;
|
sg_pt_changer::status(&self)
|
||||||
sg_pt_changer::read_element_status(&mut file)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,45 +1,19 @@
|
|||||||
use std::collections::HashSet;
|
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use proxmox::{
|
|
||||||
api::schema::parse_property_string,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
tools::run_command,
|
tools::run_command,
|
||||||
api2::types::{
|
api2::types::ScsiTapeChanger,
|
||||||
SLOT_ARRAY_SCHEMA,
|
tape::changer::{
|
||||||
ScsiTapeChanger,
|
|
||||||
},
|
|
||||||
tape::{
|
|
||||||
changer::{
|
|
||||||
MtxStatus,
|
MtxStatus,
|
||||||
mtx::{
|
mtx::parse_mtx_status,
|
||||||
parse_mtx_status,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Run 'mtx status' and return parsed result.
|
/// Run 'mtx status' and return parsed result.
|
||||||
pub fn mtx_status(config: &ScsiTapeChanger) -> Result<MtxStatus, Error> {
|
pub fn mtx_status(config: &ScsiTapeChanger) -> Result<MtxStatus, Error> {
|
||||||
|
|
||||||
let path = &config.path;
|
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");
|
let mut command = std::process::Command::new("mtx");
|
||||||
command.args(&["-f", path, "status"]);
|
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)?;
|
let mut status = parse_mtx_status(&output)?;
|
||||||
|
|
||||||
for (i, entry) in status.slots.iter_mut().enumerate() {
|
status.mark_import_export_slots(&config)?;
|
||||||
let slot = i as u64 + 1;
|
|
||||||
if export_slots.contains(&slot) {
|
|
||||||
entry.import_export = true; // mark as IMPORT/EXPORT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(status)
|
Ok(status)
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ use crate::{
|
|||||||
scsi_ascii_to_string,
|
scsi_ascii_to_string,
|
||||||
scsi_inquiry,
|
scsi_inquiry,
|
||||||
},
|
},
|
||||||
|
api2::types::ScsiTapeChanger,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SCSI_CHANGER_DEFAULT_TIMEOUT: usize = 60*5; // 5 minutes
|
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)
|
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)]
|
#[repr(C, packed)]
|
||||||
#[derive(Endian)]
|
#[derive(Endian)]
|
||||||
struct ElementStatusHeader {
|
struct ElementStatusHeader {
|
||||||
|
Loading…
Reference in New Issue
Block a user