From fa9507020af34f07f20662dbb85f3c65ffd23fa5 Mon Sep 17 00:00:00 2001 From: Dominik Csapak Date: Tue, 11 May 2021 12:50:03 +0200 Subject: [PATCH] api2/tape/restore: refactor restore code into its own function and create the 'email' and 'restore_owner' variable at the beginning, so that we can reuse them and do not have to pass the sources of those through too many functions Signed-off-by: Dominik Csapak --- src/api2/tape/restore.rs | 189 ++++++++++++++++++++++----------------- 1 file changed, 105 insertions(+), 84 deletions(-) diff --git a/src/api2/tape/restore.rs b/src/api2/tape/restore.rs index 9884b379..d1298434 100644 --- a/src/api2/tape/restore.rs +++ b/src/api2/tape/restore.rs @@ -281,84 +281,26 @@ pub fn restore( set_tape_device_state(&drive, &worker.upid().to_string())?; - let members = inventory.compute_media_set_members(&media_set_uuid)?; + let restore_owner = owner.as_ref().unwrap_or(&auth_id); - let media_list = members.media_list(); + let email = notify_user + .as_ref() + .and_then(|userid| lookup_user_email(userid)) + .or_else(|| lookup_user_email(&auth_id.clone().into())); - let mut media_id_list = Vec::new(); - - let mut encryption_key_fingerprint = None; - - for (seq_nr, media_uuid) in media_list.iter().enumerate() { - match media_uuid { - None => { - bail!("media set {} is incomplete (missing member {}).", media_set_uuid, seq_nr); - } - Some(media_uuid) => { - let media_id = inventory.lookup_media(media_uuid).unwrap(); - if let Some(ref set) = media_id.media_set_label { // always true here - if encryption_key_fingerprint.is_none() && set.encryption_key_fingerprint.is_some() { - encryption_key_fingerprint = set.encryption_key_fingerprint.clone(); - } - } - media_id_list.push(media_id); - } - } - } task_log!(worker, "Restore mediaset '{}'", media_set); - if let Some(fingerprint) = encryption_key_fingerprint { - task_log!(worker, "Encryption key fingerprint: {}", fingerprint); - } task_log!(worker, "Pool: {}", pool); - task_log!( - worker, - "Datastore(s): {}", - store_map - .used_datastores() - .into_iter() - .map(String::from) - .collect::>() - .join(", "), + let res = restore_worker( + worker.clone(), + inventory, + media_set_uuid, + drive_config, + &drive, + store_map, + restore_owner, + email ); - - task_log!(worker, "Drive: {}", drive); - task_log!( - worker, - "Required media list: {}", - media_id_list.iter() - .map(|media_id| media_id.label.label_text.as_str()) - .collect::>() - .join(";") - ); - - let mut datastore_locks = Vec::new(); - for store_name in store_map.used_datastores() { - // explicit create shared lock to prevent GC on newly created chunks - if let Some(store) = store_map.get_datastore(store_name) { - let shared_store_lock = store.try_shared_chunk_store_lock()?; - datastore_locks.push(shared_store_lock); - } - } - - let mut checked_chunks_map = HashMap::new(); - - for media_id in media_id_list.iter() { - request_and_restore_media( - worker.clone(), - media_id, - &drive_config, - &drive, - &store_map, - &mut checked_chunks_map, - &auth_id, - ¬ify_user, - &owner, - )?; - } - - drop(datastore_locks); - task_log!(worker, "Restore mediaset '{}' done", media_set); if let Err(err) = set_tape_device_state(&drive, "") { @@ -370,13 +312,100 @@ pub fn restore( ); } - Ok(()) + res } )?; Ok(upid_str.into()) } +fn restore_worker( + worker: Arc, + inventory: Inventory, + media_set_uuid: Uuid, + drive_config: SectionConfigData, + drive_name: &str, + store_map: DataStoreMap, + restore_owner: &Authid, + email: Option, +) -> Result<(), Error> { + let members = inventory.compute_media_set_members(&media_set_uuid)?; + + let media_list = members.media_list(); + + let mut media_id_list = Vec::new(); + + let mut encryption_key_fingerprint = None; + + for (seq_nr, media_uuid) in media_list.iter().enumerate() { + match media_uuid { + None => { + bail!("media set {} is incomplete (missing member {}).", media_set_uuid, seq_nr); + } + Some(media_uuid) => { + let media_id = inventory.lookup_media(media_uuid).unwrap(); + if let Some(ref set) = media_id.media_set_label { // always true here + if encryption_key_fingerprint.is_none() && set.encryption_key_fingerprint.is_some() { + encryption_key_fingerprint = set.encryption_key_fingerprint.clone(); + } + } + media_id_list.push(media_id); + } + } + } + + if let Some(fingerprint) = encryption_key_fingerprint { + task_log!(worker, "Encryption key fingerprint: {}", fingerprint); + } + + task_log!( + worker, + "Datastore(s): {}", + store_map + .used_datastores() + .into_iter() + .map(String::from) + .collect::>() + .join(", "), + ); + + task_log!(worker, "Drive: {}", drive_name); + task_log!( + worker, + "Required media list: {}", + media_id_list.iter() + .map(|media_id| media_id.label.label_text.as_str()) + .collect::>() + .join(";") + ); + + let mut datastore_locks = Vec::new(); + for store_name in store_map.used_datastores() { + // explicit create shared lock to prevent GC on newly created chunks + if let Some(store) = store_map.get_datastore(store_name) { + let shared_store_lock = store.try_shared_chunk_store_lock()?; + datastore_locks.push(shared_store_lock); + } + } + + let mut checked_chunks_map = HashMap::new(); + + for media_id in media_id_list.iter() { + request_and_restore_media( + worker.clone(), + media_id, + &drive_config, + drive_name, + &store_map, + &mut checked_chunks_map, + restore_owner, + &email, + )?; + } + + Ok(()) +} + /// Request and restore complete media without using existing catalog (create catalog instead) pub fn request_and_restore_media( worker: Arc, @@ -385,21 +414,15 @@ pub fn request_and_restore_media( drive_name: &str, store_map: &DataStoreMap, checked_chunks_map: &mut HashMap>, - authid: &Authid, - notify_user: &Option, - owner: &Option, + restore_owner: &Authid, + email: &Option, ) -> Result<(), Error> { let media_set_uuid = match media_id.media_set_label { None => bail!("restore_media: no media set - internal error"), Some(ref set) => &set.uuid, }; - let email = notify_user - .as_ref() - .and_then(|userid| lookup_user_email(userid)) - .or_else(|| lookup_user_email(&authid.clone().into())); - - let (mut drive, info) = request_and_load_media(&worker, &drive_config, &drive_name, &media_id.label, &email)?; + let (mut drive, info) = request_and_load_media(&worker, &drive_config, &drive_name, &media_id.label, email)?; match info.media_set_label { None => { @@ -419,8 +442,6 @@ pub fn request_and_restore_media( } } - let restore_owner = owner.as_ref().unwrap_or(authid); - restore_media( worker, &mut drive,