2019-08-02 13:19:33 +00:00
|
|
|
//! Feature flags for *pxar* allow to control what is stored/restored in/from the
|
|
|
|
//! archive.
|
|
|
|
//! Flags for known supported features for a given filesystem can be derived
|
|
|
|
//! from the superblocks magic number.
|
|
|
|
|
2020-07-14 07:16:16 +00:00
|
|
|
use libc::c_long;
|
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
use bitflags::bitflags;
|
2020-03-23 14:03:18 +00:00
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
bitflags! {
|
|
|
|
pub struct Flags: u64 {
|
|
|
|
/// FAT-style 2s time granularity
|
|
|
|
const WITH_2SEC_TIME = 0x40;
|
|
|
|
/// Preserve read only flag of files
|
|
|
|
const WITH_READ_ONLY = 0x80;
|
|
|
|
/// Preserve unix permissions
|
|
|
|
const WITH_PERMISSIONS = 0x100;
|
|
|
|
/// Include symbolik links
|
|
|
|
const WITH_SYMLINKS = 0x200;
|
|
|
|
/// Include device nodes
|
|
|
|
const WITH_DEVICE_NODES = 0x400;
|
|
|
|
/// Include FIFOs
|
|
|
|
const WITH_FIFOS = 0x800;
|
|
|
|
/// Include Sockets
|
|
|
|
const WITH_SOCKETS = 0x1000;
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
/// Preserve DOS file flag `HIDDEN`
|
|
|
|
const WITH_FLAG_HIDDEN = 0x2000;
|
|
|
|
/// Preserve DOS file flag `SYSTEM`
|
|
|
|
const WITH_FLAG_SYSTEM = 0x4000;
|
|
|
|
/// Preserve DOS file flag `ARCHIVE`
|
|
|
|
const WITH_FLAG_ARCHIVE = 0x8000;
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
// chattr() flags
|
|
|
|
/// Linux file attribute `APPEND`
|
|
|
|
const WITH_FLAG_APPEND = 0x10000;
|
|
|
|
/// Linux file attribute `NOATIME`
|
|
|
|
const WITH_FLAG_NOATIME = 0x20000;
|
|
|
|
/// Linux file attribute `COMPR`
|
|
|
|
const WITH_FLAG_COMPR = 0x40000;
|
|
|
|
/// Linux file attribute `NOCOW`
|
|
|
|
const WITH_FLAG_NOCOW = 0x80000;
|
|
|
|
/// Linux file attribute `NODUMP`
|
|
|
|
const WITH_FLAG_NODUMP = 0x0010_0000;
|
|
|
|
/// Linux file attribute `DIRSYNC`
|
|
|
|
const WITH_FLAG_DIRSYNC = 0x0020_0000;
|
|
|
|
/// Linux file attribute `IMMUTABLE`
|
|
|
|
const WITH_FLAG_IMMUTABLE = 0x0040_0000;
|
|
|
|
/// Linux file attribute `SYNC`
|
|
|
|
const WITH_FLAG_SYNC = 0x0080_0000;
|
|
|
|
/// Linux file attribute `NOCOMP`
|
|
|
|
const WITH_FLAG_NOCOMP = 0x0100_0000;
|
|
|
|
/// Linux file attribute `PROJINHERIT`
|
|
|
|
const WITH_FLAG_PROJINHERIT = 0x0200_0000;
|
2019-08-02 13:19:33 +00:00
|
|
|
|
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
/// Preserve BTRFS subvolume flag
|
|
|
|
const WITH_SUBVOLUME = 0x0400_0000;
|
|
|
|
/// Preserve BTRFS read-only subvolume flag
|
|
|
|
const WITH_SUBVOLUME_RO = 0x0800_0000;
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
/// Preserve Extended Attribute metadata
|
|
|
|
const WITH_XATTRS = 0x1000_0000;
|
|
|
|
/// Preserve Access Control List metadata
|
|
|
|
const WITH_ACL = 0x2000_0000;
|
|
|
|
/// Preserve SELinux security context
|
|
|
|
const WITH_SELINUX = 0x4000_0000;
|
|
|
|
/// Preserve "security.capability" xattr
|
|
|
|
const WITH_FCAPS = 0x8000_0000;
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
/// Preserve XFS/ext4/ZFS project quota ID
|
|
|
|
const WITH_QUOTA_PROJID = 0x0001_0000_0000;
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
/// Support ".pxarexclude" files
|
|
|
|
const EXCLUDE_FILE = 0x1000_0000_0000_0000;
|
|
|
|
/// Exclude submounts
|
|
|
|
const EXCLUDE_SUBMOUNTS = 0x4000_0000_0000_0000;
|
|
|
|
/// Exclude entries with chattr flag NODUMP
|
|
|
|
const EXCLUDE_NODUMP = 0x8000_0000_0000_0000;
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
// Definitions of typical feature flags for the *pxar* encoder/decoder.
|
|
|
|
// By this expensive syscalls for unsupported features are avoided.
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
/// All chattr file attributes
|
|
|
|
const WITH_CHATTR =
|
|
|
|
Flags::WITH_FLAG_APPEND.bits() |
|
|
|
|
Flags::WITH_FLAG_NOATIME.bits() |
|
|
|
|
Flags::WITH_FLAG_COMPR.bits() |
|
|
|
|
Flags::WITH_FLAG_NOCOW.bits() |
|
|
|
|
Flags::WITH_FLAG_NODUMP.bits() |
|
|
|
|
Flags::WITH_FLAG_DIRSYNC.bits() |
|
|
|
|
Flags::WITH_FLAG_IMMUTABLE.bits() |
|
|
|
|
Flags::WITH_FLAG_SYNC.bits() |
|
|
|
|
Flags::WITH_FLAG_NOCOMP.bits() |
|
|
|
|
Flags::WITH_FLAG_PROJINHERIT.bits();
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
/// All FAT file attributes
|
|
|
|
const WITH_FAT_ATTRS =
|
|
|
|
Flags::WITH_FLAG_HIDDEN.bits() |
|
|
|
|
Flags::WITH_FLAG_SYSTEM.bits() |
|
|
|
|
Flags::WITH_FLAG_ARCHIVE.bits();
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
/// All bits that may also be exposed via fuse
|
|
|
|
const WITH_FUSE =
|
|
|
|
Flags::WITH_2SEC_TIME.bits() |
|
|
|
|
Flags::WITH_READ_ONLY.bits() |
|
|
|
|
Flags::WITH_PERMISSIONS.bits() |
|
|
|
|
Flags::WITH_SYMLINKS.bits() |
|
|
|
|
Flags::WITH_DEVICE_NODES.bits() |
|
|
|
|
Flags::WITH_FIFOS.bits() |
|
|
|
|
Flags::WITH_SOCKETS.bits() |
|
|
|
|
Flags::WITH_FAT_ATTRS.bits() |
|
|
|
|
Flags::WITH_CHATTR.bits() |
|
|
|
|
Flags::WITH_XATTRS.bits();
|
2019-08-02 13:19:33 +00:00
|
|
|
|
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
/// Default feature flags for encoder/decoder
|
|
|
|
const DEFAULT =
|
|
|
|
Flags::WITH_SYMLINKS.bits() |
|
|
|
|
Flags::WITH_DEVICE_NODES.bits() |
|
|
|
|
Flags::WITH_FIFOS.bits() |
|
|
|
|
Flags::WITH_SOCKETS.bits() |
|
|
|
|
Flags::WITH_FLAG_HIDDEN.bits() |
|
|
|
|
Flags::WITH_FLAG_SYSTEM.bits() |
|
|
|
|
Flags::WITH_FLAG_ARCHIVE.bits() |
|
|
|
|
Flags::WITH_FLAG_APPEND.bits() |
|
|
|
|
Flags::WITH_FLAG_NOATIME.bits() |
|
|
|
|
Flags::WITH_FLAG_COMPR.bits() |
|
|
|
|
Flags::WITH_FLAG_NOCOW.bits() |
|
|
|
|
//WITH_FLAG_NODUMP.bits() |
|
|
|
|
Flags::WITH_FLAG_DIRSYNC.bits() |
|
|
|
|
Flags::WITH_FLAG_IMMUTABLE.bits() |
|
|
|
|
Flags::WITH_FLAG_SYNC.bits() |
|
|
|
|
Flags::WITH_FLAG_NOCOMP.bits() |
|
|
|
|
Flags::WITH_FLAG_PROJINHERIT.bits() |
|
|
|
|
Flags::WITH_SUBVOLUME.bits() |
|
|
|
|
Flags::WITH_SUBVOLUME_RO.bits() |
|
|
|
|
Flags::WITH_XATTRS.bits() |
|
|
|
|
Flags::WITH_ACL.bits() |
|
|
|
|
Flags::WITH_SELINUX.bits() |
|
|
|
|
Flags::WITH_FCAPS.bits() |
|
|
|
|
Flags::WITH_QUOTA_PROJID.bits() |
|
|
|
|
Flags::EXCLUDE_NODUMP.bits() |
|
|
|
|
Flags::EXCLUDE_FILE.bits();
|
|
|
|
}
|
|
|
|
}
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
impl Default for Flags {
|
|
|
|
fn default() -> Flags {
|
|
|
|
Flags::DEFAULT
|
|
|
|
}
|
|
|
|
}
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-07-14 07:16:16 +00:00
|
|
|
// form /usr/include/linux/fs.h
|
|
|
|
const FS_APPEND_FL: c_long = 0x0000_0020;
|
|
|
|
const FS_NOATIME_FL: c_long = 0x0000_0080;
|
|
|
|
const FS_COMPR_FL: c_long = 0x0000_0004;
|
|
|
|
const FS_NOCOW_FL: c_long = 0x0080_0000;
|
|
|
|
const FS_NODUMP_FL: c_long = 0x0000_0040;
|
|
|
|
const FS_DIRSYNC_FL: c_long = 0x0001_0000;
|
|
|
|
const FS_IMMUTABLE_FL: c_long = 0x0000_0010;
|
|
|
|
const FS_SYNC_FL: c_long = 0x0000_0008;
|
|
|
|
const FS_NOCOMP_FL: c_long = 0x0000_0400;
|
|
|
|
const FS_PROJINHERIT_FL: c_long = 0x2000_0000;
|
|
|
|
|
|
|
|
pub(crate) const INITIAL_FS_FLAGS: c_long =
|
|
|
|
FS_NOATIME_FL
|
|
|
|
| FS_COMPR_FL
|
|
|
|
| FS_NOCOW_FL
|
|
|
|
| FS_NOCOMP_FL
|
|
|
|
| FS_PROJINHERIT_FL;
|
|
|
|
|
|
|
|
#[rustfmt::skip]
|
|
|
|
const CHATTR_MAP: [(Flags, c_long); 10] = [
|
|
|
|
( Flags::WITH_FLAG_APPEND, FS_APPEND_FL ),
|
|
|
|
( Flags::WITH_FLAG_NOATIME, FS_NOATIME_FL ),
|
|
|
|
( Flags::WITH_FLAG_COMPR, FS_COMPR_FL ),
|
|
|
|
( Flags::WITH_FLAG_NOCOW, FS_NOCOW_FL ),
|
|
|
|
( Flags::WITH_FLAG_NODUMP, FS_NODUMP_FL ),
|
|
|
|
( Flags::WITH_FLAG_DIRSYNC, FS_DIRSYNC_FL ),
|
|
|
|
( Flags::WITH_FLAG_IMMUTABLE, FS_IMMUTABLE_FL ),
|
|
|
|
( Flags::WITH_FLAG_SYNC, FS_SYNC_FL ),
|
|
|
|
( Flags::WITH_FLAG_NOCOMP, FS_NOCOMP_FL ),
|
|
|
|
( Flags::WITH_FLAG_PROJINHERIT, FS_PROJINHERIT_FL ),
|
|
|
|
];
|
|
|
|
|
|
|
|
// from /usr/include/linux/msdos_fs.h
|
|
|
|
const ATTR_HIDDEN: u32 = 2;
|
|
|
|
const ATTR_SYS: u32 = 4;
|
|
|
|
const ATTR_ARCH: u32 = 32;
|
|
|
|
|
|
|
|
#[rustfmt::skip]
|
|
|
|
const FAT_ATTR_MAP: [(Flags, u32); 3] = [
|
|
|
|
( Flags::WITH_FLAG_HIDDEN, ATTR_HIDDEN ),
|
|
|
|
( Flags::WITH_FLAG_SYSTEM, ATTR_SYS ),
|
|
|
|
( Flags::WITH_FLAG_ARCHIVE, ATTR_ARCH ),
|
|
|
|
];
|
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
impl Flags {
|
|
|
|
/// Get a set of feature flags from file attributes.
|
2020-07-14 07:16:16 +00:00
|
|
|
pub fn from_chattr(attr: c_long) -> Flags {
|
2020-06-10 09:03:42 +00:00
|
|
|
let mut flags = Flags::empty();
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
for (fe_flag, fs_flag) in &CHATTR_MAP {
|
|
|
|
if (attr & fs_flag) != 0 {
|
|
|
|
flags |= *fe_flag;
|
|
|
|
}
|
|
|
|
}
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
flags
|
|
|
|
}
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-07-14 07:16:16 +00:00
|
|
|
/// Get the chattr bit representation of these feature flags.
|
|
|
|
pub fn to_chattr(self) -> c_long {
|
|
|
|
let mut flags: c_long = 0;
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-07-14 07:16:16 +00:00
|
|
|
for (fe_flag, fs_flag) in &CHATTR_MAP {
|
|
|
|
if self.contains(*fe_flag) {
|
|
|
|
flags |= *fs_flag;
|
|
|
|
}
|
|
|
|
}
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-07-14 07:16:16 +00:00
|
|
|
flags
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn to_initial_chattr(self) -> c_long {
|
|
|
|
self.to_chattr() & INITIAL_FS_FLAGS
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get a set of feature flags from FAT attributes.
|
|
|
|
pub fn from_fat_attr(attr: u32) -> Flags {
|
2020-06-10 09:03:42 +00:00
|
|
|
let mut flags = Flags::empty();
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
for (fe_flag, fs_flag) in &FAT_ATTR_MAP {
|
|
|
|
if (attr & fs_flag) != 0 {
|
|
|
|
flags |= *fe_flag;
|
|
|
|
}
|
|
|
|
}
|
2019-08-02 13:19:33 +00:00
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
flags
|
2019-08-02 13:19:33 +00:00
|
|
|
}
|
|
|
|
|
2020-07-14 07:16:16 +00:00
|
|
|
/// Get the fat attribute bit representation of these feature flags.
|
|
|
|
pub fn to_fat_attr(self) -> u32 {
|
|
|
|
let mut flags = 0u32;
|
|
|
|
|
|
|
|
for (fe_flag, fs_flag) in &FAT_ATTR_MAP {
|
|
|
|
if self.contains(*fe_flag) {
|
|
|
|
flags |= *fs_flag;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
flags
|
|
|
|
}
|
|
|
|
|
2020-06-10 09:03:42 +00:00
|
|
|
/// Return the supported *pxar* feature flags based on the magic number of the filesystem.
|
|
|
|
pub fn from_magic(magic: i64) -> Flags {
|
|
|
|
use proxmox::sys::linux::magic::*;
|
|
|
|
match magic {
|
|
|
|
MSDOS_SUPER_MAGIC => {
|
|
|
|
Flags::WITH_2SEC_TIME |
|
|
|
|
Flags::WITH_READ_ONLY |
|
|
|
|
Flags::WITH_FAT_ATTRS
|
|
|
|
},
|
|
|
|
EXT4_SUPER_MAGIC => {
|
|
|
|
Flags::WITH_2SEC_TIME |
|
|
|
|
Flags::WITH_READ_ONLY |
|
|
|
|
Flags::WITH_PERMISSIONS |
|
|
|
|
Flags::WITH_SYMLINKS |
|
|
|
|
Flags::WITH_DEVICE_NODES |
|
|
|
|
Flags::WITH_FIFOS |
|
|
|
|
Flags::WITH_SOCKETS |
|
|
|
|
Flags::WITH_FLAG_APPEND |
|
|
|
|
Flags::WITH_FLAG_NOATIME |
|
|
|
|
Flags::WITH_FLAG_NODUMP |
|
|
|
|
Flags::WITH_FLAG_DIRSYNC |
|
|
|
|
Flags::WITH_FLAG_IMMUTABLE |
|
|
|
|
Flags::WITH_FLAG_SYNC |
|
|
|
|
Flags::WITH_XATTRS |
|
|
|
|
Flags::WITH_ACL |
|
|
|
|
Flags::WITH_SELINUX |
|
|
|
|
Flags::WITH_FCAPS |
|
|
|
|
Flags::WITH_QUOTA_PROJID
|
|
|
|
},
|
|
|
|
XFS_SUPER_MAGIC => {
|
|
|
|
Flags::WITH_2SEC_TIME |
|
|
|
|
Flags::WITH_READ_ONLY |
|
|
|
|
Flags::WITH_PERMISSIONS |
|
|
|
|
Flags::WITH_SYMLINKS |
|
|
|
|
Flags::WITH_DEVICE_NODES |
|
|
|
|
Flags::WITH_FIFOS |
|
|
|
|
Flags::WITH_SOCKETS |
|
|
|
|
Flags::WITH_FLAG_APPEND |
|
|
|
|
Flags::WITH_FLAG_NOATIME |
|
|
|
|
Flags::WITH_FLAG_NODUMP |
|
|
|
|
Flags::WITH_FLAG_IMMUTABLE |
|
|
|
|
Flags::WITH_FLAG_SYNC |
|
|
|
|
Flags::WITH_XATTRS |
|
|
|
|
Flags::WITH_ACL |
|
|
|
|
Flags::WITH_SELINUX |
|
|
|
|
Flags::WITH_FCAPS |
|
|
|
|
Flags::WITH_QUOTA_PROJID
|
|
|
|
},
|
|
|
|
ZFS_SUPER_MAGIC => {
|
|
|
|
Flags::WITH_2SEC_TIME |
|
|
|
|
Flags::WITH_READ_ONLY |
|
|
|
|
Flags::WITH_PERMISSIONS |
|
|
|
|
Flags::WITH_SYMLINKS |
|
|
|
|
Flags::WITH_DEVICE_NODES |
|
|
|
|
Flags::WITH_FIFOS |
|
|
|
|
Flags::WITH_SOCKETS |
|
|
|
|
Flags::WITH_FLAG_APPEND |
|
|
|
|
Flags::WITH_FLAG_NOATIME |
|
|
|
|
Flags::WITH_FLAG_NODUMP |
|
|
|
|
Flags::WITH_FLAG_DIRSYNC |
|
|
|
|
Flags::WITH_FLAG_IMMUTABLE |
|
|
|
|
Flags::WITH_FLAG_SYNC |
|
|
|
|
Flags::WITH_XATTRS |
|
|
|
|
Flags::WITH_ACL |
|
|
|
|
Flags::WITH_SELINUX |
|
|
|
|
Flags::WITH_FCAPS |
|
|
|
|
Flags::WITH_QUOTA_PROJID
|
|
|
|
},
|
|
|
|
BTRFS_SUPER_MAGIC => {
|
|
|
|
Flags::WITH_2SEC_TIME |
|
|
|
|
Flags::WITH_READ_ONLY |
|
|
|
|
Flags::WITH_PERMISSIONS |
|
|
|
|
Flags::WITH_SYMLINKS |
|
|
|
|
Flags::WITH_DEVICE_NODES |
|
|
|
|
Flags::WITH_FIFOS |
|
|
|
|
Flags::WITH_SOCKETS |
|
|
|
|
Flags::WITH_FLAG_APPEND |
|
|
|
|
Flags::WITH_FLAG_NOATIME |
|
|
|
|
Flags::WITH_FLAG_COMPR |
|
|
|
|
Flags::WITH_FLAG_NOCOW |
|
|
|
|
Flags::WITH_FLAG_NODUMP |
|
|
|
|
Flags::WITH_FLAG_DIRSYNC |
|
|
|
|
Flags::WITH_FLAG_IMMUTABLE |
|
|
|
|
Flags::WITH_FLAG_SYNC |
|
|
|
|
Flags::WITH_FLAG_NOCOMP |
|
|
|
|
Flags::WITH_XATTRS |
|
|
|
|
Flags::WITH_ACL |
|
|
|
|
Flags::WITH_SELINUX |
|
|
|
|
Flags::WITH_SUBVOLUME |
|
|
|
|
Flags::WITH_SUBVOLUME_RO |
|
|
|
|
Flags::WITH_FCAPS
|
|
|
|
},
|
|
|
|
TMPFS_MAGIC => {
|
|
|
|
Flags::WITH_2SEC_TIME |
|
|
|
|
Flags::WITH_READ_ONLY |
|
|
|
|
Flags::WITH_PERMISSIONS |
|
|
|
|
Flags::WITH_SYMLINKS |
|
|
|
|
Flags::WITH_DEVICE_NODES |
|
|
|
|
Flags::WITH_FIFOS |
|
|
|
|
Flags::WITH_SOCKETS |
|
|
|
|
Flags::WITH_ACL |
|
|
|
|
Flags::WITH_SELINUX
|
|
|
|
},
|
|
|
|
// FUSE mounts are special as the supported feature set
|
|
|
|
// is not clear a priori.
|
|
|
|
FUSE_SUPER_MAGIC => {
|
|
|
|
Flags::WITH_FUSE
|
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
Flags::WITH_2SEC_TIME |
|
|
|
|
Flags::WITH_READ_ONLY |
|
|
|
|
Flags::WITH_PERMISSIONS |
|
|
|
|
Flags::WITH_SYMLINKS |
|
|
|
|
Flags::WITH_DEVICE_NODES |
|
|
|
|
Flags::WITH_FIFOS |
|
|
|
|
Flags::WITH_SOCKETS
|
|
|
|
},
|
|
|
|
}
|
2019-08-02 13:19:33 +00:00
|
|
|
}
|
|
|
|
}
|