Menghubungkan kembali file yang dihapus

33

Terkadang orang menghapus file yang tidak seharusnya, proses yang berjalan lama masih memiliki file terbuka, dan memulihkan data dengan catting /proc/<pid>/fd/Ntidak cukup mengagumkan. Cukup mengagumkan jika Anda dapat "membatalkan" penghapusan dengan menjalankan beberapa opsi ajaib ke ln yang akan memungkinkan Anda menautkan kembali ke nomor inode (dipulihkan melalui lsof).

Saya tidak dapat menemukan alat Linux untuk melakukan ini, apalagi dengan Googling sepintas.

Apa yang kamu dapat, serverfault?

EDIT1: Alasan catting file dari /proc/<pid>/fd/Ntidak cukup luar biasa adalah karena proses yang masih membuka file masih menulis untuk itu. Hapus menghapus referensi ke inode dari namespace sistem file. Yang saya inginkan adalah cara menciptakan kembali referensi.

EDIT2: 'debugfs ln' berfungsi tetapi risikonya terlalu tinggi karena ia merusak data sistem file mentah. File yang dipulihkan juga tidak konsisten gila. Jumlah tautan adalah nol dan saya tidak dapat menambahkan tautan ke sana. Saya lebih buruk dari ini karena saya hanya dapat menggunakan /proc/<pid>/fd/Nuntuk mengakses data tanpa merusak fs saya.

mbac32768
sumber

Jawaban:

14

Cukup mengagumkan jika Anda dapat "membatalkan" penghapusan dengan menjalankan beberapa opsi ajaib ke ln yang akan memungkinkan Anda menautkan kembali ke nomor inode (dipulihkan melalui lsof).

Keangkeran ini diperkenalkan lndi v8.0 (GNU / coreutils) dengan -L|--logicalopsi yang menyebabkan lndereference menjadi yang /proc/<pid>/fd/<handle>pertama. Sangat sederhana

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

cukup untuk menautkan kembali file yang dihapus.

tnimeu
sumber
7
Ini tidak berfungsi; jika file dihapus maka akan gagal.
Random832
1
Tidak, tidak akan. Saya secara teratur menggunakan ini untuk mengembalikan file yang dihapus tetapi masih dibuka. Tetapi Anda perlu memastikan, bahwa yang baru /path/to/deleted/fileada di sistem file yang sama dengan file itu sebelum dihapus, kalau tidak ini akan - memang - gagal. (Anda bisa mendapatkan jalan lama dengan ls -l /proc/<pid>/fd/<handle>)
tnimeu
2
Fungsionalitas semacam ini (Lihat pertanyaan dan jawaban ini) secara khusus ditolak sebagai risiko keamanan [terhadap skema keamanan hipotetis yang berputar di sekitar proses istimewa yang memberikan proses Anda menangani hanya baca file ke file yang Anda miliki tetapi tidak memiliki akses ke ]; Saya mencobanya (walaupun dengan program C kecil untuk langsung menggunakan system call yang relevan) dan tidak berhasil.
Random832
7
Saya, tentu saja, menguji ini sebelum memposting solusi saya dan pada saat itu itu benar-benar bekerja untuk saya. Apa yang saya tidak sadari adalah bahwa itu hanya bekerja pada tmpfssistem file tetapi tidak pada misalnya ext3. Lebih jauh, fitur ini sepenuhnya dinonaktifkan di 2.6.39, lihat komit . Jadi karena itu solusi ini tidak akan berfungsi dengan kernel 2.6.39 atau lebih baru dan dalam versi sebelumnya tergantung pada sistem file.
tnimeu
7
@tnimeu ln -Ltidak bekerja untuk saya. Saya memiliki file yang dihapus dan saya mencoba menghubungkannya kembali ke jalur asli. lnmemberi saya ln: failed to create hard link /my/path/file.pdf => /proc/19674/fd/16: No such file or directory. Tapi saya bisa mis berhasilcat /proc/19674/fd/16
Eugene Beresovsky
13

Sepertinya Anda sudah mengerti banyak hal, jadi saya tidak akan membahas terlalu banyak detail. Ada beberapa metode untuk menemukan inode dan Anda biasanya dapat mengecat dan mengarahkan STDOUT. Anda bisa menggunakannya debugfs. Jalankan perintah ini di dalam:

ln <$INODE> FILENAME

Pastikan Anda memiliki cadangan sistem file. Anda mungkin perlu menjalankan fsck sesudahnya. Saya menguji ini berhasil dengan inode yang masih ditulis dan itu berhasil untuk membuat tautan keras baru ke inode dereferenced.

Jika file tidak terhubung dengan file yang belum dibuka di ext3, data akan hilang. Saya tidak yakin seberapa konsisten ini, tetapi sebagian besar pengalaman pemulihan data saya adalah dengan ext2. Dari FAQ ext3:

T: Bagaimana saya bisa memulihkan (membatalkan penghapusan) file yang dihapus dari partisi ext3 saya? Sebenarnya kamu tidak bisa! Inilah yang dikatakan oleh salah satu pengembang, Andreas Dilger:

Untuk memastikan bahwa ext3 dapat dengan aman melanjutkan pembatalan tautan setelah terjadi kerusakan, ext3 benar-benar mengeluarkan pointer blok di inode, sedangkan ext2 hanya menandai blok-blok ini sebagai tidak terpakai dalam bitmap blok dan menandai inode sebagai "dihapus" dan meninggalkan blok tersebut petunjuk saja.

Satu-satunya harapan Anda adalah "grep" untuk bagian-bagian file Anda yang telah dihapus dan berharap yang terbaik.

