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 52E3595EE1 for ; Wed, 28 Feb 2024 15:09:49 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 32065E13E for ; Wed, 28 Feb 2024 15:09:19 +0100 (CET) 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 for ; Wed, 28 Feb 2024 15:09:17 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 0F06A47BBD for ; Wed, 28 Feb 2024 15:02:50 +0100 (CET) From: Christian Ebner To: pbs-devel@lists.proxmox.com Date: Wed, 28 Feb 2024 15:02:08 +0100 Message-Id: <20240228140226.1251979-19-c.ebner@proxmox.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240228140226.1251979-1-c.ebner@proxmox.com> References: <20240228140226.1251979-1-c.ebner@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.045 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy 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 - URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [mount.rs] Subject: [pbs-devel] [RFC proxmox-backup 18/36] client: mount: make split pxar archives mountable 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: Wed, 28 Feb 2024 14:09:49 -0000 Cover the cases where the pxar archive was uploaded as split payload data and metadata streams. Instantiate the required reader and decoder instances to access the metadata and payload data archives. Signed-off-by: Christian Ebner --- proxmox-backup-client/src/mount.rs | 56 ++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/proxmox-backup-client/src/mount.rs b/proxmox-backup-client/src/mount.rs index 4a2f8335..c955a7da 100644 --- a/proxmox-backup-client/src/mount.rs +++ b/proxmox-backup-client/src/mount.rs @@ -219,19 +219,22 @@ async fn mount_do(param: Value, pipe: Option) -> Result { } }; - let server_archive_name = if archive_name.ends_with(".pxar") { - if target.is_none() { - bail!("use the 'mount' command to mount pxar archives"); - } - format!("{}.didx", archive_name) - } else if archive_name.ends_with(".img") { - if target.is_some() { - bail!("use the 'map' command to map drive images"); - } - format!("{}.fidx", archive_name) - } else { - bail!("Can only mount/map pxar archives and drive images."); - }; + let server_archive_name = + if archive_name.ends_with(".pxar") || archive_name.ends_with(".pxar.meta") { + if target.is_none() { + bail!("use the 'mount' command to mount pxar archives"); + } + format!("{}.didx", archive_name) + } else if archive_name.ends_with(".img") { + if target.is_some() { + bail!("use the 'map' command to map drive images"); + } + format!("{}.fidx", archive_name) + } else if archive_name.ends_with(".pxar.pld") { + bail!("Use corresponding pxar.meta archive to mount."); + } else { + bail!("Can only mount/map pxar archives and drive images."); + }; let client = BackupReader::start( &client, @@ -289,14 +292,37 @@ async fn mount_do(param: Value, pipe: Option) -> Result { let most_used = index.find_most_used_chunks(8); let chunk_reader = RemoteChunkReader::new( client.clone(), - crypt_config, + crypt_config.clone(), file_info.chunk_crypt_mode(), most_used, ); let reader = BufferedDynamicReader::new(index, chunk_reader); + let archive_size = reader.archive_size(); let reader: pbs_pxar_fuse::Reader = Arc::new(BufferedDynamicReadAt::new(reader)); - let decoder = pbs_pxar_fuse::Accessor::new(reader, archive_size).await?; + + let mut decoder = pbs_pxar_fuse::Accessor::new(reader, archive_size).await?; + + if let Some(archive_base_name) = server_archive_name.strip_suffix(".pxar.meta.didx") { + let payload_archive_name = format!("{archive_base_name}.pxar.pld.didx"); + let payload_index = client + .download_dynamic_index(&manifest, &payload_archive_name) + .await?; + + let payload_most_used = payload_index.find_most_used_chunks(8); + let payload_chunk_reader = RemoteChunkReader::new( + client.clone(), + crypt_config, + file_info.chunk_crypt_mode(), + payload_most_used, + ); + + let payload_reader = BufferedDynamicReader::new(payload_index, payload_chunk_reader); + let payload_reader: pbs_pxar_fuse::Reader = + Arc::new(BufferedDynamicReadAt::new(payload_reader)); + + decoder = decoder.redirect_payload_input(payload_reader); + } let session = pbs_pxar_fuse::Session::mount(decoder, options, false, Path::new(target.unwrap())) -- 2.39.2