web-dev-qa-db-fra.com

Requier un fichier supprimé

Parfois, les gens suppriment des fichiers qu'ils ne devraient pas, un processus à long terme contient toujours le fichier ouvert et la récupération des données par la chatting /proc/<pid>/fd/N ne suffit pas assez génial. Si vous pouviez "annuler" la suppression en exécutant une option magique à une option magique qui vous permettrait de re-relier au numéro d'inode (récupéré via LSOF).

Je ne trouve pas d'outils Linux pour le faire, le moins avec des googles cassés.

Qu'est-ce que tu as, serverfault?

EDIT1: La raison en chat le fichier de /proc/<pid>/fd/N n'est pas assez génial, c'est parce que le processus qui a toujours le fichier ouvert l'écrit toujours. Un Supprimer supprime la référence à l'inode à partir de l'espace de noms de fichier de fichiers. Ce que je veux, c'est un moyen de recréer la référence.

EDIT2: 'Debugfs ln' fonctionne, mais le risque est trop élevé puisqu'il frobonne les données de système de fichiers brutes. Le fichier récupéré est également fou incompatible. Le nombre de liens est zéro et je ne peux pas ajouter de liens à ce sujet. Je suis pire de cette façon depuis que je peux simplement utiliser /proc/<pid>/fd/N Pour accéder aux données sans corrompre mon FS.

34
mbac32768

Si vous pouviez "annuler" la suppression en exécutant une option magique à une option magique qui vous permettrait de re-relier au numéro d'inode (récupéré via LSOF).

Cette génialité a été introduite sur ln in v8. (GNU/Coreutils) avec le -L|--logical option qui cause ln à la déréférence a /proc/<pid>/fd/<handle> premier. Donc un simple

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

est suffisant pour relier un fichier supprimé.

17
tnimeu

On dirait que vous comprenez déjà beaucoup, donc je n'irais pas en excès de détail. Il y a plusieurs méthodes pour trouver l'inode et vous pouvez généralement être chat et redirect stdout. Vous pouvez utiliser debugfs . Exécutez cette commande dans:

ln <$INODE> FILENAME

Assurez-vous que vous avez des sauvegardes du système de fichiers. Vous aurez probablement besoin d'exécuter une FSCK après. J'ai testé cela avec succès avec une inode toujours écrite et fonctionne pour créer un nouveau lien dur vers une inode déréférencée.

Si le fichier est non mélangé avec un fichier non open dans EXT3, les données sont perdues. Je ne suis pas sûr à quel point cela est toujours vrai, mais la majeure partie de mon expérience de récupération de données est avec EXT2. De la FAQ ext3:

Q: Comment puis-je récupérer (Undelete) supprimé des fichiers supprimés de ma partition ext3? En fait, vous ne pouvez pas! C'est ce que l'un des développeurs, Andreas Dilger, a déclaré à ce sujet:

Afin de s'assurer que EXT3 peut reprendre en toute sécurité une dissolution en toute sécurité après un crash, il est en fait zéros sur les pointeurs de bloc dans l'inode, tandis que EXT2 marque simplement ces blocs comme inutilisé dans le bloc bitmaps et marque l'inode comme "supprimé" et laisse le bloc Pointeurs seuls.

Votre seul espoir est de "GREP" pour certaines parties de vos fichiers supprimés et espèrent le meilleur.

Il y a aussi des informations pertinentes dans cette question:

J'ai écrasé un grand fichier avec un vierge sur un serveur Linux. Puis-je récupérer le fichier existant?

13
Warner

la voie de débroge que vous avez vue ne fonctionne pas vraiment et au mieux que votre fichier sera supprimé automatiquement (en raison de la journal) après le redémarrage et au pire, vous pouvez détruire votre système de fichiers résultant de "Redémarrer le cycle de la mort". La solution de bonne solution (TM) consiste à effectuer la non -lete au niveau VFS (qui a également l'avantage supplémentaire de travailler avec pratiquement tous les systèmes de fichiers Linux actuels). Le moyen d'appel système (FLINK) a été abattu à chaque fois qu'il est apparu dans LKML, de sorte que le meilleur moyen est de passer par un module + ioctl.

Un projet qui implémente cette approche et a un code raisonnablement petit et propre est FDLink ( https://github.com/pkt/fdlink.git pour une version testée avec le noyau de Ubuntu Maverick). Avec celui-ci, après avoir inséré le module (sudo insmod flink_dev.ko), vous pouvez simplement faire "/flinkapp/proc // fd/x/mon/lien/chemin "et cela fera exactement ce que vous voulez.

Vous pouvez également utiliser une version transmise de vfs-undelete.sourceforge.net qui fonctionne également (et peut également relier automatiquement au nom d'origine), mais le code FDLink est plus simple et cela fonctionne aussi bien, donc c'est ma préférence.

8
pktoss

Couru dans le même problème aujourd'hui. Le meilleur que je pouvais trouver est de courir

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

dans une session TMux/écran jusqu'à la fin du processus.

3
nickray

Je ne sais pas comment faire exactement ce que vous voulez, mais ce que je ferais, c'est:

  • Ouvrez le fichier RO d'un autre processus
  • Attendez que le processus d'origine quitte
  • Copiez les données de votre FD Open FD sur un fichier

Non idéal, évidemment, mais possible. L'autre option est de jouer avec des débugfs (à l'aide de la commande link), mais c'est un peu effrayant sur une machine de production!

3
Bill Weiss

Utilisez Sleuthkit icat.

Sudo icat /dev/rdisk1s2 5484287 > accidentally_deleted_open_file
1
Isaac

Question interessante. Un intervieweur m'a posé la même question dans un entretien d'embauche. Ce que je lui ai dit, c'est qu'il n'était pas un moyen facile de le faire et en général ne valait pas la peine d'être impliqué. Je lui ai demandé ce qu'il pensait que la solution à ce sujet était ....

  1. Utilisez LSOF pour trouver le numéro de l'inode sur le disque pour le processus car il apparaîtra même si le fichier a été supprimé ... La clé est qu'elle est toujours ouverte.
  2. Extraire les informations du système de fichiers en fonction de cela via un débogueur de système de fichiers.
1
mdpc

La solution rapide qui a fonctionné pour moi, sans outils intimidant:

1) Trouvez le processus + FD en regardant directement dans/proc:

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

2) Ensuite, une technique similaire à @ Nickray's, avec pv jeté dans:

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

Vous devrez peut-être avoir besoin de Ctrl-C lorsque vous avez terminé (ls /proc/{procnum}/fd/{fdnum} vous dira que le fichier n'existe plus)), mais si vous connaissez la taille exacte en octets, vous pouvez utiliser pv -S Pour que cela soit sortie lorsque le comte est atteint.

0
xenoid