O que é uma montagem de ligação?

325

O que é uma "montagem de ligação"? Como eu faço um? Para que serve?

Foi-me dito para usar uma montagem de ligação para algo, mas não entendo o que é ou como usá-lo.

Gilles
fonte
2
esclarecimento alternativo útil entre montagens e links simbólicos: quora.com/…
Charlie Parker

Respostas:

564

O que é uma montagem de ligação?

Uma montagem de ligação é uma visualização alternativa de uma árvore de diretórios. Classicamente, a montagem cria uma visualização de um dispositivo de armazenamento como uma árvore de diretórios. Uma montagem de ligação pega uma árvore de diretórios existente e a replica em um ponto diferente. Os diretórios e arquivos na montagem de ligação são os mesmos que o original. Qualquer modificação de um lado é imediatamente refletida no outro lado, pois as duas visualizações mostram os mesmos dados.

Por exemplo, depois de emitir o comando Linux

mount --bind /some/where /else/where

os diretórios /some/wheree /else/wheretêm o mesmo conteúdo.

Ao contrário de um link físico ou simbólico, uma montagem de ligação não afeta o que é armazenado no sistema de arquivos. É uma propriedade do sistema ativo.

Como crio uma montagem de ligação?

bindfs

O bindfssistema de arquivos é um sistema de arquivos FUSE que cria uma visualização de uma árvore de diretórios. Por exemplo, o comando

bindfs /some/where /else/where

cria /else/whereum ponto de montagem sob o qual o conteúdo de /some/whereé visível.

Como o bindfs é um sistema de arquivos separado, os arquivos /some/where/fooe /else/where/fooaparecem como arquivos diferentes para os aplicativos (o sistema de arquivos bindfs tem seu próprio st_devvalor). Qualquer mudança de um lado é “magicamente” refletida no outro lado, mas o fato de os arquivos serem iguais é apenas aparente quando se sabe como o bindfs opera.

O Bindfs não tem conhecimento dos pontos de montagem; portanto, se houver um ponto de montagem abaixo /some/where, ele aparecerá como apenas outro diretório abaixo /else/where. Montar ou desmontar um sistema de arquivos debaixo /some/whereaparece sob /else/wherecomo uma mudança do diretório correspondente.

O Bindfs pode alterar alguns dos metadados do arquivo: pode mostrar permissões falsas e propriedade dos arquivos. Veja o manual para detalhes e veja abaixo exemplos.

Um sistema de arquivos bindfs pode ser montado como um usuário não raiz, você só precisa do privilégio de montar sistemas de arquivos FUSE. Dependendo da sua distribuição, isso pode exigir que você esteja no fusegrupo ou seja permitido a todos os usuários. Para desmontar um sistema de arquivos FUSE, use em fusermount -uvez de umount, por exemplo

fusermount -u /else/where

nullfs

O FreeBSD fornece o nullfssistema de arquivos que cria uma visão alternativa de um sistema de arquivos. Os dois comandos a seguir são equivalentes:

mount -t nullfs /some/where /else/where
mount_nullfs /some/where /else/where

Depois de emitir qualquer comando, /else/wheretorna-se um ponto de montagem no qual o conteúdo de /some/whereé visível.

Como o nullfs é um sistema de arquivos separado, os arquivos /some/where/fooe /else/where/fooaparecem como arquivos diferentes dos aplicativos (o sistema de arquivos nullfs tem seu próprio st_devvalor). Qualquer mudança de um lado é “magicamente” refletida no outro lado, mas o fato de os arquivos serem os mesmos só é aparente quando se sabe como o nullfs opera.

Diferentemente dos bindfs do FUSE, que atuam no nível da árvore de diretórios, o nullfs do FreeBSD atua mais profundamente no kernel, portanto os pontos de montagem abaixo /else/wherenão são visíveis: somente a árvore que faz parte do mesmo ponto de montagem /some/whererefletida abaixo /else/where.

O sistema de arquivos nullfs pode ser usado em outras variantes do BSD (OS X, OpenBSD, NetBSD), mas não é compilado como parte do sistema padrão.

Montagem de ligação do Linux

No Linux, montagens de ligação estão disponíveis como um recurso do kernel. Você pode criar um com o mountcomando, passando a --bindopção de linha de comando ou a bindopção de montagem. Os dois comandos a seguir são equivalentes:

mount --bind /some/where /else/where
mount -o bind /some/where /else/where

