Frage Erneutes Verknüpfen einer gelöschten Datei


Manchmal löschen Personen Dateien, die sie nicht sollten, ein lang andauernder Prozess hat immer noch die Datei geöffnet und die Daten werden durch Catting wiederhergestellt /proc/<pid>/fd/N ist einfach nicht großartig genug. Genial genug wäre, wenn Sie das Löschen "rückgängig machen" könnten, indem Sie eine magische Option auf ln ausführen, die es Ihnen erlauben würde, die Inode-Nummer erneut zu verknüpfen (wiederhergestellt durch lsof).

Ich kann keine Linux-Tools dafür finden, zumindest nicht mit oberflächlichem Googeln.

Was hast du, Serverfehler?

EDIT1: Der Grund, warum die Datei von Catting stammt /proc/<pid>/fd/N ist nicht genial genug, weil der Prozess, der immer noch die Datei geöffnet hat, immer noch darauf schreibt. Ein Löschvorgang entfernt den Verweis auf den Inode aus dem Namespace des Dateisystems. Was ich möchte, ist eine Möglichkeit, die Referenz neu zu erstellen.

EDIT2: 'debugfs ln' funktioniert, aber das Risiko ist zu hoch, da es rohe Dateisystemdaten durchsucht. Die wiederhergestellte Datei ist auch verrückt inkonsistent. Die Linkanzahl ist null und ich kann keine Links hinzufügen. Mir geht es schlechter, weil ich es einfach benutzen kann /proc/<pid>/fd/N um auf die Daten zuzugreifen, ohne meine fs zu korrumpieren.


31
2017-08-10 14:32


Ursprung




Antworten:


Genial genug wäre, wenn Sie das Löschen "rückgängig machen" könnten, indem Sie eine magische Option auf ln ausführen, die es Ihnen erlauben würde, die Inode-Nummer erneut zu verknüpfen (wiederhergestellt durch lsof).

Diese Großartigkeit wurde eingeführt ln im v8.0 (GNU / coreutils) mit dem -L|--logical Option, die verursacht ln eine dereferenzieren a /proc/<pid>/fd/<handle> zuerst. Also ein einfaches

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

reicht aus, um eine gelöschte Datei neu zu verknüpfen.


14
2018-02-22 01:04



Dies funktioniert nicht. Wenn die Datei gelöscht wird, schlägt sie fehl. - Random832
Nein, wird es nicht. Ich verwende dies regelmäßig, um gelöschte, aber dennoch geöffnete Dateien wiederherzustellen. Aber Sie müssen sicherstellen, dass das neue /path/to/deleted/file ist auf gleiches Dateisystem Da die Datei gerade gelöscht wurde, wird dies in der Tat fehlschlagen. (Sie können den alten Pfad mit erhalten ls -l /proc/<pid>/fd/<handle>) - tnimeu
Diese Art von Funktionalität (Siehe diese Frage und antworten) war spezifisch abgelehnt als ein Sicherheitsrisiko [zu einem hypothetischen Sicherheitssystem, das sich um einen privilegierten Prozess dreht, der Ihrem Prozess ein schreibgeschütztes Dateihandle zu einer Datei gibt, die Sie besitzen, auf die Sie sonst keinen Zugriff haben]; Ich versuchte es (obwohl mit einem kleinen C-Programm, um den relevanten Systemanruf direkt zu verwenden) und es hat nicht funktioniert. - Random832
Ich habe das natürlich getestet, bevor ich meine Lösung gepostet habe, und zu dieser Zeit funktionierte es tatsächlich für mich. Was mir nicht bewusst war, ist, dass es nur funktioniert hat tmpfsDateisysteme, aber nicht z.B. ext3. Darüber hinaus Merkmal wurde komplett in 2.6.39 deaktiviert, siehe das Festschreiben. Daher wird diese Lösung nicht mehr mit dem Kernel 2.6.39 oder neuer funktionieren und in früheren Versionen hängt sie vom Dateisystem ab. - tnimeu
@tnimeu ln -L funktioniert nicht für mich. Ich habe eine gelöschte Datei und habe versucht, sie wieder mit dem ursprünglichen Pfad zu verbinden. ln gibt mir ein ln: failed to create hard link /my/path/file.pdf => /proc/19674/fd/16: No such file or directory. Aber ich kann z.B. erfolgreich cat /proc/19674/fd/16 - Eugene Beresovsky


