Eu li em livros que Unix / Linux não permite links físicos para diretórios, mas permite links físicos. É porque, quando temos ciclos e se criarmos links físicos e depois de algum tempo excluirmos o arquivo original, ele apontará para algum valor de lixo?
Se os ciclos foram a única razão por trás da não permissão de links físicos, então por que os links virtuais para diretórios permitido?
Comentários
cwd e se referir a isso quando vir um uso de..
. Claro, isso significaria que os links simbólicos precisariam ser criados com isso em mente, mas você já deve ter cuidado para não quebrar os links simbólicos e eu não ‘ não acho que essa regra adicional torne-os inúteis.
Resposta
Esta é apenas uma má ideia, pois lá não há como saber a diferença entre um link físico e um nome original.
Permitir links físicos para diretórios quebraria a estrutura gráfica acíclica direcionada do sistema de arquivos, possivelmente criando loops de diretório e subárvores de diretório pendentes, tornar fsck
e qualquer outro caminhador de árvore de arquivos sujeito a erros.
Primeiro, para entender isso, vamos falar sobre inodes. Os dados no sistema de arquivos são mantidos em blocos no disco, e esses blocos são reunidos por um inode. Você pode pensar no inode como O arquivo. No entanto, os inodes não têm nomes de arquivo. É aí que entram os links.
Um link é apenas um ponteiro para um inode. Um diretório é um inode que contém links. Cada nome de arquivo em um diretório é apenas um link para um inode. Abrir um arquivo no Unix também cria um link, mas é um tipo diferente de link (não é um link nomeado).
Um link físico é apenas uma entrada de diretório extra apontando para esse inode. Quando você ls -l
, o número após as permissões é a contagem de links nomeados. A maioria dos arquivos regulares terá um link. Criar um novo hard link para um arquivo fará com que os dois nomes de arquivo apontem para o mesmo inode. Nota:
% ls -l test ls: test: No such file or directory % touch test % ls -l test -rw-r--r-- 1 danny staff 0 Oct 13 17:58 test % ln test test2 % ls -l test* -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2 % touch test3 % ls -l test* -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2 -rw-r--r-- 1 danny staff 0 Oct 13 17:59 test3 ^ ^ this is the link count
Agora, você pode ver claramente que não existe link físico. Um link físico é igual a um nome normal. No exemplo acima, test
ou test2
, qual é o arquivo original e qual é o link físico? No final, você não pode “realmente dizer (mesmo por carimbos de data / hora) porque ambos os nomes apontam para o mesmo conteúdo, o mesmo inode:
% ls -li test* 14445750 -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test 14445750 -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2 14445892 -rw-r--r-- 1 danny staff 0 Oct 13 17:59 test3
O -i
sinalizar para ls
mostra os números de inode no início da linha. Observe como test
e test2
tem o mesmo número de inode, mas test3
tem um diferente.
Agora, se você pudesse faça isso para diretórios, dois diretórios diferentes em pontos diferentes no sistema de arquivos podem apontar para a mesma coisa. Na verdade, um subdiretório pode apontar de volta para seu avô, criando um loop.
Por que esse loop é uma preocupação ? Porque quando você está fazendo uma travessia, não há como detectar que está fazendo um loop (sem rastrear os números dos inodes conforme você faz a travessia). Imagine que você está escrevendo o comando du
, que precisa percorra subdiretórios para descobrir mais sobre o uso do disco. Como du
saberia o que n deu um loop? É propenso a erros e muita contabilidade que du
teria que fazer, apenas para realizar essa tarefa simples.
Symlinks são uma besta totalmente diferente, em que eles são um tipo especial de “arquivo” que muitas APIs de sistema de arquivos de arquivos tendem a seguir automaticamente. Observe, um link simbólico pode apontar para um destino inexistente, porque eles apontam por nome, e não diretamente para um inode. Esse conceito não faz sentido com links físicos, porque a mera existência de um “link físico” significa que o arquivo existe.
Então, por que du
pode lidar com links simbólicos facilmente e não links físicos? Pudemos ver acima que os links físicos são indistinguíveis das entradas normais do diretório. Os links simbólicos, no entanto, são especiais, detectáveis e puláveis! du
observa que o symlink é um symlink e o ignora completamente!
% ls -l total 4 drwxr-xr-x 3 danny staff 102 Oct 13 18:14 test1/ lrwxr-xr-x 1 danny staff 5 Oct 13 18:13 test2@ -> test1 % du -ah 242M ./test1/bigfile 242M ./test1 4.0K ./test2 242M .
Comentários
-
Allowing hard links to directories would break the directed acyclic graph structure of the filesystem
.Você pode explicar mais sobre o problema com os ciclos que usam links físicos? Por que está tudo bem com links simbólicos? - Eles parecem ter permitido em Macs adicionando detecção de ciclo à chamada de sistema link () e recusando-se a permitir que você crie um link físico de diretório se isso criar um ciclo . Parece ser uma solução razoável.
- @psusi mkdir -p a / b; nocheckln c a; mv c a / b; – o nocheckln existe um ln teórico que não verifica os argumentos do diretório e apenas passa para o link e, como nenhum ciclo é feito, todos somos bons em criar ‘ c ‘. em seguida, movemos ‘ c ‘ para ‘ a / b ‘, e um ciclo é criado a partir de a / b / c – > a / – verificar o link () não é bom o suficiente
- Os ciclos são muito ruins. O Windows tem esse problema com ” junções ” que são diretórios de link físico. Se você acidentalmente aplicar permissões a todo o seu perfil, ele descobrirá uma série de junções que criam um ciclo infinito. A recorrência nos diretórios ocorre até que as limitações do comprimento do caminho o interrompam.
- @WhiteWinterWolf, de acordo com este link, eles adicionaram suporte especificamente para a máquina do tempo, mas apenas o root tem permissão para fazer isso: superuser.com/questions/360926/…
Resposta
Você pode usar a montagem de ligação para simular diretórios de hard linking
sudo mount --bind /some/existing_real_contents /else/dummy_but_existing_directory sudo umount /else/dummy_but_existing_directory
Resposta
Com exceção dos pontos de montagem, cada diretório tem um e apenas pai: ..
.
Uma maneira de fazer pwd
é verificar o dispositivo: inode para “.” e “..”. Se eles forem iguais, você alcançou a raiz do sistema de arquivos. Caso contrário, encontre o nome do diretório atual no pai, empurre-o em uma pilha e comece a comparar “../.” com “../ ..”, depois “../../.” com “../../ ..”, etc. Depois de atingir a raiz, comece a destacar e imprimir os nomes da pilha. Este algoritmo se baseia no fato de que cada diretório tem um e apenas um pai.
Se links físicos para diretórios fossem permitidos, qual dos vários pais deveria ..
apontar? Essa é uma razão convincente pela qual links físicos para diretórios não são permitidos.
Symlinks para diretórios não causam esse problema. Se um programa quiser, ele pode fazer um lstat()
em cada parte do nome do caminho e detectar quando um link simbólico é encontrado. O pwd
algoritmo retornará o verdadeiro caminho absoluto para um diretório de destino. O fato de haver um pedaço de texto em algum lugar (o link simbólico) que aponta para o diretório de destino é bastante irrelevante. A existência de tal link simbólico não cria um loop no gráfico.
Comentários
- Não tenho tanta certeza sobre isso. Se pensarmos em
..
como uma espécie de hardlink virtual para o pai, não há razão técnica para que o destino do link possa ter apenas um outro link para ele.pwd
teria apenas que usar um algoritmo diferente para resolver o caminho.
Resposta
Gosto de acrescentar mais alguns pontos sobre esta questão. Links físicos para diretórios são permitidos no Linux, mas de forma restrita.
Uma maneira de testar isso é quando listamos o conteúdo de um diretório, encontramos dois diretórios especiais “.” e “..”. Como sabemos “.” aponta para o mesmo diretório e “..” aponta para o diretório pai.
Então, vamos criar uma árvore de diretórios onde “a” é o diretório pai que tem o diretório “b” como filho.
a `-- b
Anote o inode do diretório “a”. E quando fazemos um ls -la
do diretório “a”, podemos ver que “.” diretório também aponta para o mesmo inode.
797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 a
E aqui podemos descobrir que o diretório “a” tem três links físicos. Isso ocorre porque o inode 797358 tem três hardlinks em nome de “.” dentro do diretório “a” e nome como “..” dentro do diretório “b” e um com o nome “a” itslef.
$ ls -ali a/ 797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 . $ ls -ali a/b/ 797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 ..
Então, aqui podemos entender que os hardlinks existem para diretórios apenas para conexão com seus diretórios pai e filho. E assim, um diretório sem um filho terá apenas 2 links físicos, e o diretório “b” terá apenas dois links físicos.
Uma razão pela qual links físicos de diretórios foram impedidos livremente seria evitar loops de referência infinitos que irá confundir programas que atravessam o sistema de arquivos.
Como o sistema de arquivos é organizado em árvore e como árvore não pode ter referência cíclica, isso deve ter sido evitado. comentários “>
Resposta
Nenhuma das opções a seguir é a razão real para proibir links físicos para diretórios; cada problema é bastante fácil de resolver:
- ciclos na estrutura da árvore causam travessia difícil
- múltiplos pais, então qual é o “real”?
- coleta de lixo do sistema de arquivos
O motivo real (conforme sugerido por @ Thorbjørn Ravn Andersen) vem quando você exclui um diretório que tem vários pais, do diretório apontado por ..
:
O que ..
deve apontar agora?
Se o diretório for excluído de seu pai, mas seu número de links ainda é maior do que 0
então deve haver algo, em algum lugar ainda apontando para ele. Você não pode “deixar ..
apontando para nada; muitos programas dependem de ..
, então o sistema teria que atravessar o todo o sistema de arquivos até encontrar a primeira coisa que aponta para o diretório excluído, apenas para atualizar ..
. Ou isso, ou o sistema de arquivos teria que manter uma lista de todos os diretórios apontando para um diretório com link físico.
De qualquer maneira, isso seria uma sobrecarga de desempenho e uma complicação extra para os metadados e / ou código do sistema de arquivos, então os designers decidiram não permitir.
Comentários
- Isso ‘ também é fácil de resolver: mantenha uma lista dos pais de um diretório filho, que você atualiza ao adicionar ou remover um link para o filho. Ao excluir o pai canônico (o destino do filho ‘ s
), atualize
..
para apontar para um dos outros pais da lista. - Eu concordo. Não é ciência de foguetes para resolver. Mesmo assim, uma sobrecarga de desempenho e ocuparia um pouco mais de espaço nos metadados do sistema de arquivos e aumentaria a complicação. E então os designers optaram por uma abordagem simples e rápida – não ‘ não permita links para diretórios físicos.
- links Sym para dirs ” violam a semântica e os comportamentos estabelecidos “, mas ainda assim são permitidos. Alguns comandos, portanto, precisam de opções para controlar se os links simbólicos são seguidos (por exemplo, -L em find e cp). Quando um programa segue ‘ .. ‘ há mais confusão, portanto, a diferença na saída de pwd e / bin / pwd após atravessar um link sym. Não há ” respostas Unix “; apenas decisões de design. Este gira em torno do que acontece com ” .. ” como afirmei em minha resposta. Infelizmente, ‘ .. ‘ não ‘ nem mesmo foi mencionado na resposta de que todos os outros está votando a favor timidamente.
- A propósito, eu ‘ não estou dizendo que ‘ sou a favor de links físicos para dirs. De jeito nenhum. Não ‘ não quero que meu trabalho diário seja mais difícil do que já é.
- Não ‘ não é o que POSIX diz, mas IMO ‘ .. ‘ nunca deveria ter sido um conceito de sistema de arquivos, mas sim resolvido sintaticamente nos caminhos, para que
a/..
significaria sempre.
. É assim que os URLs funcionam, aliás. É ‘ é o navegador que ‘ está resolvendo ‘ .. ‘ antes mesmo de atingir o servidor. E funciona muito bem.
Resposta
A criação de hardlinks em diretórios seria irreversível. Suponha que temos:
/dir1 ├──this.txt ├──directory │ └──subfiles └──etc
Eu vinculei-o fisicamente a /dir2
.
Então, /dir2
agora também contém todos esses arquivos e diretórios
E se eu mudar de ideia? Eu não posso apenas rmdir /dir2
(porque não está vazio)
E se eu excluir recursivamente em /dir2
. .. será excluído de /dir1
também!
IMHO, é uma razão bastante suficiente para evitar isso!
Editar:
Os comentários sugerem a remoção do diretório fazendo rm
nele .Mas rm
em um diretório não vazio falha e esse comportamento deve permanecer, quer o diretório tenha um link físico ou não. Portanto, você pode “t apenas rm
desvinculá-lo. Seria necessário um novo argumento para rm
, apenas para dizer” se o inode do diretório tem uma contagem de referência> 1, então apenas desvincule o diretório “.
O que, por sua vez, quebra outro princípio de menor surpresa: isso significa que a remoção de um hardlink de diretório que acabei de criar não é o mesmo que remoção de um link físico de arquivo normal …
Vou reformular minha frase: Sem mais desenvolvimento, a criação do link físico seria irreversível (já que nenhum comando atual poderia lidar com a remoção sem ser incoerente com o comportamento atual)
Se permitirmos mais desenvolvimento para lidar com o caso, o número de armadilhas e o risco de perda de dados se você “não estamos suficientemente cientes de como o sistema funciona, tal desenvolvimento implica, IMHO é uma razão suficiente para restringir o hardlinking em diretórios.
Comentários
- Isso não deve ser um problema. Com o seu caso, quando criamos hardlink para dir2, temos que fazer hardlink para todos os conteúdos em dir1 e, portanto, se renomearmos ou excluirmos dir2, apenas um link extra para o inode será excluído. E isso não deve afetar dir1 e seu conteúdo, pois há pelo menos um link (dir1) para o inode.
- Seu argumento está incorreto. Você apenas desvincularia, não faria rm -rf. E se a contagem de links chegar a 0, o sistema saberá que pode excluir todo o conteúdo também.
- Que ‘ s mais ou menos todos os
rm
faz por baixo de qualquer maneira (desvincular). Veja: unix.stackexchange.com/questions/151951/… Isso realmente não é ‘ t é um problema, não mais do que é com arquivos com link físico. A desvinculação apenas remove a referência nomeada e diminui a contagem de links. O fato de quermdir
ganhou ‘ t excluir diretórios não vazios é irrelevante – não ‘ não faça isso paradir1
. Os hardlinks não são ‘ t cópias dos dados, são o mesmo arquivo real, portanto, ” excluindo ” o arquivo dir2 apagaria a lista de diretórios para dir1. Você sempre precisaria desvincular. - Você pode ‘ t apenas desvinculá-lo como um arquivo normal, porque
rm
em um diretório don ‘ t desvincule-o se ‘ não estiver vazio. Veja Editar.
Resposta
Esta é uma boa explicação. Quanto a “Para qual dos vários pais deve … apontar?” uma solução seria que um processo mantivesse seu caminho wd completo, como inodes ou como string. inodes seria mais robusto, pois os nomes podem ser alterados. Pelo menos nos velhos tempos, havia um inode interno para cada arquivo aberto que era incrementado sempre que um arquivo era aberto e diminuído quando fechado. Quando chegasse a zero, o armazenamento para o qual apontava seria liberado. Quando o arquivo não fosse mais aberto por ninguém, ele (a cópia in-core) seria abandonado. Isso manteria o caminho válido se algum outro processo movesse um diretório para outro enquanto o subdiretório estivesse no caminho de outro processo. Semelhante a como você pode excluir um arquivo aberto, mas ele é simplesmente removido do diretório, mas ainda aberto para qualquer processo que o tenha aberto.
Diretórios de links físicos costumavam ser permitidos gratuitamente no Bell Labs UNIX, pelo menos V6 e V7, não sei sobre Berkeley ou posterior. Nenhum sinalizador necessário. Você poderia fazer loops? Sim, não faça isso. É muito claro o que você está fazendo se fizer um loop. Além disso, você deve praticar dar nó em volta do pescoço enquanto espera sua vez de saltar de paraquedas de um avião, se a outra extremidade estiver convenientemente pendurada em um gancho na antepara. Eu esperava fazer com isso hoje era hard-link lhome to home para que eu pudesse ter / home / administ disponível ou não / home estava coberto com uma saída automática em casa, esse automount tendo um link simbólico chamado administ para / lhome / administ. Isso me permite ter uma conta administrativa que funciona independentemente do estado do meu sistema de arquivos inicial principal. Isso É um experimento para Linux, mas acho que aprendi uma vez para o SunOS baseado em UCB que as automontagens são feitas no nível de string ascii. É difícil ver como eles poderiam ser feitos de outra forma, como uma camada acima de qualquer FS arbitrário.
Eu li isso em outro lugar. e .. não são mais arquivos no diretório também. Tenho certeza de que há boas razões para tudo isso e que muito do que gostamos (como poder montar NTFS) é possível por causa dessas coisas, mas parte da elegância do UNIX estava na implementação.São os benefícios como generalidade e maleabilidade que esta elegância proporcionou que lhe permitiu ser tão robusto e durar por quatro décadas. À medida que perdemos as elegantes implementações, ele eventualmente se tornará como o Windows (espero estar errado!). Alguém criaria um novo sistema operacional baseado em princípios elegantes. Algo para pensar sobre. Talvez eu esteja errado, não estou (obviamente) familiarizado com a implementação atual. É incrível como o entendimento de 30 anos de idade é aplicável ao Linux … na maioria das vezes!
Comentários
- Eu acho, embora possa estar errado, que
.
e..
não são hardlinks no sistema de arquivos, para sistemas de arquivos modernos. No entanto, o driver do sistema de arquivos os falsifica. São esses sistemas de arquivos que interrompem os diretórios de links rígidos. Para sistemas de arquivos antigos, era possível (mas perigoso). Para fazer o que você está tentando, olhe emmount --bind
, veja tambémmount --make…
e talvez contêineres.
Resposta
Pelo que percebi, o principal motivo é que é útil poder alterar os nomes dos diretórios sem bagunçar os programas em execução que usam seus diretório de trabalho para fazer referência a outros arquivos. Suponha que você esteja usando o Wine para executar ~/.newwineprefix/drive_c/Program Files/Firefox/Firefox.exe
e deseja mover todo o prefixo para ~/.wine
. Se por algum motivo estranho o Firefox estava acessando drive_c/windows
referindo-se a ../../windows
, renomeando ~/.newwineprefix
quebras implementações de ..
que rastreiam o diretório pai como uma string de texto em vez de um inode.
Armazenar o inode de um único diretório pai deve ser mais simples do que tentar para acompanhar cada caminho como uma string de texto e uma série de inodes.
Outro motivo é que o mau comportamento ng aplicativos podem ser capazes de criar loops. Os aplicativos que se comportam devem ser capazes de verificar se o inode do diretório que está sendo movido é o mesmo que o inode de qualquer um dos diretórios aninhados para o qual está sendo movido, assim como você não pode mover um diretório para dentro dele, mas este pode não ser aplicado no nível do sistema de arquivos.
Outro motivo pode ser que, se você pudesse fazer um hardlink de diretórios, você gostaria de evitar o hardlink de um diretório que não pudesse modificar. find
tem considerações de segurança porque é usado para limpar arquivos criados por outros usuários de diretórios temporários, o que pode causar problemas se um usuário trocar um diretório real por um link simbólico enquanto find
está invocando outro comando. Ser capaz de vincular diretórios importantes forçaria um administrador a adicionar testes extras a find
para evitar afetá-los. (Ok, você já não posso fazer isso para arquivos, então este motivo é inválido.)
Ainda outro motivo é que armazenar o inode do diretório pai pode fornecer redundância extra em caso de corrupção ou dano do sistema de arquivos. queria ..
listar todos os diretórios pai que possuem link físico para este, então um pai diferente e arbitrário poderia ser facilmente encontrado se o atual fosse desvinculado, você não está apenas violando a ideia de que é difícil links são iguais, você deve alterar a forma como o sistema de arquivos armazena e usa inodes. Os programas tratam os caminhos como uma série (uniq para cada hardlink) de inodes de diretório evitaria isso, mas você não obteria a redundância no caso de danos ao sistema de arquivos.
..
deve apontar? Especialmente depois de remover o link físico para isso diretório, no diretório apontado por..
? Ele precisa apontar para algum lugar...
não ‘ não precisa existir fisicamente em qualquer unidade. É ‘ o sistema operacional ‘ função de manter o controle do diretório de trabalho atual, de qualquer maneira, por isso deve ser relativamente simples também manter uma lista de inodes associados a cada processo