Vinculando um arquivo excluído

31

Às vezes, as pessoas excluem arquivos que não devem, um processo de longa duração ainda tem o arquivo aberto e a recuperação dos dados por /proc/<pid>/fd/N não é incrível o suficiente. Bastante incrível seria se você pudesse "desfazer" a exclusão executando alguma opção mágica no ln que permitiria que você se vinculasse novamente ao número do inode (recuperado pelo lsof).

Não consigo encontrar nenhuma ferramenta do Linux para fazer isso, pelo menos com uma pesquisa superficial.

O que você tem, serverfault?

EDIT1: A razão pela qual o arquivo do /proc/<pid>/fd/N não é incrível é porque o processo que ainda tem o arquivo aberto ainda está sendo gravado. Uma exclusão remove a referência ao inode do namespace do sistema de arquivos. O que eu quero é uma maneira de recriar a referência.

EDIT2: 'debugfs ln' funciona, mas o risco é muito alto, já que os dados brutos do sistema de arquivos são exibidos. O arquivo recuperado também é 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.

    
por mbac32768 10.08.2010 / 16:32

8 respostas

14

Awesome enough would be if you could "undo" the delete by running some magic option to ln that would let you re-link to the inode number (recovered through lsof).

Esta grandiosidade foi apresentada a ln em v8.0 (GNU / coreutils) com a opção -L|--logical que faz com que ln cancele a referência a /proc/<pid>/fd/<handle> primeiro. Então um simples

ln -L /proc/<pid>/fd/<handle> /path/to/deleted/file

é o suficiente para vincular novamente um arquivo excluído.

    
por 22.02.2011 / 02:04
13

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 você pode geralmente cat e redirecionar STDOUT. Você pode usar debugfs . Execute este comando dentro de:

ln <$INODE> FILENAME

Certifique-se de ter backups do sistema de arquivos. Você provavelmente precisará executar um fsck posteriormente. Eu testei isso com sucesso com um inode ainda sendo gravado e ele trabalha para criar um novo hard link para um inode desreferenciado.

Se o arquivo estiver desvinculado com um arquivo não aberto no ext3, os dados serão perdidos. Não sei ao certo como isso é verdade, mas a maior parte da minha experiência de recuperação de dados é com o ext2. Do FAQ ext3:

Q: How can I recover (undelete) deleted files from my ext3 partition? Actually, you can't! This is what one of the developers, Andreas Dilger, said about it:

In order to ensure that ext3 can safely resume an unlink after a crash, it actually zeros out the block pointers in the inode, whereas ext2 just marks these blocks as unused in the block bitmaps and marks the inode as "deleted" and leaves the block pointers alone.

Your only hope is to "grep" for parts of your files that have been deleted and hope for the best.

Há também informações relevantes nesta pergunta:

Eu sobrei um grande arquivo com um em branco em um servidor linux. Posso recuperar o arquivo existente?

    
por 10.08.2010 / 18:32
7

a maneira como você viu debugfs não funciona de verdade e na melhor das hipóteses o seu arquivo será apagado automaticamente (devido ao diário) após a reinicialização e na pior das hipóteses você pode destruir o seu sistema de arquivos resultando em "reinicializar o ciclo da morte". A solução correta (TM) é executar a undelete no nível do VFS (que também tem o benefício adicional de trabalhar com praticamente todos os sistemas de arquivos atuais do Linux). A chamada do sistema (flink) foi cancelada toda vez que apareceu em LKML, então a melhor maneira é através de um módulo + ioctl.

Um projeto que implementa essa abordagem e tem código razoavelmente pequeno e limpo é o fdlink ( link para uma versão testada com o ubuntu o núcleo do maverick). Com ele, depois de inserir o módulo (sudo insmod flink_dev.ko) você pode fazer "./flinkapp / proc // fd / X / meu / link / caminho" e ele fará exatamente o que você quer.

Você também pode usar uma versão portada para a frente do vfs-undelete.sourceforge.net que também funciona (e também pode se revincular automaticamente ao nome original), mas o código do fdlink é mais simples e funciona tão bem, então é minha preferência.

    
por 09.04.2011 / 23:58
3

Eu não sei como fazer exatamente o que você quer, mas o que eu faria é:

  • Abra o arquivo RO de outro processo
  • Aguarde o processo original sair
  • Copie os dados do seu FD aberto para um arquivo

Não ideal, obviamente, mas possível. A outra opção é brincar com o debugfs (usando o comando link ), mas isso é meio assustador em uma máquina de produção!

    
por 10.08.2010 / 17:44
3

Correu para o mesmo problema hoje. O melhor que eu consegui fazer é correr

% tail -n +0 -f /proc/<pid>/fd/<fd> /path/to/deleted_file

em uma sessão do tmux / screen até que o processo termine.

    
por 06.12.2012 / 17:08
1

Pergunta interessante. Um entrevistador fez a mesma pergunta para mim 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 a pena o tempo e o esforço envolvidos. Eu perguntei a ele o que ele achava que a solução para esse problema era ....

  1. Use lsof para encontrar o número do inode no disco para o processo, pois ele ainda aparecerá mesmo que o arquivo tenha sido excluído ... a chave é que ele ainda está aberto.
  2. Extraia as informações do sistema de arquivos com base nisso por meio de um depurador de sistema de arquivos.
por 10.08.2010 / 18:35
1

Use o Sleuthkit icat.

sudo icat /dev/rdisk1s2 5484287 > accidentally_deleted_open_file
    
por 19.02.2012 / 19:03
0

A solução rápida que funcionou para mim, sem intimidar ferramentas:

1) encontre o processo + fd olhando diretamente em / proc:

ls -al /proc/*/fd/* 2>/dev/null | grep {filename}

2) Em seguida, uma técnica semelhante ao @ nickray, com pv lançado:

tail -c +0 -f /proc/{procnum}/fd/{fdnum} | pv -s {expectedsize} > {recovery_filename}

Você pode precisar Ctrl-C quando terminar ( ls /proc/{procnum}/fd/{fdnum} dirá que o arquivo não existe mais)), mas se você souber o tamanho exato em bytes, você pode usar pv -S para fazê-lo sair quando o arquivo a contagem é alcançada.

    
por 28.07.2017 / 09:10