Es hört sich so an, als ob du schon viel verstehst, also werde ich nicht zu sehr ins Detail gehen. Es gibt mehrere Methoden, um den Inode zu finden, und Sie können STDOUT normalerweise cat und umleiten. Sie können verwenden debugfs. Führen Sie diesen Befehl innerhalb von:

ln <$INODE> FILENAME

Stellen Sie sicher, dass Sie Sicherungen des Dateisystems haben. Sie müssen wahrscheinlich danach einen fsck ausführen. Ich habe dies erfolgreich mit einem Inode getestet, der noch geschrieben wird, und es funktioniert, um eine neue feste Verbindung zu einem dereferenzierten Inode zu erstellen.

Wenn die Datei in ext3 nicht mit einer nicht geöffneten Datei verknüpft ist, gehen die Daten verloren. Ich bin mir nicht sicher, wie konsequent das ist, aber die meisten meiner Datenrettung Erfahrung ist mit ext2. Von der ext3-FAQ:

F: Wie kann ich wiederherstellen (wiederherstellen)?   gelöschte Dateien von meiner ext3-Partition?   Eigentlich kannst du nicht! Das ist was man   von den Entwicklern, Andreas Dilger,   sagte darüber:

Um sicherzustellen, dass ext3 kann   nach einem Absturz sicher eine Verknüpfung aufheben,   es löscht den Block tatsächlich aus   Zeiger in der Inode, während ext2   markiert diese Blöcke nur als unbenutzt in   Das Block Bitmaps und markiert den Inode   als "gelöscht" und verlässt den Block   Zeiger allein.

Deine einzige Hoffnung ist es, Teile zu "grep"   Ihrer Dateien, die gelöscht wurden   und hoffe auf das Beste.

Es gibt auch relevante Informationen in dieser Frage:

Ich überschrieb eine große Datei mit einem leeren auf einem Linux-Server. Kann ich die vorhandene Datei wiederherstellen?


13
2017-08-10 16:32



Kommentar hoffentlich gelöscht, da es nicht offen war. - mdpc
Im Falle einer gelöschten aber noch offenen Datei glaube ich nicht, dass es die Zeiger im Inode auf Null setzen würde. Anstelle von "ln" in debugfs würde ich auch "undel" verwenden, damit die Inode-Referenzzähler korrekt aktualisiert werden. - Mark Wagner
Ich wollte das nicht als Embobo bezeichnen. Tut es nicht, ich habe die Leistung getestet. Ich habe meine Sprache geklärt. - Warner
Clever, aber korrumpiert mein Dateisystem. :) - mbac32768
Es ist die einzige Lösung für das Szenario, wie Sie es beschreiben. Das Manipulieren eines Dateisystems auf einer niedrigen Ebene, das angehängt und aktiv beschrieben wird, führt in fast allen Szenarien zu Beschädigungen. - Warner


Die Debugging-Methode, wie Sie gesehen haben, funktioniert nicht wirklich und im besten Fall wird Ihre Datei automatisch (aufgrund des Journals) nach dem Neustart gelöscht und im schlimmsten Fall können Sie Ihr Dateisystem zerstören, was zu einem "Neustart des Todes" führt. Die Right Solution (TM) besteht darin, das Undelete in der VFS-Ebene auszuführen (was den zusätzlichen Vorteil hat, mit praktisch allen aktuellen Linux-Dateisystemen zu arbeiten). Der Systemanrufweg (flink) wurde jedes Mal abgeschossen, wenn er in LKML auftauchte, also ist der beste Weg durch ein Modul + ioctl.

