Xem lại một tập tin đã xóa


33

Đôi khi mọi người xóa các tệp mà họ không nên, một quy trình chạy dài vẫn mở tệp và khôi phục dữ liệu bằng cách trích dẫn /proc/<pid>/fd/Nchỉ là không đủ tuyệt vời. Đủ tuyệt vời sẽ là nếu bạn có thể "hoàn tác" việc xóa bằng cách chạy một số tùy chọn ma thuật để cho phép bạn liên kết lại với số inode (được phục hồi thông qua lsof).

Tôi không thể tìm thấy bất kỳ công cụ Linux nào để làm điều này, ít nhất là với Google Googling.

Bạn có gì, serverfault?

EDIT1: Lý do trích dẫn tệp từ /proc/<pid>/fd/Nkhông đủ tuyệt vời là vì quá trình vẫn mở tệp vẫn đang ghi vào đó. Việc xóa sẽ xóa tham chiếu đến inode khỏi không gian tên hệ thống tập tin. Những gì tôi muốn là một cách để tạo lại tài liệu tham khảo.

EDIT2: 'debugfs ln' hoạt động nhưng rủi ro quá cao vì nó đóng băng dữ liệu hệ thống tập tin thô. Các tập tin phục hồi cũng điên không nhất quán. Số lượng liên kết bằng không và tôi không thể thêm liên kết đến nó. Tôi tệ hơn theo cách này vì tôi chỉ có thể sử dụng /proc/<pid>/fd/Nđể truy cập dữ liệu mà không làm hỏng fs của mình.

Câu trả lời:


14

Đủ tuyệt vời sẽ là nếu bạn có thể "hoàn tác" việc xóa bằng cách chạy một số tùy chọn ma thuật để cho phép bạn liên kết lại với số inode (được phục hồi thông qua lsof).

Điều tuyệt vời này đã được giới thiệu lntrong v8.0 (GNU / coreutils) với -L|--logicaltùy chọn gây ra lnsự thiếu sót /proc/<pid>/fd/<handle>trước tiên. Thật đơn giản

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

là đủ để xem lại một tập tin bị xóa.


7
Điều này không hoạt động; nếu tập tin bị xóa nó sẽ thất bại.
Random832

1
Không, nó sẽ không. Tôi thường xuyên sử dụng để khôi phục các tập tin đã xóa nhưng vẫn mở. Nhưng bạn cần chắc chắn rằng cái mới /path/to/deleted/filenằm trên cùng một hệ thống tập tin giống như tập tin ngay trước khi nó bị xóa, điều này sẽ - thực sự - thất bại. (Bạn có thể đi theo con đường cũ với ls -l /proc/<pid>/fd/<handle>)
tnimeu

2
Loại chức năng này (Xem câu hỏi và câu trả lời này) đã bị loại bỏ một cách cụ thể vì rủi ro bảo mật [đối với sơ đồ bảo mật giả định xoay quanh quy trình đặc quyền cho phép xử lý tệp chỉ đọc của bạn đối với tệp mà bạn sở hữu nhưng không có quyền truy cập vào ]; Tôi đã thử nó (mặc dù với một chương trình C nhỏ để sử dụng trực tiếp cuộc gọi hệ thống có liên quan) và nó không hoạt động.
Random832

7
Tôi, tất nhiên, đã kiểm tra điều này trước khi đăng giải pháp của tôi và tại thời điểm đó nó thực sự hiệu quả với tôi. Điều tôi không biết là nó chỉ hoạt động trên các tmpfshệ thống tập tin chứ không hoạt động ext3. Hơn nữa, tính năng này đã bị vô hiệu hóa hoàn toàn trong 2.6,39, xem cam kết . Vì vậy, giải pháp này sẽ không hoạt động với kernel 2.6.39 hoặc mới hơn nữa và trong các phiên bản trước đó, nó phụ thuộc vào hệ thống tập tin.
tnimeu

