Como o findmnt pode listar montagens de ligação?

11

Muitas pessoas continuam dizendo que o Linux não mantém informações sobre montagens de ligação, portanto não há como obter uma lista delas e de suas fontes. aqui estão alguns exemplos:

  • de um dos comentários aqui :

    As informações do IIRC não são mantidas em nenhum lugar: depois mount --bind, as duas cópias são equivalentes, não há uma que seja mais "original" que a outra. Afinal, não poderia haver original se você já estivesse desmontado /mnt.

  • de uma resposta neste site :

    Portanto, a única maneira de lembrar quais montagens eram montagens de ligação é o log de comandos de montagem restantes /etc/mtab. Uma operação de montagem de ligação é indicada pela opção de montagem de ligação (que faz com que o tipo de sistema de arquivos seja ignorado). Mas mount não tem opção para listar apenas sistemas de arquivos montados com um conjunto específico de conjuntos de opções.

  • de um relatório de bug do Debian :

    Isso é intencional. Ambos os pontos de montagem são totalmente iguais em todos os aspectos, portanto o kernel não mantém nenhum sinalizador para diferenciá-los.

O acima é um absurdo embora. A ferramenta findmnté capaz de listar os caminhos de origem das montagens de ligação (na forma de device[source-path]; também estou tentando fazê-lo listar apenas o caminho de origem e não o dispositivo). Se o kernel do Linux deve manter uma montagem de ligação, essas informações precisam ser armazenadas em algum lugar , caso contrário, não é possível saber a que /homeestá vinculado /users. Então, onde estão esses dados? É armazenado em alguma região obscura na RAM? Será que findmntolhar em /procalgum lugar?

Melab
fonte
Qual versão findmntvocê está executando e quais opções você está dando? O meu não imprime dessa maneira e, olhando o código-fonte que parece estar usando, o _PATH_PROC_MOUNTINFOque parece ser o /proc/self/mountinfoque também não tem essas informações.
Bratchley
OK, acho que /proc/self/mountinforelativamente recentemente foi reestruturado. Eu estava na minha máquina RHEL6 antes da qual não tinha as informações do caminho, mas minha máquina RHEL7 tem e, como mencionado no seu link, o Wheezy também.
Bratchley
Não é bobagem: era verdade com os kernels mais antigos, mas os kernels mais novos rastreiam as informações.
Gilles 'SO- stop be evil'
@Gilles Então, como uma montagem de ligação persistiria se as informações de que um diretório está montado em outro não são rastreadas?
MELAB
@ Melab Na verdade, é mais fácil persistir uma montagem de ligação se você não controlar que é uma montagem de ligação. Quando /dev/Amontado em /Be você faz mount --bind /B /C, os kernels mais antigos lembram apenas /B → /dev/Ae /C → /dev/A, eles não se lembram de nenhuma relação entre /Be /C. Portanto, desmontar /Bnaturalmente não tem efeito /C. Os kernels mais recentes lembram que /Cera uma montagem obrigatória /B, mas de uma maneira que não impede /Cque o trabalho continue se /Bfor desmontado, não sei exatamente como.
Gilles 'SO- stop be evil'

Respostas:

12

Você entendeu um pouco mal; os dois pontos de montagem são iguais em termos de permissões, sinalizadores etc. porque a ligação redireciona efetivamente o acesso de um caminho para outro. Mas eles ainda são distintos .

Se você observar, /proc/self/mountinfoverá a visão do kernel do mundo da montagem para esse processo (os espaços para nome tornam as coisas mais complicadas; não há apenas uma visão da tabela de montagem).

man 5 procexplicará o formato desse arquivo, mas você pode ver a hierarquia da árvore e onde as montagens de ligação têm seu "pai". Este é o arquivo que findmntanalisa.

Stephen Harris
fonte
9

O Linux não mantém as informações sobre qual montagem era uma montagem de ligação . Ele mantém informações sobre todas as montagens, incluindo montagens de ligação .

