
Eu estava lendo o manual da chattr
minha máquina Linux ( kali4-amd64
) quando vi isso na lista de definições de atributos de arquivo:
A directory with the 'P' attribute set will enforce a hierarchical
structure for project id's. This means that files and directory created in
the directory will inherit the project id of the directory, rename
operations are constrained so when a file or directory is moved into
another directory, that the project id's much match. In addition, a hard
link to file can only be created when the project id for the file and the
destination directory match.
Eu pessoalmente não sei o que é um "ID de projeto" quando se trata de Linux/UNIX, e muitas pesquisas no Google também não obtiveram resultados, então espero que alguém aqui possa me ajudar.
Responder1
O que você está perguntando faz parte do conceito de cotas de projeto. As cotas do projeto são uma forma de gerenciarcota de disco. Um tipo específico de sistema de arquivos pode ou não suportar IDs de projeto. Vamos nos concentrar no ext4 e começar com man 8 tune2fs
:
-O [^]feature[,...]
Defina ou desmarque os recursos (opções) indicados do sistema de arquivos no sistema de arquivos. […][…]
project
Ative o rastreamento de ID do projeto. Isso é usado para rastreamento de cotas do projeto.
quota
Habilite inodes de cota do sistema de arquivos interno.[…]
-Q quota-options
Define o recurso de 'cota' no superbloco e funciona nos arquivos de cota para um determinado tipo de cota. As opções de cota podem ser uma ou mais das seguintes:
[^]usrquota
Define/limpa o inode da cota do usuário no superbloco.
[^]grpquota
Define/limpa o inode de cota de grupo no superbloco.
[^]prjquota
Define/limpa o inode da cota do projeto no superbloco.
Você pode ativar estas opções em um sistema de arquivos existente:
tune2fs -O project,quota /your/device
(ou forneça-os mke2fs
ao criar um novo sistema de arquivos). Em seguida, ative a cota do projeto (possivelmente com cota de usuário e/ou cota de grupo, se desejar):
tune2fs -Q prjquota /your/device
Monte-o:
mount /your/device /the/mountpoint
Agora você pode gerenciar cotas com ferramentas como setquota
e quota
(observe que versões antigas (-ish) das ferramentas podem não ter a -P
opção que lida com cotas de projeto). Tradicionalmente, você limitaria a quantidade de espaço em disco que o usuário ou grupo pode usar. Com cota de projeto você pode fazer isso para “projetos”, independente dos usuários e grupos que participam.
Funciona assim. Primeiro coloque-se no ponto de montagem e crie alguns diretórios:
cd /the/mountpoint
mkdir foo bar baz
Habilite a hierarquia do projeto neles:
chattr +P foo bar baz
Atribua-os a dois projetos diferentes:
chattr -p 123 foo # 123 is an arbitrary number, project id
chattr -p 5 bar baz # so is 5, the point is they are different
Crie arquivos dentro de:
echo "lorem ipsum" > foo/file1
echo "lorem ipsum" > bar/file2
echo "lorem ipsum" > baz/file3
Agora invoque:
lsattr -pR .
e você verá (entre outras) linhas como esta:
123 --------------e---P ./foo/file1
5 --------------e---P ./bar/file2
5 --------------e---P ./baz/file3
o que significa que file1
pertence ao projeto com id 123
e pertence ao projeto com id . Se você definir cotas para esses projetos (ou seja, limitar a quantidade de espaço em disco que os projetos podem usar), cada arquivo afetará o consumo de cotas de seu respectivo projeto.file2
file3
5
Agora o que você citou faz muito sentido:
arquivos e diretórios criados no diretório herdarão o ID do projeto do diretório
Em nosso exemplo, file1
herdamos o ID do projeto de foo
. Se você criar mais arquivos/diretórios, foo
eles também herdarão o ID. Isso permite que você (e outros usuários) trabalhem no projeto em seu diretório designado, enquanto os arquivos criados contam automaticamente para a respectiva cota.
um link físico para o arquivo só pode ser criado quando o ID do projeto do arquivo e o diretório de destino corresponderem.
ln ./baz/file3 ./foo/
falhará (tente), mas ln ./baz/file3 ./bar/
terá sucesso. O sistema operacional não permitirá que você "incorpore" facilmente um arquivo que pertence a um projeto (e deve permanecer assim porque o caminho de origem não está desvinculado) em um diretório de projeto diferente. É permitido vincular um arquivo dentro de seu projeto.
quando um arquivo ou diretório é movido para outro diretório, os IDs do projeto devem corresponder
Eu acho que isso é bastante enganador. mv
fará seu trabalho mesmo que os IDs não correspondam. A questão é que se você invocar
mv baz/file3 foo/
a ferramenta tentará primeiro transferir rename(2)
o arquivo para o novo caminho, mas isso falhará (como ln
acima). Normalmente ou dentro do mesmo projeto teria sucesso e o nome original desapareceria. Aparentemente, esse comportamento é o motivo de "os IDs do projeto devem corresponder".
Mas mv
não vou sair ainda. É como mover-se entre sistemas de arquivos: depois de mv
falhar na renomeação, ele volta ao modo copiar + excluir. Com efeito, cria umacópia de(com um novo número de inode) no diretório de destino. No nosso caso, a cópia herda o id do projeto de foo
(como qualquer novo arquivo neste diretório faria), portanto afeta o consumo de cota de project 123
. O caminho original é então desvinculado. Isto pode afetar o consumo de cotas do projeto 5
; ou não: hardlinks ou descritores de arquivos abertos farão com que o inode e os dados originais sobrevivam.
Observe que é um tanto surpreendente: um novo arquivo é criado, hardlinks antigos (se houver) não estão vinculados ao novo arquivo, os descritores de arquivo que apontam para o arquivo antigo não têm nada a ver com o novo; como se a operação de movimentação fosse executada entre sistemas de arquivos.
Existe uma maneira de mv
renomear em vez de copiar + excluir. Se você atribuir manualmente o arquivo original ao projeto de destino
chattr -p 123 baz/file3
então mv baz/file3 foo/
irá realmente movê-lo sem copiar, sem quebrar hardlinks (se houver). Mas observe que o número do projeto pertence ao inode (não ao caminho, nem ao nome, nem à entrada do diretório), portanto, chattr -p
afeta todos os hardlinks.
Portanto, se você precisar mover um arquivo grande (ou seja, dados atrás de algum inode, não apenas um dos muitos hardlinks) para outro projeto, alterar o projeto e depois movê-lo evitará cópias desnecessárias.