]> git.proxmox.com Git - proxmox-backup.git/commitdiff
pxar: introduce fs_feature_flags obtained from filesystem magic in Encoder
authorChristian Ebner <c.ebner@proxmox.com>
Thu, 6 Jun 2019 11:37:07 +0000 (13:37 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Fri, 7 Jun 2019 09:08:20 +0000 (11:08 +0200)
Not all filesystems support features such as xattrs,acl,... and trying to get
them is rather expensive.
By getting the supported features based on the filesystem magic and masking the
user set feature flags, unsupported features are excluded rather inexpensively
while encoding the archive.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
src/pxar/encoder.rs
src/pxar/format_definition.rs

index c77acb6eadd1ff17edd8cf9e98686dffd19038f3..16548e871e014720f189c0064fb0e7963762be94 100644 (file)
@@ -50,7 +50,10 @@ pub struct Encoder<'a, W: Write> {
     all_file_systems: bool,
     root_st_dev: u64,
     verbose: bool,
+    // Flags set by the user
     feature_flags: u64,
+    // Flags signaling features supported by the filesystem
+    fs_feature_flags: u64,
     hardlinks: HashMap<HardLinkInfo, (PathBuf, u64)>,
 }
 
@@ -94,6 +97,8 @@ impl <'a, W: Write> Encoder<'a, W> {
             bail!("backup virtual file systems is disabled!");
         }
 
