tape: correctly parse mtx import/export slots
This commit is contained in:
parent
df3a74d7e0
commit
e0362b0d0f
@ -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,
|
||||
|
@ -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(
|
||||
|
@ -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"))
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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 };
|
||||
|
Loading…
Reference in New Issue
Block a user