O que são "IDs de projeto" no Linux, conforme mencionado no manual do chattr?

O que são "IDs de projeto" no Linux, conforme mencionado no manual do chattr?

Eu estava lendo o manual da chattrminha 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 mke2fsao 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 setquotae quota(observe que versões antigas (-ish) das ferramentas podem não ter a -Popçã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 file1pertence ao projeto com id 123e 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.file2file35

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, file1herdamos o ID do projeto de foo. Se você criar mais arquivos/diretórios, fooeles 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. mvfará 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 lnacima). 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 mvnão vou sair ainda. É como mover-se entre sistemas de arquivos: depois de mvfalhar 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 mvrenomear 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 -pafeta 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.

informação relacionada