diff --git a/src/api2/tape/changer.rs b/src/api2/tape/changer.rs index cc155842..b01cce94 100644 --- a/src/api2/tape/changer.rs +++ b/src/api2/tape/changer.rs @@ -52,7 +52,7 @@ pub async fn get_status(name: String) -> Result, Error> { let data: ScsiTapeChanger = config.lookup("changer", &name)?; let status = tokio::task::spawn_blocking(move || { - mtx_status(&data.path) + mtx_status(&data) }).await??; let state_path = Path::new(TAPE_STATUS_DIR); diff --git a/src/tape/changer/linux_tape.rs b/src/tape/changer/linux_tape.rs index 1c7c943a..51c2c963 100644 --- a/src/tape/changer/linux_tape.rs +++ b/src/tape/changer/linux_tape.rs @@ -56,7 +56,7 @@ impl MediaChange for LinuxTapeDrive { None => bail!("drive '{}' has no associated changer", self.name), }; - let status = mtx_status(&changer.path)?; + let status = mtx_status(&changer)?; let drivenum = self.changer_drive_id.unwrap_or(0); @@ -111,7 +111,7 @@ impl MediaChange for LinuxTapeDrive { let drivenum = self.changer_drive_id.unwrap_or(0); - let status = mtx_status(&changer.path)?; + let status = mtx_status(&changer)?; unload_to_free_slot(&self.name, &changer.path, &status, drivenum) } @@ -128,7 +128,7 @@ impl MediaChange for LinuxTapeDrive { None => return Ok(Vec::new()), }; - let status = mtx_status(&changer.path)?; + let status = mtx_status(&changer)?; let mut list = Vec::new(); diff --git a/src/tape/changer/mtx_wrapper.rs b/src/tape/changer/mtx_wrapper.rs index f3edca2c..d8298653 100644 --- a/src/tape/changer/mtx_wrapper.rs +++ b/src/tape/changer/mtx_wrapper.rs @@ -1,11 +1,19 @@ use std::collections::HashSet; use anyhow::Error; +use serde_json::Value; -use proxmox::tools::Uuid; +use proxmox::{ + tools::Uuid, + api::schema::parse_property_string, +}; use crate::{ tools::run_command, + api2::types::{ + SLOT_ARRAY_SCHEMA, + ScsiTapeChanger, + }, tape::{ Inventory, changer::{ @@ -17,14 +25,35 @@ use crate::{ }; /// Run 'mtx status' and return parsed result. -pub fn mtx_status(path: &str) -> Result { +pub fn mtx_status(config: &ScsiTapeChanger) -> Result { + + let path = &config.path; + + let mut export_slots: HashSet = 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"]); let output = run_command(command, None)?; - let status = parse_mtx_status(&output)?; + 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.0 = true; // mark as IMPORT/EXPORT + } + } Ok(status) } diff --git a/src/tape/online_status_map.rs b/src/tape/online_status_map.rs index 64915e03..1b6d3f96 100644 --- a/src/tape/online_status_map.rs +++ b/src/tape/online_status_map.rs @@ -103,7 +103,7 @@ pub fn update_online_status(state_path: &Path) -> Result let mut map = OnlineStatusMap::new(&config)?; for changer in changers { - let status = match mtx_status(&changer.path) { + let status = match mtx_status(&changer) { Ok(status) => status, Err(err) => { eprintln!("unable to get changer '{}' status - {}", changer.name, err);