mirror of
https://git.proxmox.com/git/proxmox-backup
synced 2025-08-03 03:36:50 +00:00
pbs-client: added overwrite parameter to PxarExtractOptions.
If overwrite 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>
This commit is contained in:
parent
5574114a2a
commit
95e910f153
@ -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
|
||||
}
|
||||
_ => {
|
||||
|
@ -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: bool,
|
||||
pub on_error: Option<ErrorHandler>,
|
||||
}
|
||||
|
||||
@ -80,6 +81,7 @@ where
|
||||
dir,
|
||||
root.metadata().clone(),
|
||||
options.allow_existing_dirs,
|
||||
options.overwrite,
|
||||
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,
|
||||
),
|
||||
(false, _) => Ok(()), // skip this
|
||||
}
|
||||
@ -215,6 +218,7 @@ where
|
||||
pub struct Extractor {
|
||||
feature_flags: Flags,
|
||||
allow_existing_dirs: bool,
|
||||
overwrite: 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: bool,
|
||||
feature_flags: Flags,
|
||||
) -> Self {
|
||||
Self {
|
||||
dir_stack: PxarDirStack::new(root_dir, metadata),
|
||||
allow_existing_dirs,
|
||||
overwrite,
|
||||
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: bool,
|
||||
) -> Result<(), Error> {
|
||||
let parent = self.parent_fd()?;
|
||||
let mut oflags = OFlag::O_CREAT | OFlag::O_WRONLY | OFlag::O_CLOEXEC;
|
||||
if overwrite {
|
||||
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: bool,
|
||||
) -> Result<(), Error> {
|
||||
let parent = self.parent_fd()?;
|
||||
let mut oflags = OFlag::O_CREAT | OFlag::O_WRONLY | OFlag::O_CLOEXEC;
|
||||
if overwrite {
|
||||
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,
|
||||
)
|
||||
.await?
|
||||
}
|
||||
@ -998,6 +1019,7 @@ where
|
||||
&mut decoder.contents().ok_or_else(|| {
|
||||
format_err!("found regular file entry without contents in archive")
|
||||
})?,
|
||||
extractor.overwrite,
|
||||
)
|
||||
.await?
|
||||
}
|
||||
|
@ -75,6 +75,11 @@ fn extract_archive_from_reader<R: std::io::Read>(
|
||||
optional: true,
|
||||
default: false,
|
||||
},
|
||||
"overwrite": {
|
||||
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: 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,
|
||||
extract_match_default,
|
||||
on_error,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user