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);
|
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 {
|
let entry = MtxStatusEntry {
|
||||||
entry_kind: MtxEntryKind::Slot,
|
entry_kind: if *import_export {
|
||||||
|
MtxEntryKind::ImportExport
|
||||||
|
} else {
|
||||||
|
MtxEntryKind::Slot
|
||||||
|
},
|
||||||
entry_id: id as u64 + 1,
|
entry_id: id as u64 + 1,
|
||||||
changer_id: match &slot_status {
|
changer_id: match &slot_status {
|
||||||
ElementStatus::Empty => None,
|
ElementStatus::Empty => None,
|
||||||
|
@ -44,13 +44,15 @@ pub struct ScsiTapeChanger {
|
|||||||
|
|
||||||
#[api()]
|
#[api()]
|
||||||
#[derive(Serialize,Deserialize)]
|
#[derive(Serialize,Deserialize)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
/// Mtx Entry Kind
|
/// Mtx Entry Kind
|
||||||
pub enum MtxEntryKind {
|
pub enum MtxEntryKind {
|
||||||
/// Drive
|
/// Drive
|
||||||
Drive,
|
Drive,
|
||||||
/// Slot
|
/// Slot
|
||||||
Slot,
|
Slot,
|
||||||
|
/// Import/Export Slot
|
||||||
|
ImportExport,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[api(
|
#[api(
|
||||||
|
@ -207,6 +207,8 @@ async fn get_status(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let options = default_table_format_options()
|
let options = default_table_format_options()
|
||||||
|
.sortby("entry-kind", false)
|
||||||
|
.sortby("entry-id", false)
|
||||||
.column(ColumnConfig::new("entry-kind"))
|
.column(ColumnConfig::new("entry-kind"))
|
||||||
.column(ColumnConfig::new("entry-id"))
|
.column(ColumnConfig::new("entry-id"))
|
||||||
.column(ColumnConfig::new("changer-id"))
|
.column(ColumnConfig::new("changer-id"))
|
||||||
|
@ -27,7 +27,8 @@ fn unload_to_free_slot(drive_name: &str, path: &str, status: &MtxStatus, drivenu
|
|||||||
} else {
|
} else {
|
||||||
let mut free_slot = None;
|
let mut free_slot = None;
|
||||||
for i in 0..status.slots.len() {
|
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);
|
free_slot = Some((i+1) as u64);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -79,9 +80,12 @@ impl MediaChange for LinuxTapeDrive {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut slot = None;
|
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 let ElementStatus::VolumeTag(tag) = element_status {
|
||||||
if *tag == changer_id {
|
if *tag == changer_id {
|
||||||
|
if *import_export {
|
||||||
|
bail!("unable to load media '{}' - inside import/export slot", changer_id);
|
||||||
|
}
|
||||||
slot = Some(i+1);
|
slot = Some(i+1);
|
||||||
break;
|
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 {
|
if let ElementStatus::VolumeTag(ref tag) = element_status {
|
||||||
list.push(tag.clone());
|
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 ElementStatus::VolumeTag(ref changer_id) = slot_status {
|
||||||
if let Some(media_id) = inventory.find_media_by_changer_id(changer_id) {
|
if let Some(media_id) = inventory.find_media_by_changer_id(changer_id) {
|
||||||
online_set.insert(media_id.label.uuid.clone());
|
online_set.insert(media_id.label.uuid.clone());
|
||||||
|
@ -31,8 +31,8 @@ pub struct DriveStatus {
|
|||||||
pub struct MtxStatus {
|
pub struct MtxStatus {
|
||||||
/// List of known drives
|
/// List of known drives
|
||||||
pub drives: Vec<DriveStatus>,
|
pub drives: Vec<DriveStatus>,
|
||||||
/// List of known slots
|
/// List of known slots, the boolean attribute marks import/export slots
|
||||||
pub slots: Vec<ElementStatus>,
|
pub slots: Vec<(bool, ElementStatus)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recognizes one line
|
// Recognizes one line
|
||||||
@ -122,17 +122,19 @@ fn parse_data_transfer_element(i: &str) -> IResult<&str, (u64, DriveStatus)> {
|
|||||||
Ok((i, (id, element_status)))
|
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, _) = multispace1(i)?;
|
||||||
let (i, _) = tag("Storage Element")(i)?;
|
let (i, _) = tag("Storage Element")(i)?;
|
||||||
let (i, _) = multispace1(i)?;
|
let (i, _) = multispace1(i)?;
|
||||||
let (i, id) = parse_u64(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, _) = nom::character::complete::char(':')(i)?;
|
||||||
let (i, element_status) = parse_slot_status(i)?;
|
let (i, element_status) = parse_slot_status(i)?;
|
||||||
let (i, _) = nom::character::complete::newline(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> {
|
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();
|
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) {
|
if id != (slots.len() as u64 + 1) {
|
||||||
return Err(parse_failure(i, "unexpected slot number"));
|
return Err(parse_failure(i, "unexpected slot number"));
|
||||||
}
|
}
|
||||||
i = n;
|
i = n;
|
||||||
slots.push(element_status);
|
slots.push((import_export, element_status));
|
||||||
}
|
}
|
||||||
|
|
||||||
let status = MtxStatus { drives, slots };
|
let status = MtxStatus { drives, slots };
|
||||||
|
Loading…
Reference in New Issue
Block a user