Ein Projekt, das diesen Ansatz implementiert und einen relativ kleinen und sauberen Code hat, ist fdlink (https://github.com/pkt/fdlink.git für eine Version mit ubuntu Maverick-Kernel getestet). Damit können Sie nach dem Einfügen des Moduls (sudo insmod flink_dev.ko) einfach tun "./flinkapp / proc // fd / X / mein / Link / Pfad" und es wird genau das tun, was Sie wollen.

Sie können auch eine Forward-Ported-Version von vfs-undelete.sourceforge.net verwenden, die ebenfalls funktioniert (und auch automatisch mit dem ursprünglichen Namen verknüpfen kann), aber der Code von fdlink ist einfacher und funktioniert genauso gut, also ist es meine Präferenz.


7
2018-04-09 21:58





Ich weiß nicht, wie ich genau das machen soll, was du willst, aber was ich tun würde, ist:

  • Öffnen Sie die Datei RO von einem anderen Prozess
  • Warten Sie, bis der ursprüngliche Prozess beendet wurde
  • Kopieren Sie die Daten von Ihrer geöffneten FD in eine Datei

Nicht ideal, natürlich, aber möglich. Die andere Option ist, mit debugfs herumzuspielen (mit dem link Befehl), aber das ist irgendwie erschreckend auf einer Produktionsmaschine!


3
2017-08-10 15:44



Der Befehl debugfs link unterstützt diesen Anwendungsfall überhaupt nicht. - mbac32768
tldp.org/HOWTO/Ext2fs-Undeletion-11.html schlägt vor, dass es tut. Ich habe es nicht versucht, aber das scheint vernünftig. - Bill Weiss
link hat in meinen Tests aber nicht funktioniert ln hat getan. - Warner


Bin heute auf dasselbe Problem gestoßen. Das Beste, was ich mir vorstellen kann, ist zu rennen

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

in einer tmux / screen-Sitzung, bis der Prozess endet.


3
2017-12-06 16:08



Die Verknüpfung mit den Originaldateien, wie in der angenommenen Antwort, sollte funktionieren. - Chris S
Es gibt keine akzeptierte Antwort für diese Frage, auf welche beziehen Sie sich? - Hamman Samuel
Sollte dies nicht eine Umleitung benötigen (>) zur gelöschten Datei? - ncasas


Interessante Frage. Ein Interviewer stellte mir dieselbe Frage in einem Vorstellungsgespräch. Was ich ihm sagte war, dass es keine einfache Möglichkeit gab, dies zu tun und im Allgemeinen war es nicht die Zeit und Mühe wert. Ich habe ihn gefragt, was er für die Lösung dieses Problems hielt ....

  1. Verwenden Sie lsof, um die Inode-Nummer auf der Festplatte für den Prozess zu finden, da sie immer noch angezeigt wird, selbst wenn die Datei gelöscht wurde ... der Schlüssel ist, dass sie noch geöffnet ist.
  2. Extrahieren Sie die Informationen von diesem Dateisystem über einen Dateisystem-Debugger.

1
2017-08-10 16:35



Ich kann die Daten einfach aus / proc / <pid> / fd / N extrahieren, aber das ist nicht das, was ich versuche zu tun. - mbac32768


Benutzen Sleuthkit icat.

sudo icat /dev/rdisk1s2 5484287 > accidentally_deleted_open_file

1
2018-02-19 18:03



Dies funktioniert, indem die Dateisystemfunktionalität des Betriebssystems umgangen und die Datenträger-Bytes direkt analysiert werden. - Flimm


Die schnelle Lösung, die für mich funktionierte, ohne Werkzeuge einzuschüchtern:

1) Finden Sie den Prozess + fd, indem Sie direkt in / proc suchen:

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

2) Dann eine ähnliche Technik zu @ Nickray, mit pv geworfen in:

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

Eventuell müssen Sie Strg-C drücken, wenn Sie fertig sind (ls /proc/{procnum}/fd/{fdnum} wird Ihnen sagen, dass die Datei nicht mehr existiert)), aber wenn Sie die genaue Größe in Bytes kennen, können Sie verwenden pv -S um es zu verlassen, wenn die Zählung erreicht ist.


0
2017-07-28 07:10