Aqui, o "dispositivo" /some/wherenão é uma partição de disco, como no caso de um sistema de arquivos em disco, mas um diretório existente. O ponto de montagem /else/wheredeve ser um diretório existente, como de costume. Observe que nenhum tipo de sistema de arquivos é especificado de qualquer maneira: fazer uma montagem de ligação não envolve um driver de sistema de arquivos, ele copia as estruturas de dados do kernel da montagem original.

mount --bindtambém suporta a montagem de um não diretório em um não diretório: /some/wherepode ser um arquivo regular (nesse caso, também /else/whereprecisa ser um arquivo regular).

Uma montagem de ligação do Linux é praticamente indistinguível da original. O comando df -T /else/wheremostra o mesmo dispositivo e o mesmo tipo de sistema de arquivos que df -T /some/where. Os arquivos /some/where/fooe /else/where/foosão indistinguíveis, como se fossem links físicos. É possível desmontar /some/where, caso em que /else/wherepermanece montado.

Com os kernels mais antigos (não sei exatamente quando, acho que até o 3.x), montagens de ligação eram realmente indistinguíveis da original. Os kernels recentes rastreiam montagens de ligação e expõem as informações através do PID / mountinfo, o que permite findmntindicar a montagem de ligação como tal .

Você pode inserir entradas de montagem de ligação /etc/fstab. Basta incluir bind(ou rbindetc.) nas opções, juntamente com outras opções desejadas. O "dispositivo" é a árvore existente. A coluna do sistema de arquivos pode conter noneou bind(é ignorada, mas usar um nome de sistema de arquivos seria confuso). Por exemplo:

/some/where /readonly/view none bind,ro

Se houver pontos de montagem embaixo /some/where, seu conteúdo não estará visível embaixo /else/where. Em vez de bind, você também pode rbindreplicar pontos de montagem embaixo /some/where. Por exemplo, se /some/where/mnté um ponto de montagem,

mount --rbind /some/where /else/where

é equivalente a

mount --bind /some/where /else/where
mount --bind /some/where/mnt /else/where/mnt

Além disso, o Linux permite que as montagens sejam declaradas como compartilhadas , escravas , privadas ou não conectáveis . Isso afeta se essa operação de montagem é refletida em uma montagem de ligação que replica o ponto de montagem. Para mais detalhes, consulte a documentação do kernel .

O Linux também fornece uma maneira de mover montagens: onde --bindcopia, --movemove um ponto de montagem.

É possível ter diferentes opções de montagem em dois diretórios montados em ligação. No entanto, há uma peculiaridade: fazer a montagem de ligação e definir as opções de montagem não podem ser feitas atomicamente, elas precisam ser duas operações sucessivas. (Os kernels mais antigos não permitiam isso.) Por exemplo, os seguintes comandos criam uma exibição somente leitura, mas há uma pequena janela de tempo durante a qual a /else/whereleitura e gravação:

mount --bind /some/where /else/where
mount -o remount,ro,bind /else/where

Não consigo montar montagens de ligação para trabalhar!

Se o seu sistema não suportar o FUSE, um truque clássico para obter o mesmo efeito é executar um servidor NFS, exporte os arquivos que você deseja expor (permitindo acesso localhost) e monte-os na mesma máquina. Isso tem uma sobrecarga significativa em termos de memória e desempenho; portanto, as montagens bind têm uma vantagem definida quando disponível (que está na maioria das variantes do Unix, graças ao FUSE).

Casos de uso

Visualização somente leitura

Pode ser útil criar uma exibição somente leitura de um sistema de arquivos, por motivos de segurança ou apenas como uma camada de segurança para garantir que você não o modifique acidentalmente.

Com bindfs:

bindfs -r /some/where /mnt/readonly

Com o Linux, da maneira mais simples:

mount --bind /some/where /mnt/readonly
mount -o remount,ro,bind /mnt/readonly

Isso deixa um curto intervalo de tempo durante o qual /mnt/readonlyé leitura / gravação. Se isso for um problema de segurança, primeiro crie a montagem de ligação em um diretório que somente o root possa acessar, torne-a somente leitura e mova-a para um ponto de montagem público. No trecho abaixo, observe que é importante que /root/private(o diretório acima do ponto de montagem) seja privado; as permissões originais ativadas /root/private/mntsão irrelevantes, pois estão ocultas atrás do ponto de montagem.

mkdir -p /root/private/mnt
chmod 700 /root/private
mount --bind /some/where /root/private/mnt
mount -o remount,ro,bind /root/private/mnt
mount --move /root/private/mnt /mnt/readonly

