From: Markus Frank <m.frank@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox-backup v2 1/3] pbs-client: added overwrite-existing-files to PxarExtractOptions.
Date: Thu, 18 Aug 2022 13:06:52 +0200 [thread overview]
Message-ID: <20220818110654.56988-2-m.frank@proxmox.com> (raw)
In-Reply-To: <20220818110654.56988-1-m.frank@proxmox.com>
If overwrite-existing-files is true, O_TRUNC is set (to clean the
leftovers) instead of O_EXCL and therefore overwrites the files and
does not error out.
Signed-off-by: Markus Frank <m.frank@proxmox.com>
---
v2: add O_TRUNC to oflags if overwrite_existing_files is true.
pbs-client/src/catalog_shell.rs | 4 ++--
| 28 +++++++++++++++++++++++++---
pxar-bin/src/main.rs | 7 +++++++
3 files changed, 34 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
}
_ => {
--git a/pbs-client/src/pxar/extract.rs b/pbs-client/src/pxar/extract.rs
index 161d2cef..36600789 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<ErrorHandler>,
}
@@ -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,21 @@ 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;
+ if overwrite_existing_files {
+ oflags = oflags | OFlag::O_TRUNC;
+ } else {
+ 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 +461,21 @@ 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_TRUNC;
+ } else {
+ oflags = oflags | OFlag::O_EXCL;
+ }
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 +838,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<T, DEST, PATH>(
@@ -951,6 +971,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 +1019,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..1dd34deb 100644
--- a/pxar-bin/src/main.rs
+++ b/pxar-bin/src/main.rs
@@ -75,6 +75,11 @@ fn extract_archive_from_reader<R: std::io::Read>(
optional: true,
default: false,
},
+ "overwrite_existing_files": {
+ description: "overwrite already 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<String>,
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
next prev parent reply other threads:[~2022-08-18 11:07 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-18 11:06 [pbs-devel] [PATCH proxmox-backup v2 0/3] pbs-client: feature #3923 Markus Frank
2022-08-18 11:06 ` Markus Frank [this message]
2022-08-18 11:06 ` [pbs-devel] [PATCH proxmox-backup v2 2/3] pbs-client: added options to skip xattr/acl/ownership/permissions Markus Frank
2022-08-18 11:06 ` [pbs-devel] [PATCH proxmox-backup v2 3/3] proxmox-backup-client: added ignore-acl/xattr/ownership/permission & overwrite parameters Markus Frank
2022-08-18 12:03 ` Wolfgang Bumiller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220818110654.56988-2-m.frank@proxmox.com \
--to=m.frank@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox