Wie kann ich eine gelöschte Datei wiederherstellen, wenn sie noch von einem Prozess geöffnet wurde?

19
$ cat important_file > /dev/null &
[1] 9711
$ rm important_file 
$ killall -STOP cat

[1]+  Stopped                 cat important_file > /tmp/p
$ ls -l /proc/`pidof cat`/fd/
total 0
lrwx------ 1 vi vi 64 May 13 20:32 0 -> /dev/pts/29
l-wx------ 1 vi vi 64 May 13 20:32 1 -> /tmp/p
lrwx------ 1 vi vi 64 May 13 20:32 2 -> /dev/pts/29
lr-x------ 1 vi vi 64 May 13 20:32 3 -> /home/vi/important_file (deleted)

Wie kann ich das wiederherstellen important_file?

Ich habe so etwas versucht

injcode -m dup2 -ofd=3 -ofilename=/tmp/recovered_file -oflags=O_CREAT $PID_OF_CAT

aber es tut nichts.

Vi.
quelle

Antworten:

11

Wenn / home NFS ist, gibt es eine .nfsNNNNNNNNNN-Datei in / home / vi, auf die Sie zugreifen / kopieren können. Wenn home ein lokales Dateisystem ist, sollten Sie in der Lage sein, dasselbe über den Link / proc / PID / fd / 3 zu tun:

cp /proc/PID/fd/3 /tmp/recovered_file

Wenn Sie die Datei tatsächlich wiederherstellen möchten, finden Sie hier einen Blogeintrag zu diesem Thema.

Mark Johnson
quelle
1
OK, das hat mich verwirrt readlink /proc/13381/fd/3-> "/ home / vi / important_file (deleted)" und existiert /home/vi/important_file\ \(deleted\)offensichtlich nicht.
Vi.
21

... besser als zu einem bestimmten Zeitpunkt zu kopieren (und nur die Momentaufnahme des Dateiinhalts zu diesem Zeitpunkt zu erfassen), ist es, " tail -f" diese Datei in eine neue Datei zu kopieren :

tail -c +0 -f /proc/PIDofProgram>/fd/# > /new/path/to/file

(Dank der vorsichtigen Programmierer von Tail funktioniert das sogar mit Binärausgabe.)

Während der Laufzeit tail -fhält das Programm die Datei selbst geöffnet und verhindert so, dass sie beim Beenden des ursprünglichen Programms von der Festplatte gelöscht wird. Stoppen Sie also nicht tail -fgleich nach dem Ende Ihres ursprünglichen Programms - prüfen Sie /new/path/to/filezuerst, ob es das ist, was Sie wollen. Wenn es nicht (oder nicht zufriedenstellend aus einem anderen Grunde) ist, können Sie die ursprüngliche Datei erneut kopieren, aber diesmal nach allen schriftlich es wird von „Programm“ und aus dem noch laufenden fertig tail -f‚s / proc / PIDoftail / fd / verzeichnis.

Christian
quelle
3
Wie wäre es mit einem Hardlink zu / proc / PIDofProgram> / fd / #?
Becko
2
@becko Invalid cross-device link.
Kamil Maciorowski
10

Verwenden Sie lsof, um die Inode-Nummer zu ermitteln, und debugfs, um eine feste Verknüpfung zu dieser wiederherzustellen. Beispielsweise:

# lsof -p 12345 | grep /var/log/messages
syslogd 12345 root    3w   REG                8,3    3000    987654 /var/log/messages (deleted)
# mount | grep var
/dev/sda2 on /var type ext3 (rw)
# debugfs -w /dev/sda2
debugfs: cd log
debugfs: ln <987654> tmp
debugfs: mi tmp
                      Mode    [0100600] 
                   User ID    [0] 
                  Group ID    [0] 
                      Size    [3181271] 
             Creation time    [1375916400] 
         Modification time    [1375916322] 
               Access time    [1375939901]
             Deletion time    [9601027] 0
                Link count    [0] 1
               Block count    [6232] 
                File flags    [0x0] 
...snip...
debugfs:  q
# mv /var/log/tmp /var/log/messages
# ls -al /var/log/messages
-rw------- 0 root root 3301 Aug  8 10:10 /var/log/messages

Bevor Sie sich beschweren, habe ich das obige Protokoll gefälscht, da ich momentan keine gelöschte Datei zur Hand habe ;-)

Ich misetze die Löschzeit und die Linkanzahl auf sinnvolle Werte zurück (0 bzw. 1), aber es funktioniert nicht richtig - Sie können sehen, dass die Linkanzahl bei Null in bleibt ls. Ich denke, der Kernel könnte die Inode-Daten zwischenspeichern. Sie sollten wahrscheinlich frühestens nach der Verwendung von debugfs prüfen, um auf der sicheren Seite zu sein.

Nach meiner Erfahrung sollten Sie den Link mit einem temporären Dateinamen erstellen und dann in den richtigen Namen umbenennen. Das direkte Verknüpfen mit dem ursprünglichen Dateinamen scheint zu einer Beschädigung des Verzeichnisses zu führen. YMMV!

Andrew Gallagher
quelle
Warum genau schlagen Sie dies vor, wenn es nicht richtig funktioniert und Systemschäden verursacht? Ich denke, Sie sollten einen klareren Haftungsausschluss in der Antwort haben, dass dies einfach ein WiP ist und nicht wirklich in der Produktion ausprobiert werden sollte.
4.
3

Sie können nur cpdie Datei, dh:

cp /proc/<pid>/fd/<fdno> /new/path/to/file

Wenn die Datei noch geändert wird, kann dies natürlich zu Problemen führen.

Ninjalj
quelle