Remapeando Usuários e Grupos

Os sistemas de arquivos registram usuários e grupos por seu ID numérico. Às vezes, você acaba com vários sistemas que atribuem diferentes IDs de usuário à mesma pessoa. Isso não é um problema com o acesso à rede, mas torna os IDs do usuário sem sentido quando você carrega dados de um sistema para outro em um disco. Suponha que você tenha um disco criado com um sistema de arquivos multiusuário (por exemplo, ext4, btrfs, zfs, UFS,…) em um sistema em que Alice tenha o ID do usuário 1000 e Bob o ID do usuário 1001, e você queira tornar esse disco acessível em um sistema em que Alice possui ID de usuário 1001 e Bob possui ID de usuário 1000. Se você montar o disco diretamente, os arquivos de Alice aparecerão como de propriedade de Bob (porque o ID de usuário é 1001) e os arquivos de Bob aparecerão como de propriedade de Alice (porque o o ID do usuário é 1000).

Você pode usar o bindfs para remapear os IDs do usuário. Primeiro monte a partição do disco em um diretório privado, onde somente o root pode acessá-la. Em seguida, crie uma visualização bindfs em uma área pública, com o ID do usuário e o ID do grupo remapeando, que trocam os IDs de usuário e de grupo de Alice e Bob.

mkdir -p /root/private/alice_disk /media/alice_disk
chmod 700 /root/private
mount /dev/sdb1 /root/private/alice_disk
bindfs --map=1000/1001:1001/1000:@1000/1001:@1001/1000 /root/private/alice_disk /media/alice_disk

Consulte Como é possível acessar arquivos na pasta inicial do usuário do sistema não inicializado? e monte - ligue outro usuário como eu outros exemplos.

Montagem em uma prisão ou contêiner

Uma cadeia ou contêiner chroot executa um processo em uma subárvore da árvore de diretórios do sistema. Isso pode ser útil para executar um programa com acesso restrito, por exemplo, executar um servidor de rede com acesso apenas aos seus próprios arquivos e aos arquivos que ele serve, mas não a outros dados armazenados no mesmo computador). Uma limitação do chroot é que o programa está confinado a uma subárvore: ele não pode acessar subárvores independentes. As montagens de ligação permitem enxertar outras subárvores nessa árvore principal. Isso os torna fundamentais para o uso mais prático de contêineres no Linux.

Por exemplo, suponha que uma máquina execute um serviço /usr/sbin/somethingdque só deve ter acesso aos dados em /var/lib/something. A menor árvore de diretórios que contém esses dois arquivos é a raiz. Como o serviço pode ser confinado? Uma possibilidade é criar links físicos para todos os arquivos em que o serviço precisa (pelo menos /usr/sbin/somethingde várias bibliotecas compartilhadas) /var/lib/something. Mas isso é complicado (as ligações duras precisam ser atualizados sempre que um arquivo é atualizado), e não funciona se /var/lib/somethinge /usrestão em diferentes sistemas de arquivos. Uma solução melhor é criar uma raiz ad hoc e preenchê-la usando montagens:

mkdir /run/something
cd /run/something
mkdir -p etc/something lib usr/lib usr/sbin var/lib/something
mount --bind /etc/something etc/something
mount --bind /lib lib
mount --bind /usr/lib usr/lib
mount --bind /usr/sbin usr/sbin
mount --bind /var/lib/something var/lib/something
mount -o remount,ro,bind etc/something
mount -o remount,ro,bind lib
mount -o remount,ro,bind usr/lib
mount -o remount,ro,bind usr/sbin
chroot . /usr/sbin/somethingd &

Os namespaces de montagem do Linux generalizam chroots. Montagens de ligação são como espaços para nome podem ser preenchidos de maneiras flexíveis. Consulte Fazendo um processo ler um arquivo diferente para o mesmo nome de arquivo para um exemplo.

Executando uma Distribuição Diferente

Outro uso do chroots é instalar uma distribuição diferente em um diretório e executar programas a partir dele, mesmo quando eles exigem arquivos em caminhos codificados que não estão presentes ou têm conteúdo diferente no sistema base. Isso pode ser útil, por exemplo, para instalar uma distribuição de 32 bits em um sistema de 64 bits que não suporta pacotes mistos, para instalar versões mais antigas de uma distribuição ou outras distribuições para testar a compatibilidade, para instalar uma versão mais nova para testar os recursos mais recentes, mantendo um sistema base estável, etc. Consulte Como executo programas de 32 bits em um Debian / Ubuntu de 64 bits? por um exemplo no Debian / Ubuntu.

