сохранение расширенных атрибутов с помощью 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.

Почему я не могу сохранить xattrс cpили rsync?

Дополнительная информация:

  • Исходная и целевая файловые системы являются ext4
  • И исходная, и целевая файловые системы являются локальными (не nfs)
  • Я использую Debian Wheezy
Мартин Вегтер
источник
Как вы монтируете эту целевую файловую систему? Это по NFS?
SLM
целевая
Можете ли вы показать вывод mountдля этой файловой системы?
SLM
1
На какой вариант и версию unix? Какие типы файловых систем на обоих концах, с какими вариантами монтирования?
Жиль "ТАК ... перестать быть злым"
1
@MartinVegter Не могли бы вы дать пример атрибута вашего файла? Я просто создал файловую систему ext4 в двух файлах и провел тестирование setfattr -n system.name0 -v "value" test_file. Я скопировал в test_file/ из ext4 / jfs / xfs cp --preserve=allи у меня не было проблем с сохранением расширенных атрибутов.
UVV

Ответы:

14

Обновить

После того, как мы еще немного поиграемся с этим и посмотрим на код chattrи прочее e2fsprogs, становится ясно, что атрибуты, установленные chattrи установленные libattr(например, с помощью команды setfattr), очень разные. chattrустанавливает extфлаги файловой системы, которые просто не отображаются на именованный атрибут или пространство имен. Ни один из них не отображаются с любым вызовом libattr«с listxattr. Они, вероятно, должны сопоставляться с именованными атрибутами в systemпространстве имен, как предполагается ниже, но на данный момент это полностью не реализовано. Также system.posix_acl_accessатрибут, который я принял за сопоставление с одним из этих атрибутов ниже, не имеет ничего общего с extфлагами файловой системы и скорее связан со списками контроля доступа. Связанныйstraceсообщения появляются для любого файла и исчезают, когда cp --preserve=xattrиспользуется только .

Кажется, что установленные атрибуты chattrспецифичны для extфайловых систем и что единственный способ повлиять на них - через e2fsprogsинструменты. На самом деле manстраница использует не термин «расширенные атрибуты», а «атрибуты файла». «Реальные» расширенные атрибуты - это пары имя / значение, которые могут быть изменены libattrи реализованы в нескольких файловых системах. Это то , что cpи rsyncискать и передавать к скопированным файлам , когда нужные параметры приведены. Однако кажется, что systemпространство имен существует для сопоставления chattrатрибутов с именами и, в конечном счете, с эквивалентными атрибутами в других файловых системах, но пока это не работает.

Я оставил первоначальный ответ нетронутым, поскольку там есть некоторая полезная информация, хотя в некоторых моментах он идет далеко не так.

Обновление 2

Я должен был вернуться к этому снова до сих пор, но согласно этому ответу , 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

Обратите внимание, что все попытки чтения / установки reiserfsфайловых флагов привели к вышеуказанной ошибке, несмотря на то, что она была указана в Википедии как имеющая некоторую функциональность. Я не проверял 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.

Трудно сопоставить буквы атрибутов, используемые chattrи lsattrс именованными атрибутами, используемыми в файловой системе (для одного нет списка в Интернете). Из моих тестов, однако, Aатрибут отображается на system.posix_acl_accessатрибут, и, поскольку это systemпространство имен, я rsyncдаже не буду пытаться его скопировать.Два других пространства имен, не упомянутых во manфрагменте, - это, trustedи securityдля их установки требуются привилегии root (и rsyncбез них не будет).

Скорее всего, атрибуты, которые вы пытались установить, попадают в systemпространство имен, которое rsyncигнорируется (и, вероятно, разумно). Либо это, либо вам нужно быть пользователем 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необходимо на ext2, ext3, reiserfsи , возможно , некоторых других. Это не обязательно дляext4

Следует также отметить , что attrинструменты setfattr, getfattrи attr(последний документирован быть только XFSтолько, но , кажется, работают точно так же , как и другие для ext4) имеют проблемы при работе в чем - либо , кроме userимен. Я получаю, Operation not supportedесли я пытаюсь использовать, setfattrчтобы поместить атрибут в systemпространство имен (или нет пространства имен согласно этой ошибке ). setfattrпо- видимому, добиться успеха в trustedи securityпространствах имен, но getfattrне в состоянии прочитать что - нибудь обратно , а также не в состоянии что - либо из чтения systemмножества имен с помощью chattr. Причиной этого chattrявляется то, что он использует ioctlвызов, а не libattr.

Что работает отлично, так это установка расширенных атрибутов в userпространстве имен с setfattrиспользованием rsyncи cpкопирование с ними в неизменном виде (проблем даже не возникает, cpесли вы не указали значение при создании атрибута). Я думаю, суть в том, что использование systemзначений пространства имен в настоящее времяглючит и / илине поддерживается, по крайней мере, в Debian и, возможно, в других дистрибутивах. Скорее всего, rsyncразработчики знают это, поэтому они игнорируют их.

Graeme
источник