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 391BA8A543 for ; Wed, 17 Aug 2022 09:31:58 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 2BD9823D15 for ; Wed, 17 Aug 2022 09:31:58 +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) server-digest SHA256) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Wed, 17 Aug 2022 09:31:57 +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 ECC8A442EA for ; Wed, 17 Aug 2022 09:31:56 +0200 (CEST) Date: Wed, 17 Aug 2022 09:31:55 +0200 From: Wolfgang Bumiller To: Markus Frank Cc: pbs-devel@lists.proxmox.com Message-ID: <20220817073155.avw6ysd6cdjhrblv@casey.proxmox.com> References: <20220816091929.26309-1-m.frank@proxmox.com> <20220816091929.26309-2-m.frank@proxmox.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20220816091929.26309-2-m.frank@proxmox.com> X-SPAM-LEVEL: Spam detection results: 0 AWL 0.275 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 - URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [main.rs, extract.rs] Subject: Re: [pbs-devel] [PATCH proxmox-backup 1/3] added overwrite-existing-files as 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, 17 Aug 2022 07:31:58 -0000 On Tue, Aug 16, 2022 at 11:19:27AM +0200, Markus Frank wrote: > If true, O_EXCL is not set and therefore overwrites the files and does not > error out. > > Signed-off-by: Markus Frank > --- > pbs-client/src/catalog_shell.rs | 4 ++-- > pbs-client/src/pxar/extract.rs | 24 +++++++++++++++++++++--- > pxar-bin/src/main.rs | 7 +++++++ > 3 files changed, 30 insertions(+), 5 deletions(-) > > diff --git a/pbs-client/src/catalog_shell.rs b/pbs-client/src/catalog_shell.rs > index b11901ed..25e27b37 100644 > --- a/pbs-client/src/catalog_shell.rs > +++ b/pbs-client/src/catalog_shell.rs > @@ -984,7 +984,7 @@ impl Shell { > .clone(); > > let extractor = > - crate::pxar::extract::Extractor::new(rootdir, root_meta, true, Flags::DEFAULT); > + crate::pxar::extract::Extractor::new(rootdir, root_meta, true, false, Flags::DEFAULT); > > let mut extractor = ExtractorState::new( > &mut self.catalog, > @@ -1172,7 +1172,7 @@ impl<'a> ExtractorState<'a> { > let file_name = CString::new(entry.file_name().as_bytes())?; > let mut contents = entry.contents().await?; > self.extractor > - .async_extract_file(&file_name, entry.metadata(), *size, &mut contents) > + .async_extract_file(&file_name, entry.metadata(), *size, &mut contents, false) > .await > } > _ => { > diff --git a/pbs-client/src/pxar/extract.rs b/pbs-client/src/pxar/extract.rs > index 161d2cef..3b9151aa 100644 > --- a/pbs-client/src/pxar/extract.rs > +++ b/pbs-client/src/pxar/extract.rs > @@ -34,6 +34,7 @@ pub struct PxarExtractOptions<'a> { > pub match_list: &'a [MatchEntry], > pub extract_match_default: bool, > pub allow_existing_dirs: bool, > + pub overwrite_existing_files: bool, > pub on_error: Option, > } > > @@ -80,6 +81,7 @@ where > dir, > root.metadata().clone(), > options.allow_existing_dirs, > + options.overwrite_existing_files, > feature_flags, > ); > > @@ -198,6 +200,7 @@ where > &mut decoder.contents().ok_or_else(|| { > format_err!("found regular file entry without contents in archive") > })?, > + extractor.overwrite_existing_files, > ), > (false, _) => Ok(()), // skip this > } > @@ -215,6 +218,7 @@ where > pub struct Extractor { > feature_flags: Flags, > allow_existing_dirs: bool, > + overwrite_existing_files: bool, > dir_stack: PxarDirStack, > > /// For better error output we need to track the current path in the Extractor state. > @@ -231,11 +235,13 @@ impl Extractor { > root_dir: Dir, > metadata: Metadata, > allow_existing_dirs: bool, > + overwrite_existing_files: bool, > feature_flags: Flags, > ) -> Self { > Self { > dir_stack: PxarDirStack::new(root_dir, metadata), > allow_existing_dirs, > + overwrite_existing_files, > feature_flags, > current_path: Arc::new(Mutex::new(OsString::new())), > on_error: Box::new(Err), > @@ -392,14 +398,19 @@ impl Extractor { > metadata: &Metadata, > size: u64, > contents: &mut dyn io::Read, > + overwrite_existing_files: bool, > ) -> Result<(), Error> { > let parent = self.parent_fd()?; > + let mut oflags = OFlag::O_CREAT | OFlag::O_WRONLY | OFlag::O_CLOEXEC; When replacing existing files we should include `O_TRUNC`, too, otherwise if the new file is smaller and doesn't end in a hole (where we already fixup the size with an explicit truncate() call) it'll have parts of the previous contents left over at the end. > + if !overwrite_existing_files { > + oflags = oflags | OFlag::O_EXCL; > + } > let mut file = unsafe { > std::fs::File::from_raw_fd( > nix::fcntl::openat( > parent, > file_name, > - OFlag::O_CREAT | OFlag::O_EXCL | OFlag::O_WRONLY | OFlag::O_CLOEXEC, > + oflags, > Mode::from_bits(0o600).unwrap(), > ) > .map_err(|err| format_err!("failed to create file {:?}: {}", file_name, err))?, > @@ -448,14 +459,19 @@ impl Extractor { > metadata: &Metadata, > size: u64, > contents: &mut T, > + overwrite_existing_files: bool, > ) -> Result<(), Error> { > let parent = self.parent_fd()?; > + let mut oflags = OFlag::O_CREAT | OFlag::O_WRONLY | OFlag::O_CLOEXEC; > + if !overwrite_existing_files { > + oflags = oflags | OFlag::O_EXCL; > + } same here > let mut file = tokio::fs::File::from_std(unsafe { > std::fs::File::from_raw_fd( > nix::fcntl::openat( > parent, > file_name, > - OFlag::O_CREAT | OFlag::O_EXCL | OFlag::O_WRONLY | OFlag::O_CLOEXEC, > + oflags, > Mode::from_bits(0o600).unwrap(), > ) > .map_err(|err| format_err!("failed to create file {:?}: {}", file_name, err))?, > @@ -818,7 +834,7 @@ where > ) > })?; > > - Ok(Extractor::new(dir, metadata, false, Flags::DEFAULT)) > + Ok(Extractor::new(dir, metadata, false, false, Flags::DEFAULT)) > } > > pub async fn extract_sub_dir( > @@ -951,6 +967,7 @@ where > &mut file.contents().await.map_err(|_| { > format_err!("found regular file entry without contents in archive") > })?, > + extractor.overwrite_existing_files, > ) > .await? > } > @@ -998,6 +1015,7 @@ where > &mut decoder.contents().ok_or_else(|| { > format_err!("found regular file entry without contents in archive") > })?, > + extractor.overwrite_existing_files, > ) > .await? > } > diff --git a/pxar-bin/src/main.rs b/pxar-bin/src/main.rs > index 3714eb03..4b49df51 100644 > --- a/pxar-bin/src/main.rs > +++ b/pxar-bin/src/main.rs > @@ -75,6 +75,11 @@ fn extract_archive_from_reader( > optional: true, > default: false, > }, > + "overwrite_existing_files": { > + description: "overwrite existing files", > + optional: true, > + default: false, > + }, > "files-from": { > description: "File containing match pattern for files to restore.", > optional: true, > @@ -112,6 +117,7 @@ fn extract_archive( > no_fcaps: bool, > no_acls: bool, > allow_existing_dirs: bool, > + overwrite_existing_files: bool, > files_from: Option, > no_device_nodes: bool, > no_fifos: bool, > @@ -179,6 +185,7 @@ fn extract_archive( > let options = PxarExtractOptions { > match_list: &match_list, > allow_existing_dirs, > + overwrite_existing_files, > extract_match_default, > on_error, > }; > -- > 2.30.2