Por que links simbólicos em / proc / $ PID / fd / atuam como hard links?

3

Quando o destino de um link simbólico é excluído, ele aponta para nada e não há como chegar ao conteúdo do destino excluído.

Os arquivos em /proc/$PID/fd/ são exibidos como links simbólicos, mas permitem que você acesse o conteúdo do destino excluído, conforme explicado aqui: Recuperar arquivos apagados do Linux com lsof .

Como isso funciona? Por que é exibido como um link simbólico se não agir como um? É a implementação do link simbólico do sistema de arquivos proc que mantém uma referência ao inode do arquivo?

    
por user300811 12.08.2016 / 13:30

1 resposta

1

Se o alvo for excluído, uma entidade em /proc/$PID/fd/ aparece como um link simbólico quebrado quando você usa ls(1) ou file(1) , mas na verdade age de forma diferente quando é aberto com open(2) .

No meu Debian 9 eu usei strace(1) para ver o que acontece quando tento ler um symlink. O comando é sudo strace cat "$symlink" . A linha relevante do stderr é

  • ou OK

    open("$symlink", O_RDONLY)                   = 3
    
  • ou ENOENT

    open("$symlink", O_RDONLY)                   = -1 ENOENT (No such file or directory)
    

(nota: não estou dizendo que todos esses são resultados possíveis de open(2) em geral).

Os resultados:

               | regular symlink | /proc/$PID/fd/$N |
---------------+-----------------+------------------+
exists, valid  |       OK        |        OK        |
exists, broken |     ENOENT      |        OK        | <- the difference
doesn't exist  |     ENOENT      |      ENOENT      |
---------------+-----------------+------------------+

Eu também aprendi que quando eu executo file "$symlink" , ele chama lstat(2) , readlink(2) e stat(2) . Essas são chamadas de sistema que se baseiam em caminhos, não em descritores de arquivos. Se o symlink existir (válido ou quebrado), open(2) nunca é chamado para abri-lo ou seu destino. ENOENT de stat(2) indica que o link está quebrado.

Minha conclusão é: "link quebrado" é uma propriedade derivada da saída de algumas chamadas do sistema; mas quando você abre um link de /proc/$PID/fd/ , open(2) apenas sabe o que fazer com ele e não se importa com o que outras ferramentas produziriam.

Observe que todo o /proc falsifica apenas um sistema de arquivos "normal". Algumas peculiaridades:

  • Os arquivos podem ter conteúdo dinâmico, mas não estão sendo modificados com as chamadas do sistema (tente inotifywait ).
  • Os objetos podem (dis) aparecer, mas não estão sendo criados nem excluídos com as chamadas do sistema (novamente inotifywait ).
  • Em algum sentido, os objetos podem não existir até você interagir com eles. Execute bash e aguarde alguns minutos. Invoque ls -l /proc/$$/fd para ver seus descritores de arquivos. Provavelmente ctimes mostrará "neste exato momento". No entanto, se você repetir o comando a cada poucos segundos, perceberá que os ctimes nunca mudam. (Curiosidades: no começo eu pensei que poderia responder a essa pergunta Determine por quanto tempo um arquivo foi aberto com stat e links simbólicos em /proc/$PID/fd/ , mas eu estava errado; agora você sabe o porquê).
Não é de admirar que esses links simbólicos que você pergunta não se comportem como links simbólicos regulares em algumas circunstâncias. O /proc inteiro foi projetado para se comportar de maneira um pouco diferente. Eu suponho open(2) foi deliberadamente dada a capacidade de tirar proveito disso.

    
por 05.06.2018 / 09:56