Skip to content

Commit

Permalink
fix: backup file even if failed listing extended attributes
Browse files Browse the repository at this point in the history
This should fix rustic-rs#232

The idea:
Even on a system that supports extended-attributes,
we might encounter some part of the file-system that doesn't.

For instance a `mount` with the right option
(streams_interface=windows for instace) will not support xattr.

AFAIK it also seems to be the case with a simple sshfs on a debian/ubuntu.
  • Loading branch information
nardoor committed Aug 5, 2024
1 parent 78045c8 commit b2e329b
Showing 1 changed file with 49 additions and 24 deletions.
73 changes: 49 additions & 24 deletions crates/core/src/backend/ignore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use chrono::TimeZone;
use chrono::{DateTime, Local, Utc};
use derive_setters::Setters;
use ignore::{overrides::OverrideBuilder, DirEntry, Walk, WalkBuilder};
use log::warn;
use log::{debug, warn};
#[cfg(not(windows))]
use nix::unistd::{Gid, Group, Uid, User};

Expand Down Expand Up @@ -472,6 +472,41 @@ fn get_group_by_gid(gid: u32) -> Option<String> {
}
}

#[cfg(target_os = "openbsd")]
fn list_extended_attributes(path: &Path) -> RusticResult<Vec<ExtendedAttribute>> {
Ok(vec![])
}

/// List [`ExtendedAttribute`] for a [`Node`] located at `path`
///
/// # Argument
///
/// * `path` to the [`Node`] for which to list attributes
///
/// # Errors
///
/// * [`IgnoreErrorKind::ErrorXattr`] - if Xattr couldn't be listed or couldn't be read
#[cfg(not(target_os = "openbsd"))]
fn list_extended_attributes(path: &Path) -> RusticResult<Vec<ExtendedAttribute>> {
Ok(xattr::list(path)
.map_err(|err| IgnoreErrorKind::ErrorXattr {
path: path.to_path_buf(),
source: err,
})?
.map(|name| {
Ok(ExtendedAttribute {
name: name.to_string_lossy().to_string(),
value: xattr::get(path, name)
.map_err(|err| IgnoreErrorKind::ErrorXattr {
path: path.to_path_buf(),
source: err,
})?
.unwrap(),
})
})
.collect::<RusticResult<Vec<ExtendedAttribute>>>()?)
}

/// Maps a [`DirEntry`] to a [`ReadSourceEntry`].
///
/// # Arguments
Expand Down Expand Up @@ -531,29 +566,19 @@ fn map_entry(
let device_id = if ignore_devid { 0 } else { m.dev() };
let links = if m.is_dir() { 0 } else { m.nlink() };

#[cfg(target_os = "openbsd")]
let extended_attributes = vec![];

#[cfg(not(target_os = "openbsd"))]
let extended_attributes = {
let path = entry.path();
xattr::list(path)
.map_err(|err| IgnoreErrorKind::ErrorXattr {
path: path.to_path_buf(),
source: err,
})?
.map(|name| {
Ok(ExtendedAttribute {
name: name.to_string_lossy().to_string(),
value: xattr::get(path, name)
.map_err(|err| IgnoreErrorKind::ErrorXattr {
path: path.to_path_buf(),
source: err,
})?
.unwrap(),
})
})
.collect::<RusticResult<_>>()?
let extended_attributes = match list_extended_attributes(entry.path()) {
Err(e) => {
// TODO - discuss this log:
// Most probably that if Xattr read failure happens for one file,
// it will also happen for every file in the same subdirectory.
//
// The end result would be a real flood of errors.
// For this reason, I propose to have this log at "debug" level
// so it's not transparent, but doesn't impact a "lambda" use case of rustic.
debug!("ignoring error: {e}\n");
vec![]
}
Ok(xattr_list) => xattr_list,
};

let meta = Metadata {
Expand Down

0 comments on commit b2e329b

Please sign in to comment.