tape: avoid executor blocking in drive API
By using tokio::task::spawn_blocking().
This commit is contained in:
parent
2d87f2fb73
commit
66dbe5639e
@ -70,7 +70,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Load media via changer from slot
|
/// Load media via changer from slot
|
||||||
pub fn load_slot(
|
pub async fn load_slot(
|
||||||
drive: String,
|
drive: String,
|
||||||
slot: u64,
|
slot: u64,
|
||||||
_param: Value,
|
_param: Value,
|
||||||
@ -85,9 +85,10 @@ pub fn load_slot(
|
|||||||
None => bail!("drive '{}' has no associated changer", drive),
|
None => bail!("drive '{}' has no associated changer", drive),
|
||||||
};
|
};
|
||||||
|
|
||||||
let drivenum = drive_config.changer_drive_id.unwrap_or(0);
|
tokio::task::spawn_blocking(move || {
|
||||||
|
let drivenum = drive_config.changer_drive_id.unwrap_or(0);
|
||||||
mtx_load(&changer.path, slot, drivenum)
|
mtx_load(&changer.path, slot, drivenum)
|
||||||
|
}).await?
|
||||||
}
|
}
|
||||||
|
|
||||||
#[api(
|
#[api(
|
||||||
@ -105,15 +106,14 @@ pub fn load_slot(
|
|||||||
/// Load media with specified label
|
/// Load media with specified label
|
||||||
///
|
///
|
||||||
/// Issue a media load request to the associated changer device.
|
/// Issue a media load request to the associated changer device.
|
||||||
pub fn load_media(drive: String, changer_id: String) -> Result<(), Error> {
|
pub async fn load_media(drive: String, changer_id: String) -> Result<(), Error> {
|
||||||
|
|
||||||
let (config, _digest) = config::drive::config()?;
|
let (config, _digest) = config::drive::config()?;
|
||||||
|
|
||||||
let (mut changer, _) = media_changer(&config, &drive, false)?;
|
tokio::task::spawn_blocking(move || {
|
||||||
|
let (mut changer, _) = media_changer(&config, &drive, false)?;
|
||||||
changer.load_media(&changer_id)?;
|
changer.load_media(&changer_id)
|
||||||
|
}).await?
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[api(
|
#[api(
|
||||||
@ -131,7 +131,7 @@ pub fn load_media(drive: String, changer_id: String) -> Result<(), Error> {
|
|||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Unload media via changer
|
/// Unload media via changer
|
||||||
pub fn unload(
|
pub async fn unload(
|
||||||
drive: String,
|
drive: String,
|
||||||
slot: Option<u64>,
|
slot: Option<u64>,
|
||||||
_param: Value,
|
_param: Value,
|
||||||
@ -146,13 +146,15 @@ pub fn unload(
|
|||||||
None => bail!("drive '{}' has no associated changer", drive),
|
None => bail!("drive '{}' has no associated changer", drive),
|
||||||
};
|
};
|
||||||
|
|
||||||
let drivenum: u64 = 0;
|
let drivenum = drive_config.changer_drive_id.unwrap_or(0);
|
||||||
|
|
||||||
if let Some(slot) = slot {
|
tokio::task::spawn_blocking(move || {
|
||||||
mtx_unload(&changer.path, slot, drivenum)
|
if let Some(slot) = slot {
|
||||||
} else {
|
mtx_unload(&changer.path, slot, drivenum)
|
||||||
drive_config.unload_media()
|
} else {
|
||||||
}
|
drive_config.unload_media()
|
||||||
|
}
|
||||||
|
}).await?
|
||||||
}
|
}
|
||||||
|
|
||||||
#[api(
|
#[api(
|
||||||
@ -270,20 +272,20 @@ pub fn rewind(
|
|||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Eject/Unload drive media
|
/// Eject/Unload drive media
|
||||||
pub fn eject_media(drive: String) -> Result<(), Error> {
|
pub async fn eject_media(drive: String) -> Result<(), Error> {
|
||||||
|
|
||||||
let (config, _digest) = config::drive::config()?;
|
let (config, _digest) = config::drive::config()?;
|
||||||
|
|
||||||
let (mut changer, _) = media_changer(&config, &drive, false)?;
|
tokio::task::spawn_blocking(move || {
|
||||||
|
let (mut changer, _) = media_changer(&config, &drive, false)?;
|
||||||
|
|
||||||
if !changer.eject_on_unload() {
|
if !changer.eject_on_unload() {
|
||||||
let mut drive = open_drive(&config, &drive)?;
|
let mut drive = open_drive(&config, &drive)?;
|
||||||
drive.eject_media()?;
|
drive.eject_media()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
changer.unload_media()?;
|
changer.unload_media()
|
||||||
|
}).await?
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[api(
|
#[api(
|
||||||
@ -439,39 +441,41 @@ fn write_media_label(
|
|||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Read media label
|
/// Read media label
|
||||||
pub fn read_label(drive: String) -> Result<MediaLabelInfoFlat, Error> {
|
pub async fn read_label(drive: String) -> Result<MediaLabelInfoFlat, Error> {
|
||||||
|
|
||||||
let (config, _digest) = config::drive::config()?;
|
let (config, _digest) = config::drive::config()?;
|
||||||
|
|
||||||
let mut drive = open_drive(&config, &drive)?;
|
tokio::task::spawn_blocking(move || {
|
||||||
|
let mut drive = open_drive(&config, &drive)?;
|
||||||
|
|
||||||
let info = drive.read_label()?;
|
let info = drive.read_label()?;
|
||||||
|
|
||||||
let info = match info {
|
let info = match info {
|
||||||
Some(info) => {
|
Some(info) => {
|
||||||
let mut flat = MediaLabelInfoFlat {
|
let mut flat = MediaLabelInfoFlat {
|
||||||
uuid: info.label.uuid.to_string(),
|
uuid: info.label.uuid.to_string(),
|
||||||
changer_id: info.label.changer_id.clone(),
|
changer_id: info.label.changer_id.clone(),
|
||||||
ctime: info.label.ctime,
|
ctime: info.label.ctime,
|
||||||
media_set_ctime: None,
|
media_set_ctime: None,
|
||||||
media_set_uuid: None,
|
media_set_uuid: None,
|
||||||
pool: None,
|
pool: None,
|
||||||
seq_nr: None,
|
seq_nr: None,
|
||||||
};
|
};
|
||||||
if let Some((set, _)) = info.media_set_label {
|
if let Some((set, _)) = info.media_set_label {
|
||||||
flat.pool = Some(set.pool.clone());
|
flat.pool = Some(set.pool.clone());
|
||||||
flat.seq_nr = Some(set.seq_nr);
|
flat.seq_nr = Some(set.seq_nr);
|
||||||
flat.media_set_uuid = Some(set.uuid.to_string());
|
flat.media_set_uuid = Some(set.uuid.to_string());
|
||||||
flat.media_set_ctime = Some(set.ctime);
|
flat.media_set_ctime = Some(set.ctime);
|
||||||
|
}
|
||||||
|
flat
|
||||||
}
|
}
|
||||||
flat
|
None => {
|
||||||
}
|
bail!("Media is empty (no label).");
|
||||||
None => {
|
}
|
||||||
bail!("Media is empty (no label).");
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(info)
|
Ok(info)
|
||||||
|
}).await?
|
||||||
}
|
}
|
||||||
|
|
||||||
#[api(
|
#[api(
|
||||||
@ -497,41 +501,49 @@ pub fn read_label(drive: String) -> Result<MediaLabelInfoFlat, Error> {
|
|||||||
/// This method queries the changer to get a list of media labels.
|
/// This method queries the changer to get a list of media labels.
|
||||||
///
|
///
|
||||||
/// Note: This updates the media online status.
|
/// Note: This updates the media online status.
|
||||||
pub fn inventory(
|
pub async fn inventory(
|
||||||
drive: String,
|
drive: String,
|
||||||
) -> Result<Vec<LabelUuidMap>, Error> {
|
) -> Result<Vec<LabelUuidMap>, Error> {
|
||||||
|
|
||||||
let (config, _digest) = config::drive::config()?;
|
let (config, _digest) = config::drive::config()?;
|
||||||
|
|
||||||
let (changer, changer_name) = media_changer(&config, &drive, false)?;
|
tokio::task::spawn_blocking(move || {
|
||||||
|
let (changer, changer_name) = media_changer(&config, &drive, false)?;
|
||||||
|
|
||||||
let changer_id_list = changer.list_media_changer_ids()?;
|
let changer_id_list = changer.list_media_changer_ids()?;
|
||||||
|
|
||||||
let state_path = Path::new(TAPE_STATUS_DIR);
|
let state_path = Path::new(TAPE_STATUS_DIR);
|
||||||
|
|
||||||
let mut inventory = Inventory::load(state_path)?;
|
let mut inventory = Inventory::load(state_path)?;
|
||||||
let mut state_db = MediaStateDatabase::load(state_path)?;
|
let mut state_db = MediaStateDatabase::load(state_path)?;
|
||||||
|
|
||||||
update_changer_online_status(&config, &mut inventory, &mut state_db, &changer_name, &changer_id_list)?;
|
update_changer_online_status(
|
||||||
|
&config,
|
||||||
|
&mut inventory,
|
||||||
|
&mut state_db,
|
||||||
|
&changer_name,
|
||||||
|
&changer_id_list,
|
||||||
|
)?;
|
||||||
|
|
||||||
let mut list = Vec::new();
|
let mut list = Vec::new();
|
||||||
|
|
||||||
for changer_id in changer_id_list.iter() {
|
for changer_id in changer_id_list.iter() {
|
||||||
if changer_id.starts_with("CLN") {
|
if changer_id.starts_with("CLN") {
|
||||||
// skip cleaning unit
|
// skip cleaning unit
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let changer_id = changer_id.to_string();
|
||||||
|
|
||||||
|
if let Some(media_id) = inventory.find_media_by_changer_id(&changer_id) {
|
||||||
|
list.push(LabelUuidMap { changer_id, uuid: Some(media_id.label.uuid.to_string()) });
|
||||||
|
} else {
|
||||||
|
list.push(LabelUuidMap { changer_id, uuid: None });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let changer_id = changer_id.to_string();
|
Ok(list)
|
||||||
|
}).await?
|
||||||
if let Some(media_id) = inventory.find_media_by_changer_id(&changer_id) {
|
|
||||||
list.push(LabelUuidMap { changer_id, uuid: Some(media_id.label.uuid.to_string()) });
|
|
||||||
} else {
|
|
||||||
list.push(LabelUuidMap { changer_id, uuid: None });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(list)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[api(
|
#[api(
|
||||||
|
Loading…
Reference in New Issue
Block a user