Para onde vão os identificadores de arquivos abertos quando morrem?

15

O que acontece com os arquivos que são excluídos enquanto eles têm um identificador de arquivo aberto para eles?

Eu me pergunto isso desde que descobri que poderia excluir um arquivo de vídeo enquanto ele estava sendo reproduzido no MPlayer e ele ainda seria reproduzido até o fim. De onde ele está puxando os dados? Ainda está vindo do disco rígido? Ele foi copiado para a RAM depois que eu excluí o arquivo?

Se ainda estiver no disco rígido, o que acontecerá se eu encher o sistema de arquivos enquanto o programa estiver executando a leitura do espaço essencialmente não alocado? Se estiver armazenado em buffer na RAM, o que acontece se eu liberar os buffers?

O que acontece se o arquivo estava em um compartilhamento NFS - ele está armazenado no servidor? (Isso não é um risco à segurança - DoS por toneladas de identificadores abertos de arquivos remotos?)

Fazer um, lsof -n |grep '(deleted)'às vezes, produz resultados interessantes; se estou atualizando pacotes que trocam arquivos de biblioteca compartilhada, a execução de programas que estavam usando essas bibliotecas ainda poderá usá-los como se nada tivesse mudado.

Pergunta bônus: Existe alguma maneira de recuperar os dados dos mortos nessa situação?

anfetamaquina
fonte

Respostas:

13

Os inodes ainda persistem no disco, embora não existam mais links físicos para os inodes. Eles serão excluídos quando o descritor de arquivo for fechado. Até então, o arquivo pode ser modificado normalmente, impedindo operações que exijam um nome de arquivo / link físico.

debugfs e ferramentas semelhantes podem ser usadas para recuperar o conteúdo dos inodes.

Ignacio Vazquez-Abrams
fonte
10
Isso está correto, no entanto, se o arquivo ainda estiver aberto, você pode recuperá-lo indo para / proc / <PID> / fd, em que PID é o pid de um programa que ainda possui o arquivo aberto. Esse diretório contém todos os descritores de arquivos abertos do programa e você pode acessá-los como arquivos normais, para criar um link físico para 'restaurar' o arquivo.
22411 Patrick
Observe que /procé específico do Linux (como está debugfs).
Ignacio Vazquez-Abrams
1
O Solaris também possui um / proc e a técnica funciona bem. Não sei sobre BSD.
Patrick
2
Eu só tenho que acrescentar que isso é incrível.
n0pe
1
@ Patrick: Você não pode criar um link físico para 'restaurar' um arquivo /proc. Os links físicos funcionam apenas no mesmo sistema de arquivos, não entre sistemas de arquivos e, como /procé um sistema de arquivos não gravável separado, você não pode criar links físicos nele. Você pode copiar o arquivo /procembora.
Camh
5

O kernel faz referência, contando com referências ao inode. Veja minha resposta para O que acontece quando eu fecho () um descritor de arquivo? .

A exclusão de arquivos abertos provavelmente não é um mecanismo DOS mais eficaz do que apenas a abertura de arquivos. Os ulimitarquivos abertos fornecem alguma proteção contra essa tentativa do DOS. Aplica-se a todos os arquivos abertos, excluídos ou não.

BillThor
fonte
5

Um arquivo é apagado apenas no sistema de arquivos uma vez que todas as referências a ele desaparecem. Os nomes e os identificadores abertos contam como referências. Enquanto o arquivo estiver aberto em um programa, ele não será excluído, embora a maioria dos sistemas não permita que você recrie um nome para ele.

Os dados ainda estão na unidade, mas o arquivo está marcado como tendo uma contagem de links de 0. Se o sistema travar, o fsck na próxima reinicialização saberá que deve excluir os dados. Isso não leva a uma negação de serviço mais do que um arquivo não excluído.

Você não pode recriar um link para o arquivo em um sistema Linux padrão, tanto quanto eu sei (além de ignorar o driver do sistema de arquivos com debugfsmétodos semelhantes), mas pode recuperar o conteúdo facilmente: cat /proc/12345/fd/42onde 12345 é o ID do processo que possui o arquivo aberto e 42 é o número do descritor de arquivo.

No NFS, quando você exclui um arquivo que ainda está aberto em algum cliente, o servidor NFS renomeia o arquivo no servidor, mas não o exclui até que todos os clientes tenham liberado o arquivo. Na minha experiência, o novo nome é .nfs…, embora eu não saiba se o nome é o mesmo em todas as implementações do NFS.

Gilles 'SO- parar de ser mau'
fonte