+        let fs_feature_flags = feature_flags_from_magic(magic);
+
         let mut me = Self {
             base_path: path,
             relative_path: PathBuf::new(),
@@ -105,6 +110,7 @@ impl <'a, W: Write> Encoder<'a, W> {
             root_st_dev: stat.st_dev,
             verbose,
             feature_flags,
+            fs_feature_flags,
             hardlinks: HashMap::new(),
         };
 
@@ -223,12 +229,12 @@ impl <'a, W: Write> Encoder<'a, W> {
 
     /// True if all of the given feature flags are set in the Encoder, false otherwise
     fn has_features(&self, feature_flags: u64) -> bool {
-        (self.feature_flags & feature_flags) == feature_flags
+        (self.feature_flags & self.fs_feature_flags & feature_flags) == feature_flags
     }
 
     /// True if at least one of the given feature flags is set in the Encoder, false otherwise
     fn has_some_features(&self, feature_flags: u64) -> bool {
-        (self.feature_flags & feature_flags) != 0
+        (self.feature_flags & self.fs_feature_flags & feature_flags) != 0
     }
 
     fn read_xattrs(&self, fd: RawFd, stat: &FileStat) -> Result<(Vec<CaFormatXAttr>, Option<CaFormatFCaps>), Error> {
@@ -568,6 +574,11 @@ impl <'a, W: Write> Encoder<'a, W> {
 
         self.read_chattr(rawfd, &mut dir_entry)?;
         self.read_fat_attr(rawfd, magic, &mut dir_entry)?;
+
+        // for each node in the directory tree, the filesystem features are
+        // checked based on the fs magic number.
+        self.fs_feature_flags = feature_flags_from_magic(magic);
+
         let (xattrs, fcaps) = self.read_xattrs(rawfd, &dir_stat)?;
         let acl_access = self.read_acl(rawfd, &dir_stat, acl::ACL_TYPE_ACCESS)?;
         let acl_default = self.read_acl(rawfd, &dir_stat, acl::ACL_TYPE_DEFAULT)?;
@@ -933,35 +944,6 @@ fn detect_fs_type(fd: RawFd) -> Result<i64, Error> {
     Ok(fs_stat.f_type)
 }
 
-
-// from /usr/include/linux/magic.h
-// and from casync util.h
-pub const BINFMTFS_MAGIC: i64 =        0x42494e4d;
-pub const CGROUP2_SUPER_MAGIC: i64 =   0x63677270;
-pub const CGROUP_SUPER_MAGIC: i64 =    0x0027e0eb;
-pub const CONFIGFS_MAGIC: i64 =        0x62656570;
-pub const DEBUGFS_MAGIC: i64 =         0x64626720;
-pub const DEVPTS_SUPER_MAGIC: i64 =    0x00001cd1;
-pub const EFIVARFS_MAGIC: i64 =        0xde5e81e4;
-pub const FUSE_CTL_SUPER_MAGIC: i64 =  0x65735543;
-pub const HUGETLBFS_MAGIC: i64 =       0x958458f6;
-pub const MQUEUE_MAGIC: i64 =          0x19800202;
-pub const NFSD_MAGIC: i64 =            0x6e667364;
-pub const PROC_SUPER_MAGIC: i64 =      0x00009fa0;
-pub const PSTOREFS_MAGIC: i64 =        0x6165676C;
-pub const RPCAUTH_GSSMAGIC: i64 =      0x67596969;
-pub const SECURITYFS_MAGIC: i64 =      0x73636673;
-pub const SELINUX_MAGIC: i64 =         0xf97cff8c;
-pub const SMACK_MAGIC: i64 =           0x43415d53;
-pub const RAMFS_MAGIC: i64 =           0x858458f6;
-pub const TMPFS_MAGIC: i64 =           0x01021994;
-pub const SYSFS_MAGIC: i64 =           0x62656572;
-pub const MSDOS_SUPER_MAGIC: i64 =     0x00004d44;
-pub const FUSE_SUPER_MAGIC: i64 =      0x65735546;
-pub const EXT4_SUPER_MAGIC: i64 =      0x0000EF53;
-pub const XFS_SUPER_MAGIC: i64 =       0x58465342;
-
-
 #[inline(always)]
 pub fn is_temporary_file_system(magic: i64) -> bool {
     magic == RAMFS_MAGIC || magic == TMPFS_MAGIC
index 9896244df200b7aa4cff1861be1be6b1919a448f..f71f302e544ff5797702dc5c3478b8a378fa840e 100644 (file)
@@ -115,40 +115,6 @@ pub const CA_FORMAT_EXCLUDE_SUBMOUNTS: u64      = 0x4000000000000000;
 /// Exclude entries with chattr flag NODUMP
 pub const CA_FORMAT_EXCLUDE_NODUMP: u64         = 0x8000000000000000;
 
-/// Default feature flags for encoder/decoder
-pub const CA_FORMAT_DEFAULT: u64 =
-CA_FORMAT_WITH_32BIT_UIDS |
-CA_FORMAT_WITH_USER_NAMES |
-CA_FORMAT_WITH_NSEC_TIME|
-CA_FORMAT_WITH_SYMLINKS|
-CA_FORMAT_WITH_DEVICE_NODES|
-CA_FORMAT_WITH_FIFOS|
-CA_FORMAT_WITH_SOCKETS|
-CA_FORMAT_WITH_FLAG_HIDDEN|
-CA_FORMAT_WITH_FLAG_SYSTEM|
-CA_FORMAT_WITH_FLAG_ARCHIVE|
-CA_FORMAT_WITH_FLAG_APPEND|
-CA_FORMAT_WITH_FLAG_NOATIME|
-CA_FORMAT_WITH_FLAG_COMPR|
-CA_FORMAT_WITH_FLAG_NOCOW|
-//CA_FORMAT_WITH_FLAG_NODUMP|
-CA_FORMAT_WITH_FLAG_DIRSYNC|
-CA_FORMAT_WITH_FLAG_IMMUTABLE|
-CA_FORMAT_WITH_FLAG_SYNC|
-CA_FORMAT_WITH_FLAG_NOCOMP|
-CA_FORMAT_WITH_FLAG_PROJINHERIT|
-CA_FORMAT_WITH_SUBVOLUME|
-CA_FORMAT_WITH_SUBVOLUME_RO|
-CA_FORMAT_WITH_XATTRS|
-CA_FORMAT_WITH_ACL|
-CA_FORMAT_WITH_SELINUX|
-CA_FORMAT_WITH_FCAPS|
-CA_FORMAT_WITH_QUOTA_PROJID |
-
-CA_FORMAT_EXCLUDE_NODUMP|
-CA_FORMAT_EXCLUDE_FILE|
-CA_FORMAT_SHA512_256;
-
 #[derive(Debug)]
 #[derive(Endian)]
 #[repr(C)]
@@ -415,3 +381,233 @@ pub fn ca_feature_flags_from_fat_attr(attr: u32) -> u64 {
 
     flags
 }
+
+// from /usr/include/linux/magic.h
+// and from casync util.h
+pub const BINFMTFS_MAGIC: i64 =        0x42494e4d;
+pub const CGROUP2_SUPER_MAGIC: i64 =   0x63677270;
+pub const CGROUP_SUPER_MAGIC: i64 =    0x0027e0eb;
+pub const CONFIGFS_MAGIC: i64 =        0x62656570;
+pub const DEBUGFS_MAGIC: i64 =         0x64626720;
+pub const DEVPTS_SUPER_MAGIC: i64 =    0x00001cd1;
+pub const EFIVARFS_MAGIC: i64 =        0xde5e81e4;
+pub const FUSE_CTL_SUPER_MAGIC: i64 =  0x65735543;
+pub const HUGETLBFS_MAGIC: i64 =       0x958458f6;
+pub const MQUEUE_MAGIC: i64 =          0x19800202;
+pub const NFSD_MAGIC: i64 =            0x6e667364;
+pub const PROC_SUPER_MAGIC: i64 =      0x00009fa0;
+pub const PSTOREFS_MAGIC: i64 =        0x6165676C;
+pub const RPCAUTH_GSSMAGIC: i64 =      0x67596969;
+pub const SECURITYFS_MAGIC: i64 =      0x73636673;
+pub const SELINUX_MAGIC: i64 =         0xf97cff8c;
+pub const SMACK_MAGIC: i64 =           0x43415d53;
+pub const RAMFS_MAGIC: i64 =           0x858458f6;
+pub const TMPFS_MAGIC: i64 =           0x01021994;
+pub const SYSFS_MAGIC: i64 =           0x62656572;
+pub const MSDOS_SUPER_MAGIC: i64 =     0x00004d44;
+pub const BTRFS_SUPER_MAGIC: i64 =     0x9123683E;
+pub const FUSE_SUPER_MAGIC: i64 =      0x65735546;
+pub const EXT4_SUPER_MAGIC: i64 =      0x0000EF53;
+pub const XFS_SUPER_MAGIC: i64 =       0x58465342;
+
+/// Definitions of typical feature flags for the *pxar* encoder/decoder.
+/// By this expensive syscalls for unsupported features are avoided.
+
+/// All chattr file attributes
+pub const CA_FORMAT_WITH_CHATTR: u64 =
+    CA_FORMAT_WITH_FLAG_APPEND|
+    CA_FORMAT_WITH_FLAG_NOATIME|
+    CA_FORMAT_WITH_FLAG_COMPR|
+    CA_FORMAT_WITH_FLAG_NOCOW|
+    CA_FORMAT_WITH_FLAG_NODUMP|
+    CA_FORMAT_WITH_FLAG_DIRSYNC|
+    CA_FORMAT_WITH_FLAG_IMMUTABLE|
+    CA_FORMAT_WITH_FLAG_SYNC|
+    CA_FORMAT_WITH_FLAG_NOCOMP|
+    CA_FORMAT_WITH_FLAG_PROJINHERIT;
+
+/// All FAT file attributes
+pub const CA_FORMAT_WITH_FAT_ATTRS: u64 =
+    CA_FORMAT_WITH_FLAG_HIDDEN|
+    CA_FORMAT_WITH_FLAG_SYSTEM|
+    CA_FORMAT_WITH_FLAG_ARCHIVE;
+
+/// All bits that may also be exposed via fuse
+pub const CA_FORMAT_WITH_FUSE: u64 =
+    CA_FORMAT_WITH_16BIT_UIDS|
+    CA_FORMAT_WITH_32BIT_UIDS|
+    CA_FORMAT_WITH_SEC_TIME|
+    CA_FORMAT_WITH_USEC_TIME|
+    CA_FORMAT_WITH_NSEC_TIME|
+    CA_FORMAT_WITH_2SEC_TIME|
+    CA_FORMAT_WITH_READ_ONLY|
+    CA_FORMAT_WITH_PERMISSIONS|
+    CA_FORMAT_WITH_SYMLINKS|
+    CA_FORMAT_WITH_DEVICE_NODES|
+    CA_FORMAT_WITH_FIFOS|
+    CA_FORMAT_WITH_SOCKETS|
+    CA_FORMAT_WITH_FAT_ATTRS|
+    CA_FORMAT_WITH_CHATTR|
+    CA_FORMAT_WITH_XATTRS;
+
+/// Default feature flags for encoder/decoder
+pub const CA_FORMAT_DEFAULT: u64 =
+    CA_FORMAT_WITH_32BIT_UIDS|
+    CA_FORMAT_WITH_USER_NAMES|
+    CA_FORMAT_WITH_NSEC_TIME|
+    CA_FORMAT_WITH_SYMLINKS|
+    CA_FORMAT_WITH_DEVICE_NODES|
+    CA_FORMAT_WITH_FIFOS|
+    CA_FORMAT_WITH_SOCKETS|
+    CA_FORMAT_WITH_FLAG_HIDDEN|
+    CA_FORMAT_WITH_FLAG_SYSTEM|
+    CA_FORMAT_WITH_FLAG_ARCHIVE|
+    CA_FORMAT_WITH_FLAG_APPEND|
+    CA_FORMAT_WITH_FLAG_NOATIME|
+    CA_FORMAT_WITH_FLAG_COMPR|
+    CA_FORMAT_WITH_FLAG_NOCOW|
+    //CA_FORMAT_WITH_FLAG_NODUMP|
+    CA_FORMAT_WITH_FLAG_DIRSYNC|
+    CA_FORMAT_WITH_FLAG_IMMUTABLE|
+    CA_FORMAT_WITH_FLAG_SYNC|
+    CA_FORMAT_WITH_FLAG_NOCOMP|
+    CA_FORMAT_WITH_FLAG_PROJINHERIT|
+    CA_FORMAT_WITH_SUBVOLUME|
+    CA_FORMAT_WITH_SUBVOLUME_RO|
+    CA_FORMAT_WITH_XATTRS|
+    CA_FORMAT_WITH_ACL|
+    CA_FORMAT_WITH_SELINUX|
+    CA_FORMAT_WITH_FCAPS|
+    CA_FORMAT_WITH_QUOTA_PROJID|
+    CA_FORMAT_EXCLUDE_NODUMP|
+    CA_FORMAT_EXCLUDE_FILE|
+    CA_FORMAT_SHA512_256;
+
+/// Return the supported *pxar* feature flags based on the magic number of the filesystem.
+pub fn feature_flags_from_magic(magic: i64) -> u64 {
+    match magic {
+        MSDOS_SUPER_MAGIC => {
+            CA_FORMAT_WITH_2SEC_TIME|
+            CA_FORMAT_WITH_READ_ONLY|
+            CA_FORMAT_WITH_FAT_ATTRS
+        },
+        EXT4_SUPER_MAGIC => {
+            CA_FORMAT_WITH_16BIT_UIDS|
+            CA_FORMAT_WITH_32BIT_UIDS|
+            CA_FORMAT_WITH_USER_NAMES|
+            CA_FORMAT_WITH_SEC_TIME|
+            CA_FORMAT_WITH_USEC_TIME|
+            CA_FORMAT_WITH_NSEC_TIME|
+            CA_FORMAT_WITH_2SEC_TIME|
+            CA_FORMAT_WITH_READ_ONLY|
+            CA_FORMAT_WITH_PERMISSIONS|
+            CA_FORMAT_WITH_SYMLINKS|
+            CA_FORMAT_WITH_DEVICE_NODES|
+            CA_FORMAT_WITH_FIFOS|
+            CA_FORMAT_WITH_SOCKETS|
+            CA_FORMAT_WITH_FLAG_APPEND|
+            CA_FORMAT_WITH_FLAG_NOATIME|
+            CA_FORMAT_WITH_FLAG_NODUMP|
+            CA_FORMAT_WITH_FLAG_DIRSYNC|
+            CA_FORMAT_WITH_FLAG_IMMUTABLE|
+            CA_FORMAT_WITH_FLAG_SYNC|
+            CA_FORMAT_WITH_XATTRS|
+            CA_FORMAT_WITH_ACL|
+            CA_FORMAT_WITH_SELINUX|
+            CA_FORMAT_WITH_FCAPS|
+            CA_FORMAT_WITH_QUOTA_PROJID
+        },
+        XFS_SUPER_MAGIC => {
+            CA_FORMAT_WITH_16BIT_UIDS|
+            CA_FORMAT_WITH_32BIT_UIDS|
+            CA_FORMAT_WITH_USER_NAMES|
+            CA_FORMAT_WITH_SEC_TIME|
+            CA_FORMAT_WITH_USEC_TIME|
+            CA_FORMAT_WITH_NSEC_TIME|
+            CA_FORMAT_WITH_2SEC_TIME|
+            CA_FORMAT_WITH_READ_ONLY|
+            CA_FORMAT_WITH_PERMISSIONS|
+            CA_FORMAT_WITH_SYMLINKS|
+            CA_FORMAT_WITH_DEVICE_NODES|
+            CA_FORMAT_WITH_FIFOS|
+            CA_FORMAT_WITH_SOCKETS|
+            CA_FORMAT_WITH_FLAG_APPEND|
+            CA_FORMAT_WITH_FLAG_NOATIME|
+            CA_FORMAT_WITH_FLAG_NODUMP|
+            CA_FORMAT_WITH_FLAG_IMMUTABLE|
+            CA_FORMAT_WITH_FLAG_SYNC|
+            CA_FORMAT_WITH_XATTRS|
+            CA_FORMAT_WITH_ACL|
+            CA_FORMAT_WITH_SELINUX|
+            CA_FORMAT_WITH_FCAPS|
+            CA_FORMAT_WITH_QUOTA_PROJID
+        },
+        BTRFS_SUPER_MAGIC => {
+            CA_FORMAT_WITH_16BIT_UIDS|
+            CA_FORMAT_WITH_32BIT_UIDS|
+            CA_FORMAT_WITH_USER_NAMES|
+            CA_FORMAT_WITH_SEC_TIME|
+            CA_FORMAT_WITH_USEC_TIME|
+            CA_FORMAT_WITH_NSEC_TIME|
+            CA_FORMAT_WITH_2SEC_TIME|
+            CA_FORMAT_WITH_READ_ONLY|
+            CA_FORMAT_WITH_PERMISSIONS|
+            CA_FORMAT_WITH_SYMLINKS|
+            CA_FORMAT_WITH_DEVICE_NODES|
+            CA_FORMAT_WITH_FIFOS|
+            CA_FORMAT_WITH_SOCKETS|
+            CA_FORMAT_WITH_FLAG_APPEND|
+            CA_FORMAT_WITH_FLAG_NOATIME|
+            CA_FORMAT_WITH_FLAG_COMPR|
+            CA_FORMAT_WITH_FLAG_NOCOW|
+            CA_FORMAT_WITH_FLAG_NODUMP|
+            CA_FORMAT_WITH_FLAG_DIRSYNC|
+            CA_FORMAT_WITH_FLAG_IMMUTABLE|
+            CA_FORMAT_WITH_FLAG_SYNC|
+            CA_FORMAT_WITH_FLAG_NOCOMP|
+            CA_FORMAT_WITH_XATTRS|
+            CA_FORMAT_WITH_ACL|
+            CA_FORMAT_WITH_SELINUX|
+            CA_FORMAT_WITH_SUBVOLUME|
+            CA_FORMAT_WITH_SUBVOLUME_RO|
+            CA_FORMAT_WITH_FCAPS
+        },
+        TMPFS_MAGIC => {
+            CA_FORMAT_WITH_16BIT_UIDS|
+            CA_FORMAT_WITH_32BIT_UIDS|
+            CA_FORMAT_WITH_USER_NAMES|
+            CA_FORMAT_WITH_SEC_TIME|
+            CA_FORMAT_WITH_USEC_TIME|
+            CA_FORMAT_WITH_NSEC_TIME|
+            CA_FORMAT_WITH_2SEC_TIME|
+            CA_FORMAT_WITH_READ_ONLY|
+            CA_FORMAT_WITH_PERMISSIONS|
+            CA_FORMAT_WITH_SYMLINKS|
+            CA_FORMAT_WITH_DEVICE_NODES|
+            CA_FORMAT_WITH_FIFOS|
+            CA_FORMAT_WITH_SOCKETS|
+            CA_FORMAT_WITH_ACL|
+            CA_FORMAT_WITH_SELINUX
+        },
+        FUSE_SUPER_MAGIC => {
+            // FUSE mounts are special as the supported feature set is not clear
+            // a priori.
+            CA_FORMAT_WITH_FUSE
+        },
+        _ => {
+            CA_FORMAT_WITH_16BIT_UIDS|
+            CA_FORMAT_WITH_32BIT_UIDS|
+            CA_FORMAT_WITH_USER_NAMES|
+            CA_FORMAT_WITH_SEC_TIME|
+            CA_FORMAT_WITH_USEC_TIME|
+            CA_FORMAT_WITH_NSEC_TIME|
+            CA_FORMAT_WITH_2SEC_TIME|
+            CA_FORMAT_WITH_READ_ONLY|
+            CA_FORMAT_WITH_PERMISSIONS|
+            CA_FORMAT_WITH_SYMLINKS|
+            CA_FORMAT_WITH_DEVICE_NODES|
+            CA_FORMAT_WITH_FIFOS|
+            CA_FORMAT_WITH_SOCKETS
+        },
+    }
+}