From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id E27E970AE7 for ; Mon, 9 May 2022 12:41:20 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id E0B252B9FA for ; Mon, 9 May 2022 12:41:20 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 401FF2B9F0 for ; Mon, 9 May 2022 12:41:20 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 1613243226 for ; Mon, 9 May 2022 12:41:20 +0200 (CEST) From: Dominik Csapak To: pbs-devel@lists.proxmox.com Date: Mon, 9 May 2022 12:41:18 +0200 Message-Id: <20220509104119.1953106-1-d.csapak@proxmox.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.120 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record T_SCC_BODY_TEXT_LINE -0.01 - Subject: [pbs-devel] [PATCH proxmox-backup 1/2] api: tape/restore: fix wrong datastore locking X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 May 2022 10:41:20 -0000 used_datastores returned the 'target', but in the full_restore_worker, we interpreted it as the source and searched for a mapping (which we then locked) since we cannot return a HashSet of Arc (missing Hash trait on DataStore), we have now a map of source -> target Signed-off-by: Dominik Csapak --- src/api2/tape/restore.rs | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/api2/tape/restore.rs b/src/api2/tape/restore.rs index 93803f14..f24ae23c 100644 --- a/src/api2/tape/restore.rs +++ b/src/api2/tape/restore.rs @@ -88,17 +88,17 @@ impl TryFrom for DataStoreMap { } impl DataStoreMap { - fn used_datastores<'a>(&self) -> HashSet<&str> { - let mut set = HashSet::new(); - for store in self.map.values() { - set.insert(store.name()); + fn used_datastores<'a>(&self) -> HashMap<&str, Arc> { + let mut map = HashMap::new(); + for (source, target) in self.map.iter() { + map.insert(source.as_str(), Arc::clone(target)); } if let Some(ref store) = self.default { - set.insert(store.name()); + map.insert("", Arc::clone(store)); } - set + map } fn get_datastore(&self, source: &str) -> Option> { @@ -200,8 +200,8 @@ pub fn restore( bail!("no datastores given"); } - for store in used_datastores.iter() { - check_datastore_privs(&user_info, store, &auth_id, &owner)?; + for (_, target) in used_datastores.iter() { + check_datastore_privs(&user_info, target.name(), &auth_id, &owner)?; } let privs = user_info.lookup_privs(&auth_id, &["tape", "drive", &drive]); @@ -233,7 +233,7 @@ pub fn restore( let taskid = used_datastores .iter() - .map(|s| s.to_string()) + .map(|(_, t)| t.name().to_string()) .collect::>() .join(", "); @@ -349,7 +349,7 @@ fn restore_full_worker( store_map .used_datastores() .into_iter() - .map(String::from) + .map(|(_, t)| String::from(t.name())) .collect::>() .join(", "), ); @@ -366,12 +366,10 @@ fn restore_full_worker( ); let mut datastore_locks = Vec::new(); - for store_name in store_map.used_datastores() { + for (_, target) 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 shared_store_lock = target.try_shared_chunk_store_lock()?; + datastore_locks.push(shared_store_lock); } let mut checked_chunks_map = HashMap::new(); -- 2.30.2