fix #4975: client: ignore E2BIG error flag
Some filesystems (f.e. zfs) support xattrs bigger than 64kB, sadly we can't get them because the kernel vfs limits us. The syscalls listxattr and getxattr will return a E2BIG error in this case. Added a flag --ignore-e2big-xattr to the client, this will ignore the metadata (but still backup the file) if this error occurs. Signed-off-by: Gabriel Goller <g.goller@proxmox.com> Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
This commit is contained in:
parent
55d50f1344
commit
a602a885af
@ -41,6 +41,8 @@ pub struct PxarCreateOptions {
|
||||
pub entries_max: usize,
|
||||
/// Skip lost+found directory
|
||||
pub skip_lost_and_found: bool,
|
||||
/// Skip xattrs of files that return E2BIG error
|
||||
pub skip_e2big_xattr: bool,
|
||||
}
|
||||
|
||||
fn detect_fs_type(fd: RawFd) -> Result<i64, Error> {
|
||||
@ -128,6 +130,7 @@ struct Archiver {
|
||||
device_set: Option<HashSet<u64>>,
|
||||
hardlinks: HashMap<HardLinkInfo, (PathBuf, LinkOffset)>,
|
||||
file_copy_buffer: Vec<u8>,
|
||||
skip_e2big_xattr: bool,
|
||||
}
|
||||
|
||||
type Encoder<'a, T> = pxar::encoder::aio::Encoder<'a, T>;
|
||||
@ -158,6 +161,7 @@ where
|
||||
feature_flags & fs_feature_flags,
|
||||
fs_magic,
|
||||
&mut fs_feature_flags,
|
||||
options.skip_e2big_xattr
|
||||
)
|
||||
.context("failed to get metadata for source directory")?;
|
||||
|
||||
@ -192,6 +196,7 @@ where
|
||||
device_set,
|
||||
hardlinks: HashMap::new(),
|
||||
file_copy_buffer: vec::undefined(4 * 1024 * 1024),
|
||||
skip_e2big_xattr: options.skip_e2big_xattr,
|
||||
};
|
||||
|
||||
archiver
|
||||
@ -540,6 +545,7 @@ impl Archiver {
|
||||
self.flags(),
|
||||
self.fs_magic,
|
||||
&mut self.fs_feature_flags,
|
||||
self.skip_e2big_xattr
|
||||
)?;
|
||||
|
||||
let match_path = PathBuf::from("/").join(self.path.clone());
|
||||
@ -765,6 +771,7 @@ fn get_metadata(
|
||||
flags: Flags,
|
||||
fs_magic: i64,
|
||||
fs_feature_flags: &mut Flags,
|
||||
skip_e2big_xattr: bool,
|
||||
) -> Result<Metadata, Error> {
|
||||
// required for some of these
|
||||
let proc_path = Path::new("/proc/self/fd/").join(fd.to_string());
|
||||
@ -780,7 +787,7 @@ fn get_metadata(
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
get_xattr_fcaps_acl(&mut meta, fd, &proc_path, flags, fs_feature_flags)?;
|
||||
get_xattr_fcaps_acl(&mut meta, fd, &proc_path, flags, fs_feature_flags, skip_e2big_xattr)?;
|
||||
get_chattr(&mut meta, fd)?;
|
||||
get_fat_attr(&mut meta, fd, fs_magic)?;
|
||||
get_quota_project_id(&mut meta, fd, flags, fs_magic)?;
|
||||
@ -818,6 +825,7 @@ fn get_xattr_fcaps_acl(
|
||||
proc_path: &Path,
|
||||
flags: Flags,
|
||||
fs_feature_flags: &mut Flags,
|
||||
skip_e2big_xattr: bool,
|
||||
) -> Result<(), Error> {
|
||||
if !flags.contains(Flags::WITH_XATTRS) {
|
||||
return Ok(());
|
||||
@ -829,6 +837,14 @@ fn get_xattr_fcaps_acl(
|
||||
fs_feature_flags.remove(Flags::WITH_XATTRS);
|
||||
return Ok(());
|
||||
}
|
||||
Err(Errno::E2BIG) => {
|
||||
match skip_e2big_xattr {
|
||||
true => return Ok(()),
|
||||
false => {
|
||||
bail!("{} (try --skip-e2big-xattr)", Errno::E2BIG.to_string());
|
||||
}
|
||||
};
|
||||
}
|
||||
Err(Errno::EBADF) => return Ok(()), // symlinks
|
||||
Err(err) => return Err(err).context("failed to read xattrs"),
|
||||
};
|
||||
@ -855,6 +871,14 @@ fn get_xattr_fcaps_acl(
|
||||
Err(Errno::ENODATA) => (), // it got removed while we were iterating...
|
||||
Err(Errno::EOPNOTSUPP) => (), // shouldn't be possible so just ignore this
|
||||
Err(Errno::EBADF) => (), // symlinks, shouldn't be able to reach this either
|
||||
Err(Errno::E2BIG) => {
|
||||
match skip_e2big_xattr {
|
||||
true => return Ok(()),
|
||||
false => {
|
||||
bail!("{} (try --skip-e2big-xattr)", Errno::E2BIG.to_string());
|
||||
}
|
||||
};
|
||||
}
|
||||
Err(err) => {
|
||||
return Err(err).context(format!("error reading extended attribute {attr:?}"))
|
||||
}
|
||||
|
@ -665,6 +665,12 @@ fn spawn_catalog_upload(
|
||||
optional: true,
|
||||
default: false,
|
||||
},
|
||||
"skip-e2big-xattr": {
|
||||
type: Boolean,
|
||||
description: "Ignore the E2BIG error when retrieving xattrs. This includes the file, but discards the metadata.",
|
||||
optional: true,
|
||||
default: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
)]
|
||||
@ -674,6 +680,7 @@ async fn create_backup(
|
||||
all_file_systems: bool,
|
||||
skip_lost_and_found: bool,
|
||||
dry_run: bool,
|
||||
skip_e2big_xattr: bool,
|
||||
_info: &ApiMethod,
|
||||
_rpcenv: &mut dyn RpcEnvironment,
|
||||
) -> Result<Value, Error> {
|
||||
@ -993,6 +1000,7 @@ async fn create_backup(
|
||||
patterns: pattern_list.clone(),
|
||||
entries_max: entries_max as usize,
|
||||
skip_lost_and_found,
|
||||
skip_e2big_xattr
|
||||
};
|
||||
|
||||
let upload_options = UploadOptions {
|
||||
|
@ -352,6 +352,7 @@ fn extract(
|
||||
device_set: None,
|
||||
patterns,
|
||||
skip_lost_and_found: false,
|
||||
skip_e2big_xattr: false,
|
||||
};
|
||||
|
||||
let pxar_writer = TokioWriter::new(writer);
|
||||
|
@ -335,6 +335,7 @@ async fn create_archive(
|
||||
device_set,
|
||||
patterns,
|
||||
skip_lost_and_found: false,
|
||||
skip_e2big_xattr: false,
|
||||
};
|
||||
|
||||
let source = PathBuf::from(source);
|
||||
|
Loading…
Reference in New Issue
Block a user