tape: correctly parse mtx import/export slots

This commit is contained in:
Dietmar Maurer 2020-12-28 13:32:56 +01:00
parent df3a74d7e0
commit e0362b0d0f
6 changed files with 29 additions and 13 deletions

View File

@ -82,9 +82,13 @@ pub async fn get_status(name: String) -> Result<Vec<MtxStatusEntry>, Error> {
list.push(entry);
}
for (id, slot_status) in status.slots.iter().enumerate() {
for (id, (import_export, slot_status)) in status.slots.iter().enumerate() {
let entry = MtxStatusEntry {
entry_kind: MtxEntryKind::Slot,
entry_kind: if *import_export {
MtxEntryKind::ImportExport
} else {
MtxEntryKind::Slot
},
entry_id: id as u64 + 1,
changer_id: match &slot_status {
ElementStatus::Empty => None,

View File

@ -44,13 +44,15 @@ pub struct ScsiTapeChanger {
#[api()]
#[derive(Serialize,Deserialize)]
#[serde(rename_all = "lowercase")]
#[serde(rename_all = "kebab-case")]
/// Mtx Entry Kind
pub enum MtxEntryKind {
/// Drive
Drive,
/// Slot
Slot,
/// Import/Export Slot
ImportExport,
}
#[api(

View File

@ -207,6 +207,8 @@ async fn get_status(
};
let options = default_table_format_options()
.sortby("entry-kind", false)
.sortby("entry-id", false)
.column(ColumnConfig::new("entry-kind"))
.column(ColumnConfig::new("entry-id"))
.column(ColumnConfig::new("changer-id"))

View File

@ -27,7 +27,8 @@ fn unload_to_free_slot(drive_name: &str, path: &str, status: &MtxStatus, drivenu
} else {
let mut free_slot = None;
for i in 0..status.slots.len() {
if let ElementStatus::Empty = status.slots[i] {
if status.slots[i].0 { continue; } // skip import/export slots
if let ElementStatus::Empty = status.slots[i].1 {
free_slot = Some((i+1) as u64);
break;
}
@ -79,9 +80,12 @@ impl MediaChange for LinuxTapeDrive {
}
let mut slot = None;
for (i, element_status) in status.slots.iter().enumerate() {
for (i, (import_export, element_status)) in status.slots.iter().enumerate() {
if let ElementStatus::VolumeTag(tag) = element_status {
if *tag == changer_id {
if *import_export {
bail!("unable to load media '{}' - inside import/export slot", changer_id);
}
slot = Some(i+1);
break;
}
@ -134,7 +138,8 @@ impl MediaChange for LinuxTapeDrive {
}
}
for element_status in status.slots.iter() {
for (import_export, element_status) in status.slots.iter() {
if *import_export { continue; }
if let ElementStatus::VolumeTag(ref tag) = element_status {
list.push(tag.clone());
}

View File

@ -87,7 +87,8 @@ pub fn mtx_status_to_online_set(status: &MtxStatus, inventory: &Inventory) -> Ha
}
}
for slot_status in status.slots.iter() {
for (import_export, slot_status) in status.slots.iter() {
if *import_export { continue; }
if let ElementStatus::VolumeTag(ref changer_id) = slot_status {
if let Some(media_id) = inventory.find_media_by_changer_id(changer_id) {
online_set.insert(media_id.label.uuid.clone());

View File

@ -31,8 +31,8 @@ pub struct DriveStatus {
pub struct MtxStatus {
/// List of known drives
pub drives: Vec<DriveStatus>,
/// List of known slots
pub slots: Vec<ElementStatus>,
/// List of known slots, the boolean attribute marks import/export slots
pub slots: Vec<(bool, ElementStatus)>,
}
// Recognizes one line
@ -122,17 +122,19 @@ fn parse_data_transfer_element(i: &str) -> IResult<&str, (u64, DriveStatus)> {
Ok((i, (id, element_status)))
}
fn parse_storage_element(i: &str) -> IResult<&str, (u64, ElementStatus)> {
fn parse_storage_element(i: &str) -> IResult<&str, (u64, bool, ElementStatus)> {
let (i, _) = multispace1(i)?;
let (i, _) = tag("Storage Element")(i)?;
let (i, _) = multispace1(i)?;
let (i, id) = parse_u64(i)?;
let (i, opt_ie) = nom::combinator::opt(tag(" IMPORT/EXPORT"))(i)?;
let import_export = opt_ie.is_some();
let (i, _) = nom::character::complete::char(':')(i)?;
let (i, element_status) = parse_slot_status(i)?;
let (i, _) = nom::character::complete::newline(i)?;
Ok((i, (id, element_status)))
Ok((i, (id, import_export, element_status)))
}
fn parse_status(i: &str) -> IResult<&str, MtxStatus> {
@ -149,12 +151,12 @@ fn parse_status(i: &str) -> IResult<&str, MtxStatus> {
}
let mut slots = Vec::new();
while let Ok((n, (id, element_status))) = parse_storage_element(i) {
while let Ok((n, (id, import_export, element_status))) = parse_storage_element(i) {
if id != (slots.len() as u64 + 1) {
return Err(parse_failure(i, "unexpected slot number"));
}
i = n;
slots.push(element_status);
slots.push((import_export, element_status));
}
let status = MtxStatus { drives, slots };