使用cp / rsync保留扩展属性


12

使用复制时cp,即使保留显式属性,扩展属性也不会保留

cp -a --preserve=all /source /dest

要么

cp -a --preserve=xattr /source /dest

与相同rsync,即

rsync -aq -A -X --delete /source /dest

但是,在目标文件系统上,我可以手动创建扩展属性(使用chattr)。这意味着目标文件系统支持xattr。

为什么我不能xattrcp或保存rsync

附加信息:

  • 源文件系统和目标文件系统均为ext4
  • 源文件系统和目标文件系统都是本地的(不是nfs)
  • 我正在使用Debian Wheezy

您如何挂载此目标文件系统?是通过NFS吗?
slm

目标文件系统是本地文件系统
Martin Vegter 2014年

您可以显示mount此文件系统的输出吗?
slm

1
在哪些Unix变体和版本上?两端都有哪些文件系统类型,有哪些安装选项?
吉尔斯(Gilles)'“ SO-不要邪恶”

1
@MartinVegter能否给您的文件提供一个示例属性?我只是在两个文件中创建了ext4文件系统,并使用进行了测试setfattr -n system.name0 -v "value" test_file。我test_file使用ext4 / jfs / xfs 复制了ext4 / jfs / xfs的内容cp --preserve=all,但保留扩展属性没有任何问题。
UVV 2014年

Answers:


14

更新资料

在弄乱了更多内容并查看了for chattr和other 的代码之后e2fsprogs,很明显,by chattr设置的属性和by 设置的属性libattr(例如,使用命令setfattr)非常不同。chattr设置ext文件系统标志,这些标志根本不会映射到命名属性或名称空间。没有他们的出现与任何电话libattrlistxattr。它们可能应该映射到命名system空间中的命名属性,如下所示,但是到目前为止,这完全没有实现。同样,system.posix_acl_access我误认为要映射到以下这些属性之一的属性与ext文件系统标志无关,而与访问控制列表有关。相关的strace消息出现在任何文件中,仅cp --preserve=xattr使用时消失。

似乎由设置的属性chattr特定于ext文件系统,并且影响它们的唯一方法是通过e2fsprogs工具。实际上,该man页面实际上并未为它们使用术语“扩展属性”,而是为“文件属性”。“真实”扩展属性是可以由libattr多个文件系统更改并在多个文件系统上实现的名称/值对。这些是什么cp以及rsync对外观,并给出正确的选择,当转移到复制的文件。但是,似乎确实system存在命名空间,可以将chattr属性映射到名称,并最终映射到其他文件系统上的等效属性,但是现在这不起作用。

我保留了原始答案,因为那里有一些很好的信息,尽管在某些方面确实有很大的错误。

更新2

我应该在此之前再次回到这个问题chattr上,但是按照这个答案,它不仅仅适用于ext文件系统。根据Wikipedia所述,它等效于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

请注意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.

这是很难通过映射使用的属性文字chattrlsattr在文件系统中使用的基本命名属性(一个有在互联网上没有列表)。从我的测试来看,该A属性映射到该system.posix_acl_access属性,并且由于这是system名称空间,rsync因此甚至都不会尝试复制它。man片段中未提及的其他两个名称空间是trustedsecurity,需要root特权才能设置这些名称空间(并且rsync如果没有它们,将无法尝试)。

您尝试设置的属性很可能属于忽略的system名称空间rsync(可能是明智的选择)。要么,要么您需要成为root用户才能获得不是的root用户。

至于cp,似乎有错误在起作用。strace在上运行cp -a,我得到以下两条有趣的代码:

fgetxattr(3, "system.posix_acl_access", 0x7fff5181c0e0, 132) = -1 ENODATA (No data available)

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

首先,该fgetxattr调用不会返回任何数据(可能是因为没有任何数据-属性的存在就足够了),但是以某种方式cp找到了28个字节的(垃圾内容)数据以设置为目标文件中的属性值。这似乎是中的错误cp,但是导致问题的原因似乎是错误,libattr因为fsetattr调用0成功返回而没有实际设置属性。

ext4无论是否安装,我都会得到这种行为user_xattr。除了说“某些系统”需要此安装选项才能使扩展属性正常工作外,我找不到其他文档。貌似我的(Debian Jessie)没有。甚至我错过了一个日益严重的问题,这都是错误的fsetattr,因此cp默默地失败了。

其实user_xattr有必要对ext2ext3reiserfs可能还有一些其他人。不需要ext4

还要注意的是,attr工具setfattrgetfattrattr(后者被证明是只为XFS而已,但似乎只是工作,以及其他的ext4)有什么,但工作问题user的命名空间。Operation not supported如果尝试使用setfattr将属性放在system名称空间中(或根据此bug没有名称空间),我会明白。setfattr似乎在trustedsecurity命名空间中成功,但随后却getfattr无法读回任何内容,也无法从system设置的命名空间中读取任何内容chattrchattr成功的原因是它使用了ioctlcall而不是libattr

但是,最有效的方法是在user名称空间中设置扩展属性setfattr并使用rsynccp原样复制它们(cp如果在创建属性时未指定值,甚至没有问题)。我认为最重要的是,system当前使用名称空间值越野车和/或至少在Debian和其他发行版中不受支持。rsync开发人员很可能知道这一点,这就是为什么他们忽略它们。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.