cp
を使用してコピーする場合、明示的な属性であっても、拡張属性は保持されません。
cp -a --preserve=all /source /dest
または
cp -a --preserve=xattr /source /dest
同じことはrsync
でも同じです。
rsync -aq -A -X --delete /source /dest
ただし、宛先ファイルシステムでは、手動で(chattr
を使用して)拡張属性を作成できます。これは、ターゲットファイルシステムがxattrをサポートすることを意味します。
xattr
をcp
またはrsync
で保存できないのはなぜですか?
これをいじって、chattr
と他のe2fsprogs
のコードを見てみると、chattr
で設定された属性とlibattr
で設定された属性(たとえば、setfattr
コマンドを使用)は非常に異なっていることがわかります。 chattr
は、ext
ファイルシステムフラグを設定します。これらのフラグは、名前付き属性または名前空間にマップされません。 なしlibattr
のlistxattr
への呼び出しで表示されます。これらはおそらくすべき以下で想定されるようにsystem
名前空間の名前付き属性にマップされますが、現時点ではこれは完全に実装されていません。また、以下の属性の1つへのマッピングと間違えたsystem.posix_acl_access
属性は、ext
ファイルシステムフラグとは関係なく、アクセス制御リストと関係しています。関連するstrace
メッセージはすべてのファイルに対して表示され、cp --preserve=xattr
のみが使用されると表示されなくなります。
chattr
によって設定された属性はext
ファイルシステムに固有であり、それらに影響を与える唯一の方法はe2fsprogs
ツールを使用することです。実際、man
ページでは、実際には「拡張属性」という用語ではなく、「ファイル属性」という用語を使用しています。 「実際の」拡張属性は、libattr
で変更できる名前と値のペアであり、複数のファイルシステムに実装されています。これらは、cp
およびrsync
が検索し、正しいオプションが指定されたときにコピーされたファイルに転送するものです。ただし、system
名前空間は、chattr
属性を名前に、最終的には他のファイルシステムの同等の属性にマップするために存在するようですが、現時点では機能しません。
いくつかの良い情報がありますので、元の回答はそのままにしておきますが、ポイントではかなり間違っています。
私は今までにこれに戻ってきたはずですが、- この答え に従って、chattr
は単なるext
ファイルシステムでは機能しません。 Wikipedia によると、これはBSDベースのシステムのchflags
コマンドと同等です。
いくつかのファイルシステムでこれらの属性の設定と読み取りをテストするスクリプトを書いて、次の結果を得ました。
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
Wikipediaにいくつかの機能があると記載されているにもかかわらず、reiserfs
ファイルフラグを読み取ったり設定したりしようとすると、上記のエラーが発生します。 reiser4
はテストしていません。また、c
フラグをext4
に設定することもできますが、これは優先されません。これらのフラグに影響するチューニング/マウントオプションもあるかもしれませんが、見つかりませんでした。
ただし、現在、chattr
はLinuxでこれらの属性を変更できる唯一のユーティリティであるため、これらの属性を保持できるコピーユーティリティはありません。
rsync
の理由は、試してさえいないためだと思われます。 rsync
ドキュメントの-X
セクションから:
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.
chattr
およびlsattr
で使用される属性文字を、ファイルシステムで使用される基本的な名前付き属性にマップすることは困難です(インターネット上にリストがない場合)。しかし、私のテストでは、A
属性はsystem.posix_acl_access
属性にマップされ、これはsystem
名前空間であるため、rsync
はそれをコピーしようとしません。man
スニペットで言及されていない他の2つの名前空間は、trusted
とsecurity
です。これらを設定するにはroot権限が必要です(そしてrsync
はこれなしでは試せません)。
おそらく、設定しようとした属性は、system
が無視するrsync
名前空間に含まれます(おそらく賢明です)。それか、そうでないものを取得するにはrootになる必要があります。
cp
については、バグが発生しているようです。cp -a
でstrace
を実行すると、次の2つの興味深い行が得られます。
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
呼び出しが成功した場合に0
を返すため、問題の原因はfsetattr
のバグのようです。
ext4
でマウントするかどうかに関係なく、user_xattr
でこの動作が発生します。 「一部のシステム」では拡張属性が機能するためにこのマウントオプションが必要であると言う以外に、これに関するドキュメントは見つかりません。一見私のもの(Debian Jessie)はそうではない。私が見逃したマウントの問題があっても、fsetattr
、つまりcp
がサイレントに失敗するのは誤りです。
実際には、user_xattr
、ext2
、reiserfs
などのext3
が必要です。 ext4
の場合は必要ありません
また、attr
ツールsetfattr
、getfattr
、attr
(後者はXFS
専用であると記載されていますが、ext4
の他のツールと同様に機能するようです)は、user
名前空間以外では機能しません。 setfattr
を使用してsystem
名前空間に属性を配置しようとすると、Operation not supported
が表示されます(または、このように名前空間がない bug )。 setfattr
は、trusted
およびsecurity
名前空間で成功しているように見えますが、getfattr
は何も読み込めず、system
によって設定されたchattr
名前空間から何も読み込めません。 chattr
が成功する理由は、ioctl
ではなくlibattr
呼び出しを使用するためです。
ただし、完全に機能するのは、user
を使用してsetfattr
名前空間に拡張属性を設定し、rsync
またはcp
を使用してそれらをそのままコピーします(属性の作成時に値を指定しない場合は、cp
でも問題はありません)。結論としては、system
名前空間の値を使用することは現在 バギーおよび/または サポートされていません、少なくともDebianとおそらく他のディストリビューションでも。おそらくrsync
開発者はこれを知っているため、無視されます。