É bastante semelhante aos links físicos. Montagens vinculadas a sistemas de arquivos, como nomes de arquivos vinculados a inodes. As únicas diferenças são que as montagens também possuem sinalizadores por ponto de montagem e podem se referir a um subdiretório do sistema de arquivos de destino em vez da raiz do sistema de arquivos.

Quando você cria um link físico, o sistema de arquivos não salva qual nome de arquivo era o original e qual era o link físico. Ambos simplesmente se referem ao mesmo inode. Se você desvincular o arquivo original, a situação é indistinguível se você criou o arquivo diretamente com o segundo nome do arquivo.

Voltar para montagens de ligação: O kernel mantém uma tabela que contém o sistema de arquivos (identificado por um par maior: número menor), o ponto de montagem, o caminho relativo à raiz do sistema de arquivos e alguns sinalizadores. Você pode acessar esta lista olhando /proc/self/mountinfo. (Fica mais complicado quando espaços de nomes estão envolvidos, como @ stephen-harris mencionado). findmntanalisa esta lista.

Se sua raiz estiver /dev/sda1com o major: minor 8:1e você executar mount --bind /a /b /proc/self/mountinfo, conterá linhas semelhantes a esta:

1 0 8:1 / / rw - ext4 /dev/sda1 rw,errors=remount-ro
2 1 8:1 /a /b rw - ext4 /dev/sda1 rw,errors=remount-ro

Se você /homeestá /dev/sda2com o major: minor 8:2e você o executa mount --bind /home /users, será assim:

1 0 8:1 / / rw - ext4 /dev/sda1 rw,errors=remount-ro
2 1 8:2 / /home rw - ext4 /dev/sda2 rw
3 1 8:2 / /users rw - ext4 /dev/sda2 rw

As colunas relevantes para sua pergunta são a terceira, a quarta e a quinta. Estes são os IDs do sistema de arquivos (para sistemas de arquivos reais é o mesmo que o dispositivo principal: minor; para sistemas de arquivos virtuais como tmpfs é [0: counter ]), o caminho relativo à raiz do sistema de arquivos que está vinculado ao ponto de montagem (geralmente / para normal montagens, pode ser qualquer coisa para montagens de ligação) e o ponto de montagem.
Para o significado das colunas restantes, consulte a documentação do kernel do Linux .

findmntchama o caminho de origem relativo à raiz do sistema de arquivos "FSROOT". Você pode usar findmnt -o TARGET,FSROOTpara obtê-lo. Se quiser que o caminho de origem absoluta, você provavelmente precisará analisar /proc/self/mountinfopor si mesmo e combinar as informações sobre os suportes para o mesmo sistema de arquivos.

Para obter mais informações, consulte minha resposta em "Listar apenas montagens de ligação" .

cg909
fonte
Se /proc/self/mountinfopode conter linhas semelhantes 2 1 8:1 /a /b rw - ext4 /dev/sda1 rw,errors=remount-ro, então Linux certamente não manter algumas informações sobre montagens bind.
MELAB
Não. Veja o meu segundo exemplo. Ele mantém as informações de qual sistema de arquivos foi montado e qual caminho relativo à raiz do sistema de arquivos foi montado . Assim, para mount --bind /home/melab /mnta linha resultante pode parecer um dos seguintes dependendo de qual /homee /home/melabé um ponto de montagem: 3 1 8:1 /home/melab /mnt rw - ext4 /dev/sda1 rw, 3 1 8:2 /melab /mnt rw - ext4 /dev/sda2 rw,3 1 8:3 / /mnt rw - ext4 /dev/sda3 rw
cg909
É verdade que algo diferente /da quarta coluna geralmente indica uma montagem de ligação. Mas também pode ser um subvolume Btrfs.
cg909
É /dev/sda3suposto ser montado em /home/melab?
Melab 3/03
Sim. No meu exemplo eu usei /dev/sda1como /, /dev/sda2como /homee /dev/sda3como/home/melab
cg909 03/03