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 932AC97660 for ; Tue, 5 Mar 2024 10:28:44 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 312D73F7F for ; Tue, 5 Mar 2024 10:27:50 +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 ; Tue, 5 Mar 2024 10:27:48 +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 BD08E487CD for ; Tue, 5 Mar 2024 10:27:47 +0100 (CET) From: Christian Ebner To: pbs-devel@lists.proxmox.com Date: Tue, 5 Mar 2024 10:26:45 +0100 Message-Id: <20240305092703.126906-19-c.ebner@proxmox.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240305092703.126906-1-c.ebner@proxmox.com> References: <20240305092703.126906-1-c.ebner@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.043 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 - Subject: [pbs-devel] [RFC v2 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: Tue, 05 Mar 2024 09:28:44 -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 --- changes since version 1: - no changes 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