Suponha que você tenha uma instalação dos pacotes mais recentes da sua distribuição no diretório /f/unstableonde executa os programas alternando para esse diretório chroot /f/unstable. Para disponibilizar diretórios pessoais nessas instalações, monte-os no chroot:

mount --bind /home /f/unstable/home

O programa schroot faz isso automaticamente.

Acessando arquivos ocultos atrás de um ponto de montagem

Quando você monta um sistema de arquivos em um diretório, isso oculta o que está por trás do diretório. Os arquivos nesse diretório ficam inacessíveis até que o diretório seja desmontado. Como as montagens de ligação BSD nullfs e Linux operam em um nível mais baixo do que a infraestrutura de montagem, uma montagem nullfs ou uma montagem de ligação de um sistema de arquivos expõe diretórios que estavam ocultos atrás dos submounts no original.

Por exemplo, suponha que você tenha um sistema de arquivos tmpfs montado em /tmp. Se havia arquivos em /tmpquando o sistema de arquivos tmpfs foi criado, esses arquivos ainda podem permanecer, efetivamente inacessíveis, mas ocupando espaço em disco. Corre

mount --bind / /mnt

(Linux) ou

mount -t nullfs / /mnt

(FreeBSD) para criar uma visão do sistema de arquivos raiz em /mnt. O diretório /mnt/tmpé o do sistema de arquivos raiz.

Exportações NFS em diferentes caminhos

Alguns servidores NFS (como o servidor NFS do kernel Linux antes do NFSv4) sempre anunciam o local do diretório real quando exportam um diretório. Ou seja, quando um cliente solicita server:/requested/location, o servidor serve a árvore no local /requested/location. Às vezes, é desejável permitir que os clientes solicitem, /request/locationmas na verdade sirvam os arquivos abaixo /actual/location. Se o servidor NFS não suportar a localização de um local alternativo, você poderá criar uma montagem de ligação para a solicitação esperada, por exemplo

/requested/location *.localdomain(rw,async)

em /etc/exportse o seguinte em /etc/fstab:

/actual/location /requested/location bind bind

Um substituto para links simbólicos

Às vezes, você deseja criar um link simbólico para fazer com que um arquivo /some/where/is/my/fileapareça abaixo /else/where, mas o aplicativo que usa fileexpande os links simbólicos e rejeita /some/where/is/my/file. Uma montagem de ligação pode contornar isso: bind-mount /some/where/is/mypara /else/where/is/mye, em seguida realpath, reportará /else/where/is/my/fileestar abaixo /else/where, não abaixo /some/where.

Efeitos colaterais de montagens de ligação

Travessias de diretório recursivas

Se você usar montagens de ligação, precisará cuidar de aplicativos que percorrem a árvore do sistema de arquivos recursivamente, como backups e indexação (por exemplo, para criar um banco de dados de localização ).

Geralmente, montagens de ligação devem ser excluídas de percursos de diretório recursivos, para que cada árvore de diretório seja percorrida apenas uma vez, no local original. Com bindfs e nullfs, configure a ferramenta transversal para ignorar esses tipos de sistema de arquivos, se possível. As montagens de ligação do Linux não podem ser reconhecidas como tal: o novo local é equivalente ao original. Com montagens de ligação do Linux ou com ferramentas que podem excluir apenas caminhos e não tipos de sistema de arquivos, é necessário excluir os pontos de montagem para as montagens de ligação.

Traversals que param nos limites do sistema de arquivos (por exemplo find -xdev, rsync -x, du -x, ...) irá parar automaticamente quando se deparam com um bindfs ou nullfs ponto de montagem, porque esse ponto de montagem é um sistema de arquivos diferente. Com montagens de ligação do Linux, a situação é um pouco mais complicada: existe um limite do sistema de arquivos apenas se a montagem de ligação estiver enxertando um sistema de arquivos diferente, não se estiver enxertando outra parte do mesmo sistema de arquivos.

Indo além das montagens de ligação