Ada juga informasi yang relevan dalam pertanyaan ini:

Saya menimpa file besar dengan yang kosong di server linux. Bisakah saya memulihkan file yang ada?

Warner
sumber
Mudah-mudahan komentar dihapus karena tidak terpesona.
mdpc
1
Dalam hal file yang dihapus tetapi masih terbuka saya tidak berpikir itu akan nol pointer dalam inode. Selain itu, daripada menggunakan "ln" di debugfs saya akan menggunakan "undel" sehingga jumlah referensi inode akan diperbarui dengan benar.
Mark Wagner
Aku tidak bermaksud menyinggung itu, embobo. Tidak, saya menguji kinerjanya. Saya sudah mengklarifikasi bahasa saya.
Warner
Pintar, tetapi merusak sistem file saya. :)
mbac32768
Ini satu-satunya solusi untuk skenario saat Anda menggambarkannya. Memanipulasi sistem file pada level rendah yang sudah terpasang dan aktif ditulis cenderung menyebabkan korupsi di hampir semua skenario.
Warner
8

cara debugfs seperti yang Anda lihat tidak benar-benar berfungsi dan yang terbaik file Anda akan dihapus secara otomatis (karena jurnal) setelah reboot dan paling buruk Anda dapat membuang sistem file Anda yang mengakibatkan "reboot cycle of death". Solusi Tepat (TM) adalah untuk melakukan penghapusan yang dihapus pada tingkat VFS (yang juga memiliki manfaat tambahan untuk bekerja dengan hampir semua sistem file Linux saat ini). Cara panggilan sistem (flink) telah ditembak jatuh setiap kali muncul di LKML sehingga cara terbaik adalah melalui modul + ioctl.

Sebuah proyek yang mengimplementasikan pendekatan ini dan memiliki kode yang cukup kecil dan bersih adalah fdlink ( https://github.com/pkt/fdlink.git untuk versi yang diuji dengan kernel ubvernver maverick). Dengan itu, setelah Anda memasukkan modul (sudo insmod flink_dev.ko) Anda bisa melakukan "./flinkapp / proc // fd / X / my / link / path" dan itu akan melakukan apa yang Anda inginkan.

Anda juga dapat menggunakan versi vfs-undelete.sourceforge.net port-maju yang juga berfungsi (dan juga dapat secara otomatis menautkan kembali ke nama asli), tetapi kode fdlink lebih sederhana dan berfungsi dengan baik, jadi itu adalah pilihan saya.

pktoss
sumber
3

Saya tidak tahu bagaimana melakukan persis apa yang Anda inginkan, tetapi apa yang akan saya lakukan adalah:

  • Buka file RO dari proses lain
  • Tunggu proses asli untuk keluar
  • Salin data dari FD terbuka Anda ke file

Jelas tidak ideal, tetapi mungkin. Pilihan lainnya adalah bermain-main dengan debugfs (menggunakan linkperintah), tapi itu agak menakutkan pada mesin produksi!

Bill Weiss
sumber
Perintah tautan debugfs sama sekali tidak mendukung use case ini.
mbac32768
tldp.org/HOWTO/Ext2fs-Undeletion-11.html menyarankan itu. Saya belum mencobanya, tapi itu masuk akal.
Bill Weiss
linktidak bekerja dalam pengujian saya tetapi lnberhasil.
Warner
3

Berlari ke masalah yang sama hari ini. Yang terbaik yang bisa saya lakukan adalah berlari

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

dalam sesi tmux / layar sampai proses berakhir.

Nickray
sumber
2
Menautkan ke file asli, seperti dalam jawaban yang diterima, akan berfungsi.
Chris S
1
Tidak ada jawaban yang diterima untuk pertanyaan ini, yang mana yang Anda maksud?
Hamman Samuel
Tidakkah ini perlu redirection ( >) ke file yang dihapus?
ncasas
1

Pertanyaan menarik. Seorang pewawancara mengajukan pertanyaan yang sama kepada saya dalam wawancara kerja. Apa yang saya katakan kepadanya adalah bahwa tidak ada cara mudah untuk melakukan ini dan secara umum tidak sepadan dengan waktu dan upaya yang terlibat. Saya bertanya kepadanya apa yang dia pikir solusi untuk masalah ini adalah ....

  1. Gunakan lsof untuk menemukan nomor inode pada disk untuk proses karena akan tetap muncul bahkan jika file telah dihapus ... kuncinya adalah bahwa itu masih terbuka.
  2. Ekstrak informasi dari sistem file berdasarkan ini melalui debugger sistem file.
mdpc
sumber
Saya dapat mengekstrak data dengan baik dari / proc / <pid> / fd / N tapi bukan itu yang saya coba lakukan.
mbac32768
1

Gunakan Sleuthkit icat.

sudo icat /dev/rdisk1s2 5484287 > accidentally_deleted_open_file
Ishak
sumber
Ini berfungsi dengan mem-bypass fungsionalitas sistem file sistem operasi dan mem-parsing byte disk secara langsung.
Flimm
0

Solusi cepat yang berhasil bagi saya, tanpa alat yang mengintimidasi:

1) temukan proses + fd dengan melihat langsung di / proc:

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

2) Kemudian teknik yang mirip dengan @ nickray, dengan pvdilemparkan ke:

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

Anda mungkin perlu Ctrl-C saat selesai ( ls /proc/{procnum}/fd/{fdnum}akan memberi tahu Anda bahwa file tidak ada lagi)), tetapi jika Anda tahu ukuran pasti dalam byte, Anda dapat menggunakannya pv -Suntuk keluar ketika hitungan tercapai.

xenoid
sumber