Um diretório é removido quando seu número de links físicos se torna 0?

10

Um diretório é removido quando seu número de hard links se torna 0?

Um diretório sempre tem pelo menos 2 como o número de links físicos, por causa de . . Quando rm -r um diretório, diminui o número de hard link de 2 para 0 por 2 ao invés de 1?

O número de links de um diretório pode ser 1?

Obrigado.

    
por Tim 07.05.2015 / 01:05

2 respostas

9

Em primeiro lugar, nem todos os sistemas de arquivos usam . e .. como links físicos. isso está documentado no manual de busca do gnu. Eu vou ignorar esses sistemas de arquivos para o resto da minha resposta, porque eles não foram projetados para unix e apenas complicam as coisas sem adicionar clareza. Também vou ignorar o diretório raiz e os pontos de montagem pelo mesmo motivo.

o número de links para um diretório nunca é menor que dois devido a . e .. . O número de subdiretórios é igual ao número de links menos dois. Por causa disso, você não pode vincular ou desvincular um diretório, portanto, rm -r irá stat um arquivo antes de excluir e usar rmdir em vez de unlink nos diretórios. As duas chamadas de sistema usam caminhos de código completamente diferentes no kernel.

    
por 07.05.2015 / 01:25
11

Qualquer arquivo em um sistema de arquivos UNIX convencionalmente projetado cuja referência de contagem (por exemplo, a soma da contagem de hardlink e o número de identificadores de arquivo aberto *) atinge 0 é removido. No entanto, nos sistemas UNIX modernos, a chamada de sistema rmdir remove um diretório vazio em uma única operação em vez de remover . e .. um por um.

Em sistemas UNIX históricos, no entanto, essa chamada de sistema não existia. Em vez disso, o comando rmdir era um programa setuid ( código-fonte pode ser encontrado aqui ) que verificou se um diretório estava vazio (exceto as entradas especiais) e, em seguida, removeu .. e . , nessa ordem, e depois removeu o próprio diretório, todos com a chamada de sistema unlink que somente a raiz tinha permissão para usar nos diretórios (daí porque o comando era setuid). Então, nesses sistemas, a contagem de links de um diretório seria momentaneamente 1 depois que . fosse removido, mas antes que o diretório fosse removido do diretório pai, então seria 0.

O comando rm , aliás, impediu que até mesmo root removesse diretórios. E rm -r chamaria o comando rmdir para remover diretórios depois de esvaziar seu conteúdo.

Nesses sistemas históricos, use indevidamente a chamada unlink de um programa em execução como raiz, executando uma condição de corrida com rmdir ou mv ou criando um arquivo em um processo cujo diretório atual foi excluído (moderno impedir isso), pode resultar em arquivos pendentes ou diretórios que têm uma contagem de hardlink acima de 0, mas não existem na árvore de diretórios. Essa condição foi detectada por dcheck e ainda é uma das verificações em fsck , já que permanece fisicamente possível na maioria dos sistemas de arquivos.

Os sistemas de arquivos não são, por acaso, necessários para implementar diretórios (incluindo . e .. ) como arquivos normais que possuem hardlinks. Nesses sistemas de arquivos, a contagem de hardlink de um diretório será sempre relatada como 0 (mas, é claro, sua existência no diretório pai é qualificada para uma "contagem de referência" de 1).

O comportamento de um diretório removido (por exemplo, quando examinado por um processo que já o tenha aberto ou o possui como seu diretório atual) e o significado exato da "contagem de links" de um diretório não são especificados. No Mac OS X, por exemplo, relatará uma contagem de hardlink de 2 , mesmo que não tenha hardlinks reais. Mesmo que . e .. não apareçam na listagem, o diretório pode ser aberto e stat pode ser chamado com o nome . ou .. . No Linux, a contagem de links é 0, mas . e .. também funcionam.

O Mac OS X também informa o número de todos os arquivos em um diretório como a contagem de links, em vez de apenas o número de subdiretórios. Mas é 2 mesmo quando . e .. se foram.

* Isso inclui descritores abertos normais, seções mapeadas na memória (incluindo, por exemplo, executar binários e bibliotecas compartilhadas) e processar diretórios atuais.

    
por 07.05.2015 / 05:59

Tags