Montagens de ligação fornecem uma visão de uma árvore de diretórios em um local diferente. Eles expõem os mesmos arquivos, possivelmente com diferentes opções de montagem e (com bindfs) diferentes propriedades e permissões. Os sistemas de arquivos que apresentam uma visão alterada de uma árvore de diretórios são chamados de sistemas de arquivos de sobreposição ou sistemas de arquivos empilháveis . Existem muitos outros sistemas de arquivos de sobreposição que executam transformações mais avançadas. Aqui estão alguns comuns. Se o seu caso de uso desejado não for abordado aqui, verifique o repositório de sistemas de arquivos FUSE .

Filtrar arquivos visíveis

  • clamfs - executa arquivos através de um antivírus quando são lidos
  • filterfs - oculta partes de um sistema de arquivos
  • rofs - uma visualização somente leitura. Semelhante a bindfs -r, apenas um pouco mais leve.
  • Montagens de união - apresente vários sistemas de arquivos (chamados ramos ) em um único diretório: se tree1contém fooe tree2contém bar, sua visualização de união contém ambos fooe bar. Novos arquivos são gravados em uma ramificação específica ou em uma ramificação escolhida de acordo com regras mais complexas. Existem várias implementações desse conceito, incluindo:

    • aufs - Implementação do kernel Linux, mas rejeitada upstream muitas vezes
    • funionfs - implementação do FUSE
    • mhddfs - FUSE, grava arquivos em um ramo com base no espaço livre
    • overlay - Implementação do kernel do Linux, mesclada no upstream no Linux v3.18
    • unionfs-fuse - FUSE, com recursos de armazenamento em cache e cópia na gravação

Modificar nomes de arquivos e metadados

  • ciopfs - nomes de arquivos que não diferenciam maiúsculas de minúsculas (podem ser úteis para montar sistemas de arquivos do Windows)
  • convmvfs - converte nomes de arquivos entre conjuntos de caracteres ( exemplo )
  • posixovl - armazena nomes de arquivos Unix e outros metadados (permissões, propriedade,…) em sistemas de arquivos mais restritos, como VFAT ( exemplo )

Exibir conteúdo do arquivo alterado

Modifique a maneira como o conteúdo é armazenado

  • chironfs - replica arquivos em vários armazenamentos subjacentes ( RAID-1 no nível da árvore de diretórios )
  • copyfs - mantém cópias de todas as versões dos arquivos
  • encfs - criptografa arquivos
  • pcachefs - camada de cache em disco para sistemas de arquivos remotos lentos
  • simplecowfs - armazena alterações através da visualização fornecida na memória, deixando os arquivos originais intactos
  • wayback - mantém cópias de todas as versões dos arquivos
Gilles
fonte
1
um pode querer adicionar um exemplo de como fazê-lo com Systemd: utcc.utoronto.ca/~cks/space/blog/linux/SystemdBindMountUnits
dothebart
1
O que mount --bind /dir1 /dir1faz? Como é diferente do caso em que a origem e o destino da montagem são diferentes?
Mark
Não vi nenhum registro em / proc / self / mountinfo, usando o linux 5.0. O kernel não me diz que é mount mount ou não. E um processo pode facilmente quebrar o chroot, o isolamento deve ser feito pelo espaço para nome da montagem.
炸鱼 薯条 德里克 22/03
@ 德里克 薯条 德里克 Acho que a pergunta vinculada unix.stackexchange.com/questions/295525/… aborda /proc/self/mountinfo. Quanto ao chroot, ele pode ser usado para isolamento, mas não por si só. Você não precisa montar namespaces: chroot é suficiente para a parte do namespace do sistema de arquivos. Você precisa garantir que nenhum processo no chroot seja executado como o mesmo usuário que um processo fora do chroot.
Gilles
@Mark A montagem de um diretório em si não é muito útil. Eu acho que você poderia usá-lo para ocultar sistemas de arquivos montados em um determinado diretório, mas não consigo pensar em um momento em que eu quisesse fazer isso especificamente.
Gilles
-1

Simples, quando você usa a montagem de ligação, um arquivo ou diretório na máquina host é montado em um contêiner, para que quaisquer alterações feitas dentro do diretório de arquivos na máquina host estejam automaticamente disponíveis dentro do contêiner no diretório.

srinivas
fonte
Essa é uma das maneiras de usar uma montagem de ligação, mas as montagens de ligação em si não têm nada a ver com contêineres. Mencionei isso na minha resposta, mas sob o nome "prisão" em vez de "contêiner"; adicionar "contêiner" seria uma edição valiosa (eu faço isso). Esta também é uma descrição pobre: ​​por que mencionar que as alterações feitas fora também estão disponíveis dentro sem mencionar o contrário?
Gilles