Às vezes, as pessoas excluem arquivos que não deveriam, um processo de longa execução ainda tem o arquivo aberto e a recuperação dos dados por catting /proc/<pid>/fd/N
não é impressionante o suficiente. O mais impressionante seria se você pudesse "desfazer" a exclusão executando uma opção mágica em ln que permitiria que você se vinculasse novamente ao número do inode (recuperado através de lsof).
Não consigo encontrar nenhuma ferramenta Linux para fazer isso, pelo menos com o Google superficial.
O que você tem, falha no servidor?
EDIT1: A razão pela qual capturar o arquivo /proc/<pid>/fd/N
não é impressionante o suficiente é porque o processo que ainda tem o arquivo aberto ainda está gravando nele. Uma exclusão remove a referência ao inode do espaço para nome do sistema de arquivos. O que eu quero é uma maneira de recriar a referência.
EDIT2: 'debugfs ln' funciona, mas o risco é muito alto, pois gera dados brutos do sistema de arquivos. O arquivo recuperado também é louco inconsistente. A contagem de links é zero e não consigo adicionar links. Estou pior desse jeito, já que posso apenas /proc/<pid>/fd/N
acessar os dados sem corromper meu fs.
/path/to/deleted/file
está no mesmo sistema de arquivos que o arquivo estava pouco antes de ser excluído; caso contrário, isso realmente irá falhar. (Você pode obter o caminho antigo comls -l /proc/<pid>/fd/<handle>
)tmpfs
sistemas de arquivos, mas não em, por exemploext3
. Além disso, esse recurso foi completamente desativado na 2.6.39, consulte o commit . Portanto, esta solução não funcionará mais com o kernel 2.6.39 ou mais recente e, nas versões anteriores, depende do sistema de arquivos.ln -L
não funciona para mim. Eu tenho um arquivo excluído e tentei vinculá-lo novamente ao caminho original.ln
me dá umln: failed to create hard link /my/path/file.pdf => /proc/19674/fd/16: No such file or directory
. Mas eu posso, por exemplo, com sucessocat /proc/19674/fd/16
Parece que você já entende muito, então não vou entrar em detalhes em excesso. Existem vários métodos para encontrar o inode e, geralmente, você pode gato e redirecionar STDOUT. Você pode usar
debugfs
. Execute este comando dentro de:ln <$INODE> FILENAME
Verifique se você possui backups do sistema de arquivos. Você provavelmente precisará executar um fsck depois. Eu testei isso com sucesso com um inode ainda sendo gravado e funciona para criar um novo link físico para um inode não referenciado.
Se o arquivo for desvinculado de um arquivo fechado no ext3, os dados serão perdidos. Não tenho certeza de quão consistentemente isso é verdade, mas a maior parte da minha experiência de recuperação de dados está no ext2. Na FAQ do ext3:
Há também informações relevantes nesta pergunta:
Eu substituí um arquivo grande por um em branco em um servidor Linux. Posso recuperar o arquivo existente?
fonte
a maneira como você viu os debugfs realmente não funciona e, na melhor das hipóteses, seu arquivo será excluído automaticamente (devido ao diário) após a reinicialização e, na pior das hipóteses, você pode lixeira no seu sistema de arquivos resultante de "reboot cycle of death". A solução certa (TM) é executar a exclusão no nível do VFS (que também possui o benefício adicional de trabalhar com praticamente todos os sistemas de arquivos Linux atuais). A maneira de chamada do sistema (flink) foi abatida toda vez que apareceu no LKML, portanto a melhor maneira é através de um módulo + ioctl.
Um projeto que implementa essa abordagem e possui um código razoavelmente pequeno e limpo é o fdlink ( https://github.com/pkt/fdlink.git para uma versão testada com o kernel do ubuntu maverick). Com ele, depois de inserir o módulo (sudo insmod flink_dev.ko), você pode simplesmente fazer "./flinkapp / proc // fd / X / meu / link / caminho" e ele fará exatamente o que você deseja.
Você também pode usar uma versão de porta direta do vfs-undelete.sourceforge.net que também funciona (e também pode vincular automaticamente novamente ao nome original), mas o código do fdlink é mais simples e funciona da mesma forma, portanto, é minha preferência.
fonte
Não sei como fazer exatamente o que você deseja, mas o que eu faria é:
Não é o ideal, obviamente, mas é possível. A outra opção é brincar com os debugfs (usando o
link
comando), mas isso é meio assustador em uma máquina de produção!fonte
link
não funcionou nos meus testes, masln
funcionou.Encontrei o mesmo problema hoje. O melhor que eu poderia pensar é correr
em uma sessão tmux / screen até o processo terminar.
fonte
>
) para o arquivo excluído?Pergunta interessante. Um entrevistador me fez a mesma pergunta em uma entrevista de emprego. O que eu disse a ele foi que não havia uma maneira fácil de fazer isso e, em geral, não valia o tempo e o esforço envolvidos. Perguntei a ele o que ele achava que a solução para esse problema era ....
fonte
Use Sleuthkit icat.
fonte
A solução rápida que funcionou para mim, sem ferramentas intimidantes:
1) encontre o processo + fd olhando diretamente em / proc:
2) Em seguida, uma técnica semelhante à @ nickray's,
pv
lançada em:Pode ser necessário pressionar Ctrl-C quando terminar (
ls /proc/{procnum}/fd/{fdnum}
informará que o arquivo não existe mais), mas se você souber o tamanho exato em bytes, poderá usápv -S
-lo para sair quando a contagem for atingida.fonte