Por que não consigo criar um `hardlink` para um arquivo a partir de um diretório“ mount --bind ”no mesmo sistema de arquivos?


9

Problema original

Eu tenho um arquivo em um sistema de arquivos: /data/src/file

e quero vinculá-lo a: /home/user/proj/src/file

mas /homeestá em um disco e /dataem outro, então eu recebo um erro:

$ cd /home/user/proj/src
$ ln /data/src/file .
ln: failed to create hard link './file' => '/data/src/file': Invalid cross-device link

Tudo bem, então aprendi que não consigo estabelecer uma ligação direta entre dispositivos. Faz sentido.

Problema em questão

Por isso, pensei em criar uma srcpasta montada em um /datasistema de arquivos:

$ mkdir -p /data/other/src
$ cd /home/user/proj
$ sudo mount --bind /data/other/src src/
$ cd src
$ # (now we're technically on `/data`'s file system, right?)
$ ln /data/src/file .
ln: failed to create hard link './file' => '/data/src/file': Invalid cross-device link

Por que isso ainda não funciona?

Gambiarra

Eu sei que tenho essa configuração correta, porque posso criar o link físico desde que eu esteja no /datadiretório "real" em vez do diretório vinculado.

$ cd /data/other/src
$ ln /data/src/file .
$ # OK
$ cd /home/user/proj/src
$ ls -lh
total 35M
-rw------- 2 user user 35M Jul 17 22:22 file

$

Algumas informações do sistema

$ uname -a
Linux <host> 4.10.0-24-generic #28-Ubuntu SMP Wed Jun 14 08:14:34 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

$ findmnt
.
.
.
├─/home                               /dev/sdb8   ext4       rw,relatime,data=ordered
│ └─/home/usr/proj/src             /dev/sda2[/other/src]
│                                                 ext4       rw,relatime,data=ordered
└─/data                               /dev/sda2   ext4       rw,relatime,data=ordered

$ mountpoint -d /data
8:2

$ mountpoint -d /home/usr/proj/src/
8:2

Nota : Alterei manualmente os nomes de arquivos e diretórios para tornar a situação mais clara, para que possa haver um erro de digitação ou dois nas leituras de comando.


2
Não importa onde você monta a pasta. Eles são físicos em diferentes partições. Cada partição possui sua própria tabela de arquivos e o hardlink é apenas um registro nesta tabela.
user996142

2
O ponto aqui é que os arquivos NÃO estão em partições fisicamente diferentes. É o mesmo sistema de arquivos da mesma partição. A diferença é a montagem de ligação.
roaima 21/07

A montagem de ligação é apenas uma ficção. Não altera as estruturas de dados nos discos. Os sistemas de arquivos ainda estão fisicamente separados.
21817 Bob Eager

Mas quando eu crio o link /datafísico, posso acessar o inode a partir do diretório de montagem de ligação, portanto, a montagem de ligação deve estar na mesma partição /dataou o link físico está funcionando em dispositivos, o que deve ser ilegal, mas funciona de qualquer maneira. o que estou perdendo?
jdk1.0

Respostas:


6

Há uma decepcionante falta de comentários no código . É como se ninguém nunca considerasse útil, uma vez que as montagens de ligação temporizada foram implementadas na v2.4. Certamente tudo o que você precisa fazer é substituir o .mnt->mnt_sbque diz .mnt...

Porque fornece um limite de segurança em torno de uma subárvore.

PS: isso já foi discutido algumas vezes, mas para evitar pesquisas: considere, por exemplo, mount --bind / tmp / tmp; agora você tem uma situação em que os usuários não podem criar links para outros lugares sem fs raiz, mesmo que eles tenham / tmp gravável para eles. Técnicas semelhantes funcionam para outras necessidades de isolamento - basicamente, você pode confinar renomear / vincular a determinada subárvore. IOW, é uma característica deliberada. Observe que você pode vincular um monte de árvores ao chroot e obter restrições previsíveis, independentemente de como as coisas possam ser reorganizadas um ano depois na árvore principal, etc.

- Al Viro

Há um exemplo concreto mais abaixo na discussão

Sempre que o mount -r --bind trabalha corretamente (que eu uso para colocar cópias das bibliotecas compartilhadas necessárias dentro das cadeias chroot, permitindo o compartilhamento de cache da página), esse recurso prejudica a segurança.

mkdir /usr/lib/libs.jail
for i in $LIST_OF_LIBRARIES; do
ln /usr/lib/$i /usr/lib/libs.jail/$i
done
mount -r /usr/lib/libs.jail /jail/lib
chown prisoner /usr/log/jail
mount /usr/log/jail /jail/usr/log
chrootuid /jail prisoner /bin/untrusted &

Embora as proteções devam ser suficientes, prefiro evitar o link do prisioneiro /jail/lib/libfoo.so (a gravação retorna EROFS) para / jail / usr / log, onde é potencialmente gravável.


-1

O motivo pelo qual você não pode fazer a vinculação entre dispositivos é porque você introduz ambiguidades. A entrada de diretório para o arquivo contém (em sistemas simples) o número do nó i do arquivo em questão. Um link físico (apenas outra entrada de diretório) também deve conter o mesmo número de nó i. Isso é bom, mas os números dos nós i são únicos em um único sistema de arquivos (geralmente são um conjunto denso começando em 1).

Sua montagem de ligação não corrige esse problema. Sim, ele constrói um tipo de 'ficção' da estrutura, mas o que não faz é renumerar todos os nós-i em um sistema de arquivos para garantir que eles sejam únicos nos dois sistemas de arquivos envolvidos! Isso seria bobagem.

Essa restrição sempre esteve presente nos sistemas UNIX. O link simbólico foi inventado em parte para resolver isso. Eu sei que eles não são funcionalmente iguais, mas geralmente são bons.

Tente um link simbólico? ( ln -s)


Não haveria nome para qualquer inode renumerado aqui. Existe apenas um sistema de arquivos subjacente, com duas visualizações.
Gilles 'SO- stop be evil'

Uma razão pela qual eu não queria um link simbólico era porque meus caminhos eram longos e era confuso fazer um ls -l. Meio raciocínio bobo no começo, mas depois levar a um buraco de coelho e fiquei curioso sobre o que estava acontecendo com os links de disco rígido ...
jdk1.0

@ Gilles, era o que eu estava dizendo. O que eu estava argumentando era que a renumeração de inodes seria ridícula. Não faço ideia por que uma resposta correta foi rebaixada.
22617 Bob Eager

Você chegou à conclusão certa, mas sua explicação está errada em tantos lugares que sua resposta como um todo é muito enganadora. Veja a resposta do sourcejedi para uma boa explicação.
Gilles 'SO- stop be evil'

Não vejo nenhum erro, embora admita que poderia ter sido mais claro.
22817 Bob Eager
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.