preservando atributos estendidos com cp / rsync

12

Ao copiar cp, os atributos estendidos não são preservados, mesmo com explícitos

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

ou

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

O mesmo acontece com rsync, ie

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

No entanto, no sistema de arquivos de destino, posso criar atributos estendidos manualmente (com chattr). Isso significa que o sistema de arquivos de destino suporta xattr.

Por que não xattrconsigo preservar com cpou rsync?

Informação adicional:

  • Os sistemas de arquivos de origem e de destino são ext4
  • Os sistemas de arquivos de origem e de destino são locais (não nfs)
  • Estou usando o Debian Wheezy
Martin Vegter
fonte
Como você está montando esse sistema de arquivos de destino? É sobre NFS?
Slm
o sistema de arquivos de destino é um sistema de arquivos local
Martin Vegter
Você pode mostrar a saída mountdeste sistema de arquivos?
Slm
1
Em qual variante e versão unix? Quais tipos de sistema de arquivos nas duas extremidades, com quais opções de montagem?
Gilles 'SO- stop be evil'
1
@MartinVegter Você poderia dar um exemplo de atributo ao seu arquivo? Acabei de criar o sistema de arquivos ext4 em dois arquivos e fiz um teste com setfattr -n system.name0 -v "value" test_file. Copiei o test_file/ para ext4 / jfs / xfs com cp --preserve=alle não tive nenhum problema ao preservar atributos estendidos.
UVV

Respostas:

14

Atualizar

Depois de mexer um pouco mais com isso e examinar o código para chattroutro e2fsprogs, fica claro que os atributos definidos por chattre aqueles definidos por libattr( por exemplo, com o comando setfattr) são muito diferentes.chattrdefine extsinalizadores do sistema de arquivos que simplesmente não são mapeados para um atributo ou espaço para nome nomeado. Nenhum deles aparecem com qualquer chamada para libattr's listxattr. Eles provavelmente devem mapear para atributos nomeados no systemespaço para nome, conforme assumido abaixo, mas ainda não foi completamente implementado. Além disso, o system.posix_acl_accessatributo que confundi com o mapeamento para um desses atributos abaixo, não tem nada a ver com os extsinalizadores do sistema de arquivos e sim com as listas de controle de acesso. O associadostraceas mensagens aparecem para qualquer arquivo e desaparecem quando apenas cp --preserve=xattré usado.

Parece que os atributos definidos por chattrsão específicos para os extsistemas de arquivos e que a única maneira de afetá-los é atravése2fsprogs ferramentas. De fato, a manpágina não usa realmente o termo 'atributos estendidos' para eles, mas 'atributos de arquivo'. Atributos estendidos 'reais' são pares nome / valor que podem ser alterados libattre implementados em vários sistemas de arquivos. Estes são o que cpe rsyncprocurar e transferir para os arquivos copiados quando as opções corretas são dadas. Parece, no entanto, que systemexiste espaço para nome para mapear os chattratributos para nomes e, finalmente, para atributos equivalentes em outros sistemas de arquivos, mas por enquanto isso não funciona.

Eu deixei a resposta original intacta, pois há algumas informações boas lá, embora, em alguns casos, dê muito errado.

Atualização 2

Eu deveria ter voltado a isso novamente antes agora, mas, de acordo com essa resposta , chattrfunciona em mais do que apenas extsistemas de arquivos. Segundo a Wikipedia , é equivalente ao chflagscomando em sistemas baseados em BSD.

Escrevi um script para testar a configuração e a leitura desses atributos em alguns sistemas de arquivos e obtive os seguintes resultados:

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

Observe que todas as tentativas de ler / definir reiserfs sinalizadores de arquivo deram o erro acima, apesar de estar listado na Wikipedia como tendo alguma funcionalidade. Eu não testei reiser4. Além disso, embora o csinalizador possa ser definido, ext4isso não é respeitado. Também pode haver opções de ajuste / montagem que afetam esses sinalizadores, mas não encontrei nenhum.

No entanto, parece que atualmente chattré o único utilitário no Linux capaz de modificar esses atributos e, portanto, nenhum utilitário de cópia é capaz de preservá-los.

Resposta original

A razão para isso rsyncparece ser que nem sequer tenta. Na -Xseção da rsyncdocumentação:

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.

É difícil mapear as letras de atributo usadas por chattre lsattrpara os atributos nomeados subjacentes usados ​​no sistema de arquivos (para uma que não existe uma lista na Internet). Nos meus testes, porém, o Aatributo é mapeado para o system.posix_acl_accessatributo e, como esse é osystem espaço para nome, rsyncnem tentará copiá-lo.Os outros dois namespaces não mencionados no mansnippet são trustede security, são necessários privilégios de root para defini-los (e rsyncnão tentam sem).

Muito provavelmente os atributos que você tentou definir caem no systemespaço para nome que rsyncignora (e provavelmente com sabedoria). Ou isso ou você precisa ser root para obter os que não são.

Quanto a cp, parece haver bugs em jogo.Correndo straceem cp -a, recebo as seguintes duas linhas interessantes:

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

e

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

Em primeiro lugar, a fgetxattrchamada não retorna nenhum dado (provavelmente porque não existe - a existência do atributo é suficiente), mas de alguma forma cpencontra 28 bytes de dados (indesejados?) Para definir como o valor do atributo no arquivo de destino. Isso parece um bug cp, mas o que está causando os problemas parece ser um bug, libattrpois a fsetattrchamada retorna 0para o sucesso sem realmente definir o atributo.

Recebo esse comportamento ext4independentemente de montar com ele user_xattr. Não consigo encontrar nenhuma documentação sobre isso além de dizer que 'alguns sistemas' precisam dessa opção de montagem para que atributos estendidos funcionem. Aparentemente o meu (Debian Jessie) não. Mesmo que haja um problema de montagem que eu perdi, ele está errado fsetattre, portanto, cpfalha silenciosamente.

Realmente user_xattré necessário em ext2, ext3, reiserfse possivelmente alguns outros. Não é necessário paraext4

Observe também que as attrferramentas setfattr, getfattre attr(a última está documentada apenas para XFSapenas, mas parece funcionar tão bem quanto as demais ext4), têm problemas para trabalhar em qualquer coisa, menos no userespaço de nomes. Eu recebo Operation not supportedse eu tentar usar setfattrpara colocar um atributo no systemespaço para nome (ou nenhum espaço para nome conforme esse bug ). setfattrparece ter sucesso nos espaços de nome trustede security, mas getfattrfalha ao ler qualquer coisa de volta e também falha ao ler qualquer coisa do systemespaço de nome definido por chattr. O motivo chattré que ele usa uma ioctlchamada e não libattr.

No entanto, o que funciona perfeitamente é definir atributos estendidos no userespaço para nome setfattre usá -los rsyncou cpcopiá-los intactos (não há problemas cpse você não especificar um valor ao criar o atributo). Eu acho que a linha inferior é que o uso de systemvalores de namespace está atualmentebuggy e / ousem suporte, pelo menos no Debian e provavelmente em outras distros também. É provável que os rsyncdesenvolvedores saibam disso, e é por isso que eles os ignoram.

Graeme
fonte