* [pbs-devel] [PATCH proxmox-backup 0/3] pbs-client feature #3923 @ 2022-08-16 9:19 Markus Frank 2022-08-16 9:19 ` [pbs-devel] [PATCH proxmox-backup 1/3] added overwrite-existing-files as Markus Frank ` (2 more replies) 0 siblings, 3 replies; 7+ messages in thread From: Markus Frank @ 2022-08-16 9:19 UTC (permalink / raw) To: pbs-devel These patches are for ignore-acl, ignore-xattr, ignore-ownership & overwrite-existing-files parameter in proxmox-backup-client. Markus Frank (3): overwrite-existing-files for pxar skip xattr/acl/ownership options added ignore-acl/xattr/ownership & overwrite parameter to proxmox-backup-client pbs-client/src/catalog_shell.rs | 4 +-- pbs-client/src/pxar/extract.rs | 24 ++++++++++++++-- pbs-client/src/pxar/flags.rs | 1 + pbs-client/src/pxar/metadata.rs | 48 ++++++++++++++++++++----------- proxmox-backup-client/src/main.rs | 40 +++++++++++++++++++++++++- pxar-bin/src/main.rs | 7 +++++ 6 files changed, 101 insertions(+), 23 deletions(-) -- 2.30.2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [pbs-devel] [PATCH proxmox-backup 1/3] added overwrite-existing-files as 2022-08-16 9:19 [pbs-devel] [PATCH proxmox-backup 0/3] pbs-client feature #3923 Markus Frank @ 2022-08-16 9:19 ` Markus Frank 2022-08-16 9:48 ` Markus Frank 2022-08-17 7:31 ` Wolfgang Bumiller 2022-08-16 9:19 ` [pbs-devel] [PATCH proxmox-backup 2/3] skip xattr/acl/ownership options Markus Frank 2022-08-16 9:19 ` [pbs-devel] [PATCH proxmox-backup 3/3] added ignore-acl/xattr/ownership & overwrite parameter to proxmox-backup-client Markus Frank 2 siblings, 2 replies; 7+ messages in thread From: Markus Frank @ 2022-08-16 9:19 UTC (permalink / raw) To: pbs-devel If true, O_EXCL is not set and therefore overwrites the files and does not error out. Signed-off-by: Markus Frank <m.frank@proxmox.com> --- 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<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,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; + 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; + } 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<T, DEST, PATH>( @@ -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<R: std::io::Read>( 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<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 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [pbs-devel] [PATCH proxmox-backup 1/3] added overwrite-existing-files as 2022-08-16 9:19 ` [pbs-devel] [PATCH proxmox-backup 1/3] added overwrite-existing-files as Markus Frank @ 2022-08-16 9:48 ` Markus Frank 2022-08-17 7:31 ` Wolfgang Bumiller 1 sibling, 0 replies; 7+ messages in thread From: Markus Frank @ 2022-08-16 9:48 UTC (permalink / raw) To: pbs-devel I am sorry. Subject/Commit-Message should be: added overwrite-existing-files to PxarExtractOptions On 8/16/22 11:19, 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 <m.frank@proxmox.com> > --- > 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<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,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; > + 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; > + } > 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<T, DEST, PATH>( > @@ -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<R: std::io::Read>( > 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<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 > > > > _______________________________________________ > pbs-devel mailing list > pbs-devel@lists.proxmox.com > https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel > > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [pbs-devel] [PATCH proxmox-backup 1/3] added overwrite-existing-files as 2022-08-16 9:19 ` [pbs-devel] [PATCH proxmox-backup 1/3] added overwrite-existing-files as Markus Frank 2022-08-16 9:48 ` Markus Frank @ 2022-08-17 7:31 ` Wolfgang Bumiller 1 sibling, 0 replies; 7+ messages in thread From: Wolfgang Bumiller @ 2022-08-17 7:31 UTC (permalink / raw) To: Markus Frank; +Cc: pbs-devel 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 <m.frank@proxmox.com> > --- > 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<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,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<T, DEST, PATH>( > @@ -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<R: std::io::Read>( > 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<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 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [pbs-devel] [PATCH proxmox-backup 2/3] skip xattr/acl/ownership options 2022-08-16 9:19 [pbs-devel] [PATCH proxmox-backup 0/3] pbs-client feature #3923 Markus Frank 2022-08-16 9:19 ` [pbs-devel] [PATCH proxmox-backup 1/3] added overwrite-existing-files as Markus Frank @ 2022-08-16 9:19 ` Markus Frank 2022-08-17 7:36 ` Wolfgang Bumiller 2022-08-16 9:19 ` [pbs-devel] [PATCH proxmox-backup 3/3] added ignore-acl/xattr/ownership & overwrite parameter to proxmox-backup-client Markus Frank 2 siblings, 1 reply; 7+ messages in thread From: Markus Frank @ 2022-08-16 9:19 UTC (permalink / raw) To: pbs-devel added cases to skip xattr/acl/ownership if the flags are not set. Also added WITH_PERMISSIONS to Default-Flags, because otherwise it would be needed to activly set it and most filesystems that support XATTR and ACL also support POSIX-Permissions. Signed-off-by: Markus Frank <m.frank@proxmox.com> --- pbs-client/src/pxar/flags.rs | 1 + pbs-client/src/pxar/metadata.rs | 48 +++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/pbs-client/src/pxar/flags.rs b/pbs-client/src/pxar/flags.rs index d46c8af3..938d0c57 100644 --- a/pbs-client/src/pxar/flags.rs +++ b/pbs-client/src/pxar/flags.rs @@ -135,6 +135,7 @@ bitflags! { Flags::WITH_FLAG_PROJINHERIT.bits() | Flags::WITH_SUBVOLUME.bits() | Flags::WITH_SUBVOLUME_RO.bits() | + Flags::WITH_PERMISSIONS.bits() | Flags::WITH_XATTRS.bits() | Flags::WITH_ACL.bits() | Flags::WITH_SELINUX.bits() | diff --git a/pbs-client/src/pxar/metadata.rs b/pbs-client/src/pxar/metadata.rs index 22bc5f9d..3195fb03 100644 --- a/pbs-client/src/pxar/metadata.rs +++ b/pbs-client/src/pxar/metadata.rs @@ -100,27 +100,17 @@ pub fn apply( on_error: &mut (dyn FnMut(Error) -> Result<(), Error> + Send), ) -> Result<(), Error> { let c_proc_path = CString::new(format!("/proc/self/fd/{}", fd)).unwrap(); + apply_ownership(flags, c_proc_path.as_ptr(), metadata, &mut *on_error)?; - unsafe { - // UID and GID first, as this fails if we lose access anyway. - c_result!(libc::chown( - c_proc_path.as_ptr(), - metadata.stat.uid, - metadata.stat.gid - )) - .map(drop) - .or_else(allow_notsupp) - .map_err(|err| format_err!("failed to set ownership: {}", err)) - .or_else(&mut *on_error)?; - } - - let mut skip_xattrs = false; + let mut skip_xattrs = !flags.contains(Flags::WITH_XATTRS); apply_xattrs(flags, c_proc_path.as_ptr(), metadata, &mut skip_xattrs) .or_else(&mut *on_error)?; add_fcaps(flags, c_proc_path.as_ptr(), metadata, &mut skip_xattrs).or_else(&mut *on_error)?; - apply_acls(flags, &c_proc_path, metadata, path_info) - .map_err(|err| format_err!("failed to apply acls: {}", err)) - .or_else(&mut *on_error)?; + if flags.contains(Flags::WITH_ACL) { + apply_acls(flags, &c_proc_path, metadata, path_info) + .map_err(|err| format_err!("failed to apply acls: {}", err)) + .or_else(&mut *on_error)?; + } apply_quota_project_id(flags, fd, metadata).or_else(&mut *on_error)?; // Finally mode and time. We may lose access with mode, but the changing the mode also @@ -162,6 +152,30 @@ pub fn apply( Ok(()) } +pub fn apply_ownership( + flags: Flags, + c_proc_path: *const libc::c_char, + metadata: &Metadata, + on_error: &mut (dyn FnMut(Error) -> Result<(), Error> + Send), +) -> Result<(), Error> { + if !flags.contains(Flags::WITH_PERMISSIONS) { + return Ok(()); + } + unsafe { + // UID and GID first, as this fails if we lose access anyway. + c_result!(libc::chown( + c_proc_path, + metadata.stat.uid, + metadata.stat.gid + )) + .map(drop) + .or_else(allow_notsupp) + .map_err(|err| format_err!("failed to set ownership: {}", err)) + .or_else(&mut *on_error)?; + } + Ok(()) +} + fn add_fcaps( flags: Flags, c_proc_path: *const libc::c_char, -- 2.30.2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [pbs-devel] [PATCH proxmox-backup 2/3] skip xattr/acl/ownership options 2022-08-16 9:19 ` [pbs-devel] [PATCH proxmox-backup 2/3] skip xattr/acl/ownership options Markus Frank @ 2022-08-17 7:36 ` Wolfgang Bumiller 0 siblings, 0 replies; 7+ messages in thread From: Wolfgang Bumiller @ 2022-08-17 7:36 UTC (permalink / raw) To: Markus Frank; +Cc: pbs-devel On Tue, Aug 16, 2022 at 11:19:28AM +0200, Markus Frank wrote: > added cases to skip xattr/acl/ownership if the flags are not set. > Also added WITH_PERMISSIONS to Default-Flags, because otherwise it > would be needed to activly set it and most filesystems that support > XATTR and ACL also support POSIX-Permissions. > > Signed-off-by: Markus Frank <m.frank@proxmox.com> > --- > pbs-client/src/pxar/flags.rs | 1 + > pbs-client/src/pxar/metadata.rs | 48 +++++++++++++++++++++------------ > 2 files changed, 32 insertions(+), 17 deletions(-) > > diff --git a/pbs-client/src/pxar/flags.rs b/pbs-client/src/pxar/flags.rs > index d46c8af3..938d0c57 100644 > --- a/pbs-client/src/pxar/flags.rs > +++ b/pbs-client/src/pxar/flags.rs > @@ -135,6 +135,7 @@ bitflags! { > Flags::WITH_FLAG_PROJINHERIT.bits() | > Flags::WITH_SUBVOLUME.bits() | > Flags::WITH_SUBVOLUME_RO.bits() | > + Flags::WITH_PERMISSIONS.bits() | > Flags::WITH_XATTRS.bits() | > Flags::WITH_ACL.bits() | > Flags::WITH_SELINUX.bits() | > diff --git a/pbs-client/src/pxar/metadata.rs b/pbs-client/src/pxar/metadata.rs > index 22bc5f9d..3195fb03 100644 > --- a/pbs-client/src/pxar/metadata.rs > +++ b/pbs-client/src/pxar/metadata.rs > @@ -100,27 +100,17 @@ pub fn apply( > on_error: &mut (dyn FnMut(Error) -> Result<(), Error> + Send), > ) -> Result<(), Error> { > let c_proc_path = CString::new(format!("/proc/self/fd/{}", fd)).unwrap(); > + apply_ownership(flags, c_proc_path.as_ptr(), metadata, &mut *on_error)?; > > - unsafe { > - // UID and GID first, as this fails if we lose access anyway. > - c_result!(libc::chown( > - c_proc_path.as_ptr(), > - metadata.stat.uid, > - metadata.stat.gid > - )) > - .map(drop) > - .or_else(allow_notsupp) > - .map_err(|err| format_err!("failed to set ownership: {}", err)) > - .or_else(&mut *on_error)?; > - } > - > - let mut skip_xattrs = false; > + let mut skip_xattrs = !flags.contains(Flags::WITH_XATTRS); > apply_xattrs(flags, c_proc_path.as_ptr(), metadata, &mut skip_xattrs) > .or_else(&mut *on_error)?; > add_fcaps(flags, c_proc_path.as_ptr(), metadata, &mut skip_xattrs).or_else(&mut *on_error)?; > - apply_acls(flags, &c_proc_path, metadata, path_info) > - .map_err(|err| format_err!("failed to apply acls: {}", err)) > - .or_else(&mut *on_error)?; > + if flags.contains(Flags::WITH_ACL) { > + apply_acls(flags, &c_proc_path, metadata, path_info) > + .map_err(|err| format_err!("failed to apply acls: {}", err)) > + .or_else(&mut *on_error)?; > + } > apply_quota_project_id(flags, fd, metadata).or_else(&mut *on_error)?; > > // Finally mode and time. We may lose access with mode, but the changing the mode also > @@ -162,6 +152,30 @@ pub fn apply( > Ok(()) > } > > +pub fn apply_ownership( > + flags: Flags, > + c_proc_path: *const libc::c_char, > + metadata: &Metadata, > + on_error: &mut (dyn FnMut(Error) -> Result<(), Error> + Send), > +) -> Result<(), Error> { > + if !flags.contains(Flags::WITH_PERMISSIONS) { > + return Ok(()); > + } While we're at it, I think we should rename `WITH_PERMISSIONS` to `WITH_OWNER`, as it doesn't affect permissions ;-) We could mask the chmod call in metadata::apply with this instead and have both flags separately? But I'd like to get rid fo this confusion in the code :-) > + unsafe { > + // UID and GID first, as this fails if we lose access anyway. > + c_result!(libc::chown( > + c_proc_path, > + metadata.stat.uid, > + metadata.stat.gid > + )) > + .map(drop) > + .or_else(allow_notsupp) > + .map_err(|err| format_err!("failed to set ownership: {}", err)) > + .or_else(&mut *on_error)?; > + } > + Ok(()) > +} > + > fn add_fcaps( > flags: Flags, > c_proc_path: *const libc::c_char, > -- > 2.30.2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [pbs-devel] [PATCH proxmox-backup 3/3] added ignore-acl/xattr/ownership & overwrite parameter to proxmox-backup-client 2022-08-16 9:19 [pbs-devel] [PATCH proxmox-backup 0/3] pbs-client feature #3923 Markus Frank 2022-08-16 9:19 ` [pbs-devel] [PATCH proxmox-backup 1/3] added overwrite-existing-files as Markus Frank 2022-08-16 9:19 ` [pbs-devel] [PATCH proxmox-backup 2/3] skip xattr/acl/ownership options Markus Frank @ 2022-08-16 9:19 ` Markus Frank 2 siblings, 0 replies; 7+ messages in thread From: Markus Frank @ 2022-08-16 9:19 UTC (permalink / raw) To: pbs-devel If ignore-acl/ignore-xattr/ignore-ownership is set, the corresponding flag gets removed. overwrite-existing-files is saved as an PxarExtractOption like allow-existing-dirs. Signed-off-by: Markus Frank <m.frank@proxmox.com> --- proxmox-backup-client/src/main.rs | 40 ++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/proxmox-backup-client/src/main.rs b/proxmox-backup-client/src/main.rs index 4bb9aa5e..20c29e26 100644 --- a/proxmox-backup-client/src/main.rs +++ b/proxmox-backup-client/src/main.rs @@ -1201,6 +1201,26 @@ We do not extract '.pxar' archives when writing to standard output. type: CryptMode, optional: true, }, + "ignore-ownership": { + type: Boolean, + description: "ignore owner settings", + optional: true, + }, + "ignore-acl": { + type: Boolean, + description: "ignore acl errors", + optional: true, + }, + "ignore-xattr": { + type: Boolean, + description: "ignore xattr errors", + optional: true, + }, + "overwrite-existing-files": { + type: Boolean, + description: "overwrite existing files", + optional: true, + }, } } )] @@ -1210,6 +1230,11 @@ async fn restore(param: Value) -> Result<Value, Error> { let allow_existing_dirs = param["allow-existing-dirs"].as_bool().unwrap_or(false); + let ignore_acls = param["ignore-acl"].as_bool().unwrap_or(false); + let ignore_xattrs = param["ignore-xattr"].as_bool().unwrap_or(false); + let ignore_ownership = param["ignore-ownership"].as_bool().unwrap_or(false); + let overwrite_existing_files = param["overwrite-existing-files"].as_bool().unwrap_or(false); + let archive_name = json::required_string_param(¶m, "archive-name")?; let rate = match param["rate"].as_str() { @@ -1331,14 +1356,27 @@ async fn restore(param: Value) -> Result<Value, Error> { match_list: &[], extract_match_default: true, allow_existing_dirs, + overwrite_existing_files, on_error: None, }; + let mut feature_flags = pbs_client::pxar::Flags::DEFAULT; + + if ignore_ownership { + feature_flags.remove(pbs_client::pxar::Flags::WITH_PERMISSIONS); + } + if ignore_acls { + feature_flags.remove(pbs_client::pxar::Flags::WITH_ACL); + } + if ignore_xattrs { + feature_flags.remove(pbs_client::pxar::Flags::WITH_XATTRS); + } + if let Some(target) = target { pbs_client::pxar::extract_archive( pxar::decoder::Decoder::from_std(reader)?, Path::new(target), - pbs_client::pxar::Flags::DEFAULT, + feature_flags, |path| { log::debug!("{:?}", path); }, -- 2.30.2 ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2022-08-17 7:37 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-08-16 9:19 [pbs-devel] [PATCH proxmox-backup 0/3] pbs-client feature #3923 Markus Frank 2022-08-16 9:19 ` [pbs-devel] [PATCH proxmox-backup 1/3] added overwrite-existing-files as Markus Frank 2022-08-16 9:48 ` Markus Frank 2022-08-17 7:31 ` Wolfgang Bumiller 2022-08-16 9:19 ` [pbs-devel] [PATCH proxmox-backup 2/3] skip xattr/acl/ownership options Markus Frank 2022-08-17 7:36 ` Wolfgang Bumiller 2022-08-16 9:19 ` [pbs-devel] [PATCH proxmox-backup 3/3] added ignore-acl/xattr/ownership & overwrite parameter to proxmox-backup-client Markus Frank
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.Service provided by Proxmox Server Solutions GmbH | Privacy | Legal