7
@tnimeu ln -Lkhông làm việc cho tôi. Tôi có một tập tin bị xóa và tôi đã cố gắng đưa nó trở lại đường dẫn ban đầu. lncho tôi a ln: failed to create hard link /my/path/file.pdf => /proc/19674/fd/16: No such file or directory. Nhưng tôi có thể ví dụ thành côngcat /proc/19674/fd/16
Eugene Beresovsky

13

Có vẻ như bạn đã hiểu rất nhiều, vì vậy tôi sẽ không đi sâu vào chi tiết. Có một số phương pháp để tìm inode và bạn thường có thể cat và chuyển hướng STDOUT. Bạn có thể sử dụng debugfs. Chạy lệnh này trong:

ln <$INODE> FILENAME

Hãy chắc chắn rằng bạn có bản sao lưu của hệ thống tập tin. Bạn có thể sẽ cần phải chạy một fsck sau đó. Tôi đã thử nghiệm điều này thành công với một nút vẫn đang được viết và nó hoạt động để tạo ra một liên kết cứng mới đến một nút bị hủy đăng ký.

Nếu tệp không được liên kết với tệp chưa mở trong ext3, dữ liệu sẽ bị mất. Tôi không chắc điều này đúng như thế nào nhưng hầu hết trải nghiệm phục hồi dữ liệu của tôi là với ext2. Từ câu hỏi thường gặp về ext3:

H: Làm cách nào tôi có thể khôi phục (hủy xóa) các tệp đã xóa khỏi phân vùng ext3 của mình? Thật ra, bạn không thể! Đây là những gì một trong những nhà phát triển, Andreas Dilger, nói về nó:

Để đảm bảo ext3 có thể khôi phục lại một liên kết một cách an toàn sau khi gặp sự cố, nó thực sự loại bỏ các con trỏ khối trong inode, trong khi ext2 chỉ đánh dấu các khối này là không được sử dụng trong bitmap khối và đánh dấu inode là "bị xóa" và rời khỏi khối con trỏ một mình.

Hy vọng duy nhất của bạn là "grep" cho các phần của tệp đã bị xóa và hy vọng điều tốt nhất.

Cũng có thông tin liên quan trong câu hỏi này:

Tôi ghi đè lên một tệp lớn với một tệp trống trên máy chủ linux. Tôi có thể khôi phục các tập tin hiện có?


Bình luận hy vọng xóa vì nó không được tiết lộ.
mdpc

1
Trong trường hợp tệp bị xóa nhưng vẫn mở, tôi không nghĩ rằng nó sẽ loại bỏ các con trỏ trong nút. Ngoài ra, thay vì sử dụng "ln" trong debugfs, tôi sử dụng "undel" để số tham chiếu inode sẽ được cập nhật chính xác.
Đánh dấu Wagner

Tôi không có ý ám chỉ như vậy, embobo. Không, tôi đã kiểm tra hiệu suất. Tôi đã làm rõ ngôn ngữ của mình.
Warner

Thông minh, nhưng làm hỏng hệ thống tập tin của tôi. :)
mbac32768

Đó là giải pháp duy nhất cho kịch bản như bạn mô tả. Thao tác một hệ thống tập tin ở mức thấp được gắn rw và chủ động được ghi vào có khả năng gây ra tham nhũng trong hầu hết các kịch bản.
Warner

8

cách gỡ lỗi như bạn thấy không thực sự hoạt động và tốt nhất là tệp của bạn sẽ tự động bị xóa (do tạp chí) sau khi khởi động lại và tệ nhất là bạn có thể rác hệ thống tệp của mình dẫn đến "chu kỳ khởi động lại cái chết". Giải pháp đúng (TM) là thực hiện khôi phục ở cấp độ VFS (cũng có thêm lợi ích khi làm việc với tất cả các hệ thống tệp Linux hiện tại). Cách gọi hệ thống (flink) đã bị bắn hạ mỗi khi nó xuất hiện trong LKML, vì vậy cách tốt nhất là thông qua một mô-đun + ioctl.

