Mar*_*ter 16 filesystems cp rsync xattr
复制 with 时cp,不会保留扩展属性,即使使用显式
cp -a --preserve=all /source /dest
Run Code Online (Sandbox Code Playgroud)
或者
cp -a --preserve=xattr /source /dest
Run Code Online (Sandbox Code Playgroud)
同理rsync,即
rsync -aq -A -X --delete /source /dest
Run Code Online (Sandbox Code Playgroud)
但是,在目标文件系统上,我可以手动创建扩展属性(使用chattr)。这意味着目标文件系统支持 xattr。
为什么我不能xattr用cp或保存rsync?
Gra*_*eme 16
在对此进行了更多处理并查看了chattr和 other的代码之后e2fsprogs,很明显设置的属性chattr和设置的属性libattr(例如使用命令setfattr)是非常不同的。chattr设置ext文件系统标志,这些标志根本不映射到命名属性或命名空间。他们都没有出现任何对libattr's 的 调用listxattr。它们可能应该映射到命名system空间中的命名属性,如下面假设的那样,但到目前为止这还完全没有实现。此外,system.posix_acl_access我误认为映射到以下这些属性之一的属性与ext文件系统标志无关,而是与访问控制列表有关。相关的strace任何文件都会出现消息,仅cp --preserve=xattr在使用时消失。
似乎由 设置的属性chattr特定于ext文件系统,影响它们的唯一方法是通过e2fsprogs工具。事实上,man页面实际上并没有为它们使用术语“扩展属性”,而是使用“文件属性”。“真实”扩展属性是名称/值对,可以由libattr多个文件系统更改并在多个文件系统上实现。这些是什么cp以及rsync对外观,并给出正确的选择,当转移到复制的文件。然而,似乎system命名空间的存在是为了将chattr属性映射到名称并最终映射到其他文件系统上的等效属性,但目前这不起作用。
我保留了原始答案不变,因为那里有一些很好的信息,尽管在某些方面确实有很大的错误。
我应该在此之前再次回到这个问题,但根据这个答案,它chattr不仅仅适用于ext文件系统。根据维基百科,它相当于chflags基于 BSD 的系统上的命令。
我写了一个脚本来测试几个文件系统上这些属性的设置和读取,并得到以下结果:
ext4:
suS-iadAcj-t-e-- mnt/test_file
suSDiadAcj-tTe-- mnt/test_dir
reiserfs:
lsattr: Inappropriate ioctl for device While reading flags on mnt/test_file
lsattr: Inappropriate ioctl for device While reading flags on mnt/test_dir
xfs:
--S-iadA-------- mnt/test_file
--S-iadA-------- mnt/test_dir
btrfs:
--S-iadAc------C mnt/test_file
--SDiadAc------C mnt/test_dir
Run Code Online (Sandbox Code Playgroud)
请注意,所有读取/设置reiserfs文件标志的尝试都会出现上述错误,尽管它在 Wikipedia 上被列为具有某些功能。我没有测试reiser4。此外,虽然c国旗可以设置在ext4它上面是不尊重的。可能还有影响这些标志的调整/安装选项,但我找不到任何选项。
然而,目前似乎chattr是 Linux 上唯一能够修改这些属性的实用程序,因此没有复制实用程序能够保留它们。
原因rsync似乎是甚至没有尝试。从文档-X部分rsync:
For systems that support extended-attribute namespaces, a copy being done by a
super-user copies all namespaces except system.*. A normal user only copies
the user.* namespace.
Run Code Online (Sandbox Code Playgroud)
这是很难通过映射使用的属性文字chattr并lsattr在文件系统中使用的基本命名属性(一个有在互联网上没有列表)。但从我的测试来看,A属性映射到system.posix_acl_access属性,因为这是system命名空间,rsync甚至不会尝试复制它。man代码段中没有提到的另外两个命名空间是trustedand security,需要 root 权限来设置这些(并且rsync不会尝试没有)。
您尝试设置的属性很可能位于忽略(并且可能是明智的)的system命名空间中rsync。要么是那个,要么你需要成为 root 才能得到那些不是。
至于运行cp,似乎存在错误。strace上cp -a,我得到以下两个有趣的线路:
fgetxattr(3, "system.posix_acl_access", 0x7fff5181c0e0, 132) = -1 ENODATA (No data available)
Run Code Online (Sandbox Code Playgroud)
和
fsetxattr(4, "system.posix_acl_access", "\x02\x00\x00\x00\x01\x00\x06\x00\xff\xff\xff\xff\x04\x00\x04\x00\xff\xff\xff\xff \x00\x04\x00\xff\xff\xff\xff", 28, 0) = 0
Run Code Online (Sandbox Code Playgroud)
首先,fgetxattr调用不返回任何数据(可能是因为没有任何数据 - 属性的存在就足够了),但不知何故cp找到了 28 个字节的(垃圾?)数据以设置为目标文件中的属性值。这似乎是 中的一个错误cp,但导致问题的原因似乎是一个错误,libattr因为fsetattr调用返回0成功而没有实际设置属性。
我得到的这种行为ext4,无论我是否有安装user_xattr。我找不到任何关于此的文档,只能说“某些系统”需要此安装选项才能使扩展属性正常工作。似乎我的(Debian Jessie)没有。即使我遗漏了一个日益严重的问题,它也是错误的fsetattr,因此cp默默地失败了。
其实user_xattr有必要对ext2,ext3,reiserfs可能还有一些其他人。没有必要ext4
另请注意,attr工具setfattr,getfattr和attr(后者被记录为仅适用于XFS,但似乎与其他工具一样有效ext4)在user名称空间以外的任何地方都存在问题。Operation not supported如果我尝试使用setfattr将属性放入system命名空间(或根据此错误没有命名空间),我会得到。setfattr出现在成功trusted和security命名空间,但随后getfattr无法读取任何东西,也无法读取从任何system通过命名空间设置chattr。chattr成功的原因是它使用的是ioctlcall 而不是libattr。
然而,完美的工作是在user命名空间中设置扩展属性setfattr并使用rsync或cp完整复制它们(cp如果在创建属性时没有指定值,甚至没有问题)。我认为最重要的system是目前使用命名空间值马车和/或不受支持,至少在 Debian 和其他发行版中也是如此。rsync开发人员可能知道这一点,这就是他们忽略它们的原因。