
Às vezes, as pessoas excluem arquivos que não deveriam, um processo demorado ainda mantém o arquivo aberto e recuperar os dados por catting /proc/<pid>/fd/N
simplesmente não é incrível o suficiente. Seria incrível se você pudesse "desfazer" a exclusão executando alguma opção mágica para ln que permitiria vincular novamente ao número do inode (recuperado por meio de lsof).
Não consigo encontrar nenhuma ferramenta Linux para fazer isso, pelo menos pesquisando superficialmente no Google.
O que você tem, falha no servidor?
EDIT1: O motivo pelo qual capturar o arquivo /proc/<pid>/fd/N
não é incrível o suficiente é porque o processo que ainda mantém o arquivo aberto ainda está gravando nele. Uma exclusão remove a referência ao inode do namespace do sistema de arquivos. O que eu quero é uma forma de recriar a referência.
EDIT2: 'debugfs ln' funciona, mas o risco é muito alto, pois coleta dados brutos do sistema de arquivos. O arquivo recuperado também é totalmente inconsistente. A contagem de links é zero e não consigo adicionar links a ela. Estou pior assim, pois posso usar apenas /proc/<pid>/fd/N
para acessar os dados sem corromper meu fs.
Responder1
Seria incrível se você pudesse "desfazer" a exclusão executando alguma opção mágica para ln que permitiria vincular novamente ao número do inode (recuperado por meio de lsof).
Essa grandiosidade foi apresentada ln
emv8.0(GNU/coreutils) com a -L|--logical
opção que faz com ln
que a referência seja desreferenciada /proc/<pid>/fd/<handle>
primeiro. Então, um simples
ln -L /proc/<pid>/fd/<handle> /path/to/deleted/file
é suficiente para vincular novamente um arquivo excluído.
Responder2
Parece que você já entende bastante, então não vou entrar em detalhes excessivos. Existem vários métodos para encontrar o inode e geralmente você pode cat e redirecionar STDOUT. Você pode usardebugfs
. Execute este comando em:
ln <$INODE> FILENAME
Certifique-se de ter 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 desreferenciado.
Se o arquivo for desvinculado de um arquivo não aberto 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 em recuperação de dados é com ext2. Das perguntas frequentes do ext3:
P: Como posso recuperar (recuperar) arquivos excluídos da minha partição ext3? Na verdade, você não pode! Isto é o que um dos desenvolvedores, Andreas Dilger, disse sobre isso:
Para garantir que o ext3 possa retomar com segurança uma desvinculação após uma falha, ele na verdade zera os ponteiros de bloco no inode, enquanto o ext2 apenas marca esses blocos como não utilizados nos bitmaps do bloco e marca o inode como "excluído" e deixa o bloco ponteiros sozinhos.
Sua única esperança é "grep" para partes de seus arquivos que foram excluídas e torcer pelo melhor.
Também há informações relevantes nesta questão:
Responder3
o modo debugfs como você viu 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 destruir seu sistema de arquivos, resultando em um "ciclo de reinicialização da morte". A Solução Certa (TM) é realizar o undelete no nível VFS (que também tem o benefício adicional de trabalhar com praticamente todos os sistemas de arquivos Linux atuais). A forma de chamada do sistema (flink) foi derrubada toda vez que aparecia no LKML, então a melhor forma é através de um módulo + ioctl.
Um projeto que implementa essa abordagem e possui código razoavelmente pequeno e limpo é o fdlink (https://github.com/pkt/fdlink.gitpara 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 /my/link/path" e ele fará exatamente o que você deseja.
Você também pode usar uma versão portada de vfs-undelete.sourceforge.net que também funciona (e também pode vincular automaticamente ao nome original), mas o código do fdlink é mais simples e funciona tão bem, então é minha preferência.
Responder4
Não sei como fazer exatamente o que você quer, mas o que eu faria é:
- Abra o arquivo RO de outro processo
- Aguarde a saída do processo original
- Copie os dados do seu FD aberto para um arquivo
Não é o ideal, obviamente, mas é possível. A outra opção é brincar com debugfs (usando o link
comando), mas isso é meio assustador em uma máquina de produção!