Relier un fichier supprimé

33

Parfois, des personnes suppriment des fichiers qu’elles ne devraient pas, un processus de longue durée a toujours le fichier ouvert, et récupérer les données à la volée /proc/<pid>/fd/Nn’est tout simplement pas assez impressionnant. Ce serait assez génial si vous pouviez "annuler" la suppression en exécutant une option magique sur ln qui vous permettrait de vous reconnecter au numéro d'inode (récupéré via lsof).

Je ne trouve aucun outil Linux pour le faire, le moins avec Google rapide.

Qu'est-ce que tu as, serverfault?

EDIT1: La raison pour laquelle le fichier /proc/<pid>/fd/Nn'est pas assez impressionnant est parce que le processus qui a toujours le fichier ouvert est encore en train de l'écrire. Une suppression supprime la référence à l'inode de l'espace de noms du système 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é car il bloque les données brutes du système de fichiers. Le fichier récupéré est également fou incohérent. Le nombre de liens est égal à zéro et je ne peux pas y ajouter de liens. Je suis pire de cette façon puisque je peux simplement utiliser /proc/<pid>/fd/Npour accéder aux données sans corrompre mon fs.

mbac32768
la source

Réponses:

14

Ce serait assez génial si vous pouviez "annuler" la suppression en exécutant une option magique sur ln qui vous permettrait de vous reconnecter au numéro d'inode (récupéré via lsof).

Cette génialité a été introduite lndans la v8.0 (GNU / coreutils) avec l’ -L|--logicaloption qui permet lnde déréférencer une /proc/<pid>/fd/<handle>première. Donc un simple

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

est suffisant pour relier un fichier supprimé.

tnimeu
la source
7
Cela ne marche pas si le fichier est supprimé, il échouera.
Random832
1
Non, ça ne va pas. Je l'utilise régulièrement pour restaurer des fichiers supprimés mais toujours ouverts. Mais vous devez vous assurer que la nouvelle version se /path/to/deleted/filetrouve sur le même système de fichiers que le fichier était juste avant sa suppression, sinon, cela échouera. (Vous pouvez obtenir l'ancien chemin avec ls -l /proc/<pid>/fd/<handle>)
mardi
2
Ce type de fonctionnalité (voir cette question et cette réponse) a été expressément rejeté comme risque pour la sécurité ]; Je l'ai essayé (bien qu'avec un petit programme en C d'utiliser directement l'appel système correspondant) et cela n'a pas fonctionné.
Random832
7
Bien entendu, j'ai testé cela avant de publier ma solution et à ce moment-là, cela fonctionnait réellement pour moi. Ce que je ne savais pas, c'est que cela ne fonctionnait que sur les tmpfssystèmes de fichiers, mais pas sur, par exemple ext3. De plus, cette fonctionnalité a été complètement désactivée dans 2.6.39, voir la validation . Cette solution ne fonctionnera donc plus avec le noyau 2.6.39 ou plus récent et dans les versions antérieures, cela dépend du système de fichiers.
mardi
7
@nimeu ln -Lne fonctionne pas pour moi. J'ai un fichier supprimé et j'ai essayé de le relier au chemin d'origine. lnme donne un ln: failed to create hard link /my/path/file.pdf => /proc/19674/fd/16: No such file or directory. Mais je peux par exemple avec succèscat /proc/19674/fd/16
Eugene Beresovsky
13

On dirait que vous comprenez déjà beaucoup, alors je n’entrerai pas dans les détails. Il existe plusieurs méthodes pour trouver l'inode et vous pouvez généralement chat et rediriger 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 de lancer un fsck après. J'ai testé cela avec succès avec un inode toujours en cours d'écriture et cela fonctionne pour créer un nouveau lien dur vers un inode déréférencé.

Si le fichier n'est pas lié à un fichier non ouvert dans ext3, les données sont perdues. Je ne suis pas sûr que cela soit toujours vrai, mais l'essentiel de mon expérience de récupération de données se fait avec ext2. De la FAQ ext3:

Q: Comment puis-je récupérer (récupérer) des fichiers supprimés de ma partition ext3? En fait, vous ne pouvez pas! Voici ce qu'en dit l'un des développeurs, Andreas Dilger:

Afin de garantir que ext3 puisse reprendre en toute sécurité une dissociation après un crash, il supprime en fait les pointeurs de bloc dans l'inode, alors qu'ext2 marque simplement ces blocs comme inutilisés dans les bitmaps de bloc et marque l'inode comme "supprimé" et laisse le bloc. pointeurs seuls.

Votre seul espoir est de "grep" pour des parties de vos fichiers qui ont été supprimés et qui espèrent mieux.

Il y a aussi des informations pertinentes dans cette question:

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

