Li em livros de texto que o Unix / Linux não permite links físicos para diretórios, mas permite links físicos. É porque, quando temos ciclos e se criamos links físicos, e depois de algum tempo excluímos o arquivo original, ele aponta 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, por que os links físicos para diretórios são permitidos?
filesystems
directory
symlink
hard-link
user3539
fonte
fonte
..
apontar? Especialmente depois de remover o link físico para este diretório, no diretório apontado por..
? Precisa apontar para algum lugar...
não precisa existir fisicamente em nenhuma unidade. De qualquer forma, é tarefa do sistema operacional acompanhar o diretório de trabalho atual; portanto, deve ser relativamente simples manter também uma lista de inodes associados ao cwd de cada processo e referir-se a ele quando usar..
. Obviamente, isso significaria que links simbólicos precisariam ser criados com isso em mente, mas você já deve ter cuidado para não quebrar links simbólicos, e eu não acho que essa regra adicional os torne inúteis.Respostas:
Essa é apenas uma péssima idéia, pois não há como distinguir 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, o que tornaria
fsck
qualquer outro caminhante da árvore de arquivos propenso 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 coletados juntos por um inode. Você pode pensar no inode como o arquivo. Os inodes não possuem nomes de arquivos. É 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 link físico para um arquivo fará com que os dois nomes de arquivos apontem para o mesmo inode. Nota:Agora, você pode ver claramente que não existe um link físico. Um link físico é o mesmo que um nome comum. No exemplo acima,
test
outest2
, qual é o arquivo original e qual é o link físico? No final, você não pode realmente dizer (mesmo com registros de data e hora) porque os dois nomes apontam para o mesmo conteúdo, o mesmo inode:A
-i
bandeira parals
mostra os números de inode no início da linha. Observe comotest
etest2
tenha o mesmo número de inode, mastest3
tem um número diferente.Agora, se você pudesse fazer isso para diretórios, dois diretórios diferentes em pontos diferentes no sistema de arquivos poderiam apontar para a mesma coisa. De fato, um subdir poderia apontar de volta para seu avô, criando um loop.
Por que esse loop é uma preocupação? Porque quando você está percorrendo, não há como detectar que você está fazendo um loop (sem acompanhar os números dos inodes enquanto você percorre). Imagine que você está escrevendo o
du
comando, que precisa se repetir nos subdiretórios para descobrir sobre o uso do disco. Comodu
saberia quando atingisse um loop? É propenso a erros e muita contabilidadedu
deveria ser feita, apenas para executar esta tarefa simples.Os links simbólicos são um animal totalmente diferente, pois são um tipo especial de "arquivo" que muitas APIs de sistema de arquivos tendem a seguir automaticamente. Observe que um link simbólico pode apontar para um destino inexistente, porque aponta pelo 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
lidar com links simbólicos com facilidade e não com 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 ignoráveis!du
percebe que o link simbólico é um link simbólico e o ignora completamente!fonte
Allowing hard links to directories would break the directed acyclic graph structure of the filesystem
. Você pode explicar mais sobre o problema dos ciclos usando links físicos? Por que está tudo bem com links simbólicosCom exceção dos pontos de montagem, cada diretório tem um e apenas parent:
..
.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, coloque-o em uma pilha e comece a comparar '../.' com '../ ..', depois '../../.' com '../../ ..', etc. Depois de acessar a raiz, comece a exibir e imprimir os nomes da pilha. Esse algoritmo baseia-se no fato de que cada diretório possui um e apenas um pai.Se links físicos para diretórios forem permitidos, qual dos vários pais deve
..
apontar? Essa é uma razão convincente pela qual links físicos para diretórios não são permitidos.Links simbólicos para diretórios não causam esse problema. Se um programa quiser, ele pode executar um
lstat()
em cada parte do nome do caminho e detectar quando um link simbólico é encontrado. Opwd
algoritmo retornará o nome do caminho absoluto verdadeiro 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 é praticamente irrelevante. A existência desse link simbólico não cria um loop no gráfico.fonte
..
uma espécie de link físico virtual para o pai, não há razão técnica para que o destino do link possa ter apenas outro link para ele.pwd
precisaria usar um algoritmo diferente para resolver o caminho.Você pode usar o mount mount para simular diretórios de link físico
fonte
Eu gostaria de acrescentar mais alguns pontos sobre esta questão. Links físicos para diretórios são permitidos no linux, mas de maneira restrita.
Uma maneira de testar isso é quando listamos o conteúdo de um diretório e 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 possui o diretório "b" como filho.
Anote o inode do diretório "a". E quando fazemos um
ls -la
diretório "a", podemos ver isso "." O diretório também aponta para o mesmo inode.E aqui podemos descobrir que o diretório "a" possui três links físicos. Isso ocorre porque o inode 797358 possui três hardlinks no nome de "." dentro do diretório "a" e nomeie como ".." dentro do diretório "b" e um com o nome "a" em si.
Portanto, aqui podemos entender que os hardlinks existem apenas para os diretórios se conectarem aos diretórios pai e filho. E assim, um diretório sem filho terá apenas 2 hardlink, e o diretório "b" terá apenas dois hardlink.
Uma razão pela qual a vinculação forçada de diretórios foi impedida livremente seria evitar loops de referência infinitos, que confundirão programas que atravessam o sistema de arquivos.
Como o sistema de arquivos é organizado como árvore e como a árvore não pode ter referência cíclica, isso deveria ter sido evitado.
fonte
Nenhuma das seguintes é a verdadeira razão para não permitir links físicos para diretórios; cada problema é bastante fácil de resolver:
O verdadeiro motivo (como sugerido por @ Thorbjørn Ravn Andersen) ocorre quando você exclui um diretório que possui vários pais, do diretório apontado por
..
:O que
..
agora deve apontar?Se o diretório for excluído de seu pai, mas sua contagem de links ainda for maior do que
0
então, deve haver algo, em algum lugar ainda apontando para ele. Você não pode deixar de..
apontar para o nada; muitos programas dependem..
, então o sistema precisaria percorrer 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 forma, 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.
fonte
..
), atualize..
para apontar para um dos outros pais na lista.a/..
sempre significaria.
. É assim que os URLs funcionam, btw. É o navegador que está resolvendo '..' antes mesmo de atingir o servidor. E funciona muito bem.A criação de hardlinks nos diretórios seria irreversível. Suponha que tenhamos:
Eu o vinculo a ele
/dir2
.Então
/dir2
agora também contém todos esses arquivos e diretóriosE se eu mudar de idéia? Eu não posso simplesmente
rmdir /dir2
(porque não está vazio)E se eu excluir recursivamente em
/dir2
... será excluído/dir1
também!IMHO é uma razão amplamente suficiente para evitar isso!
Editar:
Os comentários sugerem a remoção do diretório, fazendo
rm
-o. Masrm
em um diretório não vazio falha, e esse comportamento deve permanecer, independentemente de o diretório estar vinculado ou não. Então você não pode simplesmenterm
desvincular. Seria necessário um novo argumento pararm
, apenas para dizer "se o inode do diretório tiver uma contagem de referência> 1, desvinculará apenas o diretório".O que, por sua vez, quebra outro princípio de menor surpresa: significa que a remoção de um hardlink de diretório que acabei de criar não é a mesma coisa que a remoção de um hardlink de arquivo normal ...
Vou reformular minha frase: sem desenvolvimento adicional, a criação de links físicos seria irreversível (já que nenhum comando atual poderia lidar com a remoção sem ser incoerente com o comportamento atual)
Se permitirmos que mais desenvolvimento lide com o caso, o número de armadilhas e o risco de perda de dados, se você não estiver ciente de como o sistema funciona, como implica esse desenvolvimento, o IMHO é uma razão suficiente para restringir a vinculação de diretórios.
fonte
rm
que existe por baixo (desvincular). Veja: unix.stackexchange.com/questions/151951/… Isso realmente não é um problema, assim como acontece com os arquivos com links físicos . Desvincular apenas remove a referência nomeada e diminui a contagem de links. O fato dermdir
não excluir diretórios não vazios é irrelevante - não faria issodir1
também. Os hardlinks não são cópias de dados, eles são o mesmo arquivo real; portanto, "excluir" o arquivo dir2 apagaria a listagem de diretórios do dir1. Você sempre precisaria desvincular.rm
em um diretório não desvincule-o se não estiver vazio. Veja Editar.Esta é uma boa explicação. Em relação a "Qual dos vários pais deve .. apontar?" uma solução seria que um processo mantivesse seu caminho wd completo, como inodes ou como uma string. inodes seria mais robusto, pois os nomes podem ser alterados. Pelo menos nos dias antigos, havia um inode no núcleo para cada arquivo aberto que era incrementado sempre que um arquivo era aberto, diminuído quando fechado. Quando chegasse a zero, o armazenamento apontado seria liberado. Quando o arquivo não era mais aberto por ninguém, ele (a cópia dentro do núcleo) seria abandonado. Isso manteria o caminho válido se algum outro processo movesse um diretório para outro diretório 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,
Os diretórios de link físico costumavam ser permitidos livremente no Bell Labs UNIX, pelo menos V6 e V7. Não conheça Berkeley ou posterior. Não é necessário sinalizador. Você poderia fazer loops? Sim, não faça isso. É muito claro o que você está fazendo se fizer um loop. Nether, você deve praticar um nó no pescoço enquanto aguarda a sua vez de saltar de um avião se você tiver a outra extremidade convenientemente pendurada em um gancho na cabeça.
O que eu esperava fazer com isso hoje era ligar o lhome a casa para que eu pudesse ter / home / administ disponível, independentemente de / home estar coberto com um automout sobre home, esse automount com um link simbólico chamado administ para / lhome / administ. Isso me permite ter uma conta administrativa que funcione independentemente do estado do meu sistema de arquivos inicial principal. Este é um experimento para linux, mas acho que aprendi ao mesmo tempo para o SunOS baseado em UCB que as montagens automáticas são feitas no nível de string ascii. É difícil ver como eles poderiam ser feitos de outra forma como uma camada sobre qualquer FS arbitrário.
Eu li em outro lugar isso. e .. também não existem arquivos no diretório Estou certo de que existem boas razões para tudo isso e que muito do que desfrutamos (como poder montar o NTFS) é possível por causa disso, mas parte da elegância do UNIX estava na implementação. São os benefícios, como generalidade e maleabilidade, que essa elegância proporcionou que lhe permitiu ser tão robusta e durar quatro décadas. À medida que perdemos as implementações elegantes, ele se tornará 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. ele é Por incrível que pareça, o quão aplicável é o entendimento de 30 anos no Linux ... na maioria das vezes!
fonte
.
e..
não são hardlinks no sistema de arquivos dos 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 link físico. Para sistemas de arquivos antigos, era possível (mas perigoso). Para fazer o que você está tentandomount --bind
, veja tambémmount --make…
e talvez contêineres.Pelo que entendi, o principal motivo é que é útil poder alterar os nomes de diretório sem atrapalhar os programas em execução que usam seu diretório de trabalho para referenciar outros arquivos. Suponha que você estivesse usando o Wine para executar
~/.newwineprefix/drive_c/Program Files/Firefox/Firefox.exe
e desejasse mover o prefixo inteiro para~/.wine
ele. Se por alguma razão estranha Firefox estava acessandodrive_c/windows
, referindo-se../../windows
, renomeando~/.newwineprefix
breaks implementações de..
que manter o controle do diretório pai como uma cadeia de texto em vez de um inode.Armazenar o inode de um diretório pai único deve ser mais simples do que tentar rastrear todos os caminhos como uma sequência de texto e uma série de inodes.
Outro motivo é que aplicativos com comportamento inadequado podem criar loops. Os aplicativos com comportamento devem poder verificar se o inode do diretório que está sendo movido é igual ao inode de qualquer diretório aninhado para o qual está sendo movido, assim como você não pode mover um diretório para si mesmo, mas isso pode não ser imposto. no nível do sistema de arquivos.
Ainda outro motivo pode ser o fato de que, se você pudesse vincular diretórios a diretórios, desejaria impedir a vinculação de um diretório que não pôde modificar.
find
possui 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 alternar um diretório real para um link simbólico enquantofind
estiver chamando outro comando. Ser capaz de vincular diretórios importantes forçaria um administrador a adicionar testes extrasfind
para evitar afetá-los. (Ok, você já não pode fazer isso para arquivos, portanto, este motivo é inválido.)Outro motivo é que o armazenamento do inode do diretório pai pode fornecer redundância extra em caso de corrupção ou dano no sistema de arquivos. Se você deseja
..
listar todos os diretórios-pai que possuem um link direto para este, para que um pai arbitrário diferente possa ser facilmente encontrado se o atual for desvinculado, você não apenas estará violando a ideia de que os links físicos são iguais, mas também como sistema de arquivos armazena e usa inodes. O fato de os programas tratarem os caminhos como uma série (exclusiva para cada link físico) de inodes de diretório evitaria isso, mas você não obteria a redundância em caso de danos no sistema de arquivos.fonte