Một dự án thực hiện phương pháp này và có mã nhỏ và hợp lý là fdlink ( https://github.com/pkt/fdlink.git cho một phiên bản được thử nghiệm với kernel của ub Ubuntu maverick). Với nó, sau khi bạn chèn mô-đun (sudo insmod flink_dev.ko), bạn có thể thực hiện "./flinkapp / Proc // fd / X / my / link / path" và nó sẽ thực hiện chính xác những gì bạn muốn.

Bạn cũng có thể sử dụng phiên bản chuyển tiếp của vfs-undelete.sourceforge.net cũng hoạt động (và cũng có thể tự động chuyển lại tên gốc), nhưng mã của fdlink đơn giản hơn và nó cũng hoạt động tốt, vì vậy đó là sở thích của tôi.


3

Tôi không biết làm thế nào để làm chính xác những gì bạn muốn, nhưng những gì tôi sẽ làm là:

  • Mở tệp RO từ quy trình khác
  • Đợi quá trình ban đầu để thoát
  • Sao chép dữ liệu từ FD mở của bạn vào một tệp

Không lý tưởng, rõ ràng, nhưng có thể. Tùy chọn khác là chơi xung quanh với debugfs (sử dụng linklệnh), nhưng điều đó thật đáng sợ trên một máy sản xuất!


Lệnh liên kết debugfs hoàn toàn không hỗ trợ trường hợp sử dụng này.
mbac32768

tldp.org/HOWTO/Ext2fs-Undeletion-11.html gợi ý rằng nó có. Tôi đã không thử nó, nhưng điều đó có vẻ hợp lý.
Bill Weiss

linkđã không làm việc trong thử nghiệm của tôi nhưng lnđã làm.
Warner

3

Ran vào cùng một vấn đề ngày hôm nay. Điều tốt nhất tôi có thể nghĩ ra là chạy

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

trong một phiên tmux / màn hình cho đến khi quá trình kết thúc.


2
Liên kết đến các tệp gốc, như trong câu trả lời được chấp nhận, sẽ hoạt động.
Chris S

1
Không có câu trả lời được chấp nhận cho câu hỏi này, bạn đang đề cập đến câu hỏi nào?
Hamman Samuel

Không nên điều này cần một chuyển hướng ( >) đến tập tin bị xóa?
ncasas

1

Câu hỏi thú vị. Một người phỏng vấn đã hỏi tôi câu hỏi tương tự trong một cuộc phỏng vấn xin việc. Những gì tôi nói với anh ta là không có cách nào dễ dàng để làm điều này và nói chung là không xứng đáng với thời gian và nỗ lực liên quan. Tôi đã hỏi anh ấy những gì anh ấy nghĩ giải pháp cho vấn đề này là ....

  1. Sử dụng lsof để tìm số inode trên đĩa cho quá trình vì nó vẫn sẽ xuất hiện ngay cả khi tệp đã bị xóa ... điều quan trọng là nó vẫn đang mở.
  2. Trích xuất thông tin từ hệ thống tập tin dựa trên điều này thông qua trình gỡ lỗi hệ thống tập tin.

Tôi có thể trích xuất dữ liệu tốt từ / Proc / <pid> / fd / N nhưng đó không phải là điều tôi đang cố gắng thực hiện.
mbac32768

1

Sử dụng iuth Sleuthkit .

sudo icat /dev/rdisk1s2 5484287 > accidentally_deleted_open_file

Điều này hoạt động bằng cách bỏ qua chức năng hệ thống tập tin của hệ điều hành và phân tích cú pháp các byte đĩa trực tiếp.
Flimm

0

Giải pháp nhanh chóng hiệu quả với tôi mà không cần các công cụ đáng sợ:

1) tìm quá trình + fd bằng cách xem trực tiếp trong / Proc:

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

2) Sau đó, một kỹ thuật tương tự như @ nickray, với pvném vào:

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

Bạn có thể cần Ctrl-C khi hoàn tất ( ls /proc/{procnum}/fd/{fdnum}sẽ cho bạn biết rằng tệp không còn tồn tại)), nhưng nếu bạn biết kích thước chính xác theo byte, bạn có thể sử dụng pv -Sđể làm cho nó thoát khi đạt được số đếm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.