Warner
la source
J'espère que le commentaire a été supprimé car ce n'était pas le cas.
Mdpc
1
Dans le cas d'un fichier supprimé mais toujours ouvert, je ne pense pas qu'il remettrait à zéro les pointeurs de l'inode. De plus, au lieu d'utiliser "ln" dans debugfs, j'utiliserais "undel" pour que les comptes de références d'inodes soient correctement mis à jour.
Mark Wagner
Je ne voulais pas faire allusion en tant que telle, embobo. Ce n'est pas le cas, j'ai testé les performances. J'ai clarifié ma langue.
Warner
Intelligent, mais corrompt mon système de fichiers. :)
mbac32768
C'est la seule solution pour le scénario tel que vous le décrivez. Manipuler un système de fichiers de bas niveau monté avec écriture active est susceptible de provoquer une corruption dans presque tous les scénarios.
Warner
8

la méthode de débogage que vous avez vue ne fonctionne pas vraiment et au mieux votre fichier sera automatiquement supprimé (à cause du journal) après le redémarrage et au pire vous pouvez détruire votre système de fichiers, ce qui entraînerait un "cycle de redémarrage de la mort". The Right Solution (TM) consiste à effectuer la suppression de suppression au niveau VFS (ce qui présente également l’avantage supplémentaire de fonctionner avec pratiquement tous les systèmes de fichiers Linux actuels). La voie d'appel système (flink) a été supprimée chaque fois qu'elle est apparue dans LKML. La meilleure façon de procéder consiste donc à utiliser un module + ioctl.

Fdlink ( https://github.com/pkt/fdlink.git pour une version testée avec le noyau d'ubuntu maverick) est un projet qui met en œuvre cette approche et a un code raisonnablement petit et propre . Avec celui-ci, après avoir inséré le module (sudo insmod flink_dev.ko), vous pouvez simplement faire "./flinkapp / proc // fd / X / my / link / path" et il fera exactement ce que vous voulez.

Vous pouvez également utiliser une version à port transféré de vfs-undelete.sourceforge.net qui fonctionne également (et peut également renvoyer automatiquement le lien au nom d'origine), mais le code de fdlink est plus simple et fonctionne tout aussi bien, c'est donc ma préférence.

Pktoss
la source
3

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

  • Ouvrir le fichier RO depuis un autre processus
  • Attendez que le processus original se termine
  • Copiez les données de votre FD ouvert dans un fichier

Pas idéal, évidemment, mais possible. L'autre option consiste à jouer avec debugfs (à l'aide de la linkcommande), mais c'est plutôt effrayant sur une machine de production!

Bill Weiss
la source
La commande link debugfs ne prend pas du tout en charge ce cas d'utilisation.
mbac32768
tldp.org/HOWTO/Ext2fs-Undeletion-11.html suggère de le faire. Je n'ai pas essayé, mais cela semble raisonnable.
Bill Weiss
linkn'a pas fonctionné lors de mes tests, mais l'a lnfait.
Warner
3

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

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

dans une session tmux / screen jusqu'à la fin du processus.

nickray
la source
2
La liaison aux fichiers d'origine, comme dans la réponse acceptée, devrait fonctionner.
Chris S
1
Il n'y a pas de réponse acceptée à cette question, de laquelle parlez-vous?
Hamman Samuel
Cela ne devrait-il pas nécessiter une redirection ( >) vers le fichier supprimé?
ncasas
1

Question interessante. Un interviewer m'a posé la même question lors d'un entretien d'embauche. Ce que je lui ai dit, c'est qu'il n'y avait pas de moyen facile de faire cela et qu'en général, cela ne valait pas le temps et les efforts nécessaires. Je lui ai demandé quelle était, à son avis, la solution à ce problème ...

  1. Utilisez lsof pour trouver le numéro d’inode sur le disque pour le processus car il apparaîtra même si le fichier a été supprimé ... la clé est qu’il est toujours ouvert.
  2. Extrayez les informations du système de fichiers en fonction de cela via un débogueur de système de fichiers.
mdpc
la source
Je peux très bien extraire les données de / proc / <pid> / fd / N mais ce n’est pas ce que j’essaie de faire.
mbac32768
1

Utilisez Sleuthkit icat.

sudo icat /dev/rdisk1s2 5484287 > accidentally_deleted_open_file
Isaac
la source
Cela fonctionne en contournant la fonctionnalité du système de fichiers du système d'exploitation et en analysant directement les octets du disque.
Flimm
0

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

1) trouvez le processus + fd en regardant directement dans / proc:

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

2) Ensuite, une technique similaire à celle de @ nickray, avec pv:

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

Vous devrez peut-être appuyer sur Ctrl-C lorsque ls /proc/{procnum}/fd/{fdnum}vous aurez terminé ( vous indiquerez que le fichier n'existe plus), mais si vous connaissez la taille exacte en octets, vous pouvez l'utiliser pv -Spour le faire quitter lorsque le nombre est atteint.

xénoïde
la source