Linux ext3 系統下刪除檔案救回全記錄

URL Link //n.sfs.tw/10431

2016-12-14 23:17:46 By 張○○

原由,今天一個不小心,下了 rm 的指令,從此奮戰一個下午,終於把檔案救回來,以下是全記錄。希望對其他人有幫助。

Linux 下的 rm 是刪檔的指令,在console下並沒有回收桶這個東西,刪了還有機會拿回來嗎?別想得太美好,能拿回一部分就偷笑了,非常的不容易。

一、發生原因

  本來想把寫的程式壓縮,壓縮完後要把他拷背到  html 的目錄下,因此:

本來是要下這樣的指令
# cp tccipv6_html.tgz html/
因為剛剛壓縮完畢,所以偷懶,就按方向鍵的「上」,得到上一個指令
# tar cvzf tccipv6_html.tgz html/*
然後要改成cp 那個指令,結果誰知一個分心,不知在想什麼鬼竟然改成
# rm tccipv6_html.tgz html/*

而且那個 '/*' 又沒拿掉,結果…整個 html/下的檔案都不見了,另外連壓縮備份的tccipv6_html.tgz也不見了

二、尋找備份

程式不大,重寫大概三四個小時,可是我不想重寫,開始找有沒有備份,暫存....

努力的思考,結果是 ..... 全沒有。因為東西剛完成,還沒備出來。當然事發當時大腦一片茫然,因為那個指令下去太快了,一切都沒有了,我還好有點概念,馬上把 apache 給停掉。

三、開始找網路文

1. Linux 上面的檔案救援 -- 用debugfs和什麼lsdel害我抱著一點希望,這個試很久發現都不行,原來這只適用 ext2系統的,ext3用了也是白用
     link.. http://antontw.blogspot.com/2008/03/linux-linux.html

2. 由上面那一篇得到用 dd 的方法回復,拿來試了 一個小時,放棄,因為他只能 by block 回復,不能 by inode,誰會知道刪掉的檔案 block 有幾個,連續的還好,片斷的根本無能為力。他的方法大概是這樣:

                                       v 要回覆到哪一個檔名      v 幾個 block
     # dd if=/dev/hdb2 of=recover_file bs=4096 count=1 skip=1901106
              ^ 介面的裝置,不是mount 的目錄                            ^ 起啟 block
     link.. http://linux.chinaunix.net/bbs/viewthread.php?tid=908164

3. 後來找到這一篇 HOWTO recover deleted files on an ext3 file system,也靠作者的程式,花了四個多小時,把程式成功救回
     link.. http://www.xs4all.nl/~carlo17/howto/undelete_ext3.html

     下載.. http://ext3grep.googlecode.com/files/ext3grep-0.10.1.tar.gz
     下載頁面... http://code.google.com/p/ext3grep/

    安裝很簡單,解壓後

    # ./configure
    # make install

四、救回方法

原作者 Carlo Wood 也在文章中寫得很清楚,這部分我還認真的看完,原來他在February 7th, 2008,不小心把他的 /home 給rm -rf 掉了,大概有3G而且是唯一的備份,(也許大家都要他放棄)但他開始研究ext3 系統,而且花了三週寫了5000多行的 C,並救回他所有的檔案。

作者非常仔細的介紹了 superblock,block,group等的概念,只是心急救回沒認真看,直到檔案救回來,晚上才慢慢的看。這篇可能是對 ext3 最詳細的說明文件了。原作者有非常詳細的說明,不再重複,以下是一個範例

我的磁碟系統

# df -h
Filesystem            容量  已用 可用 已用% 掛載點
/dev/mapper/VolGroup00-LogVol00  22G  2.3G   18G  12% /
/dev/cciss/c0d0p1      97M   13M   80M  14% /boot
none                  1.5G     0  1.5G   0% /dev/shm
/dev/mapper/VolGroup00-LogVol03 29G   22G  6.0G  79% /home
/dev/mapper/VolGroup00-LogVol02  49G   22G   24G  49% /var

# ext3grep /dev/mapper/VolGroup00-LogVol03 --restore-file ipv6/html
以上操作最值得注意的是,就是不要在這個磁碟下操作,還好當初我有把 /home 劃出去,所以我到 /tmp下操作,不會因為新的檔案蓋掉原來的 inode

這裡的 ipv6/html 代表的是原本的 /home/ipv6/html/ 因為這個磁碟是掛載在 /home,磁碟本身的路徑上是不知道自己在 /home 的,所以不用加,至於後面那個 '/' 請務必拿掉。這樣子他會把在 /home/ipv6/html/ 下的檔案還原。真的是這樣子就能還原嗎?不,沒這麼順利,當我做這個操作時,發現他沒辦法把我剛刪除的檔案找回來。

五、實際過程

因為這程式會將 inode 的內容複製一份到 RESTORED_FILES/ 目錄下。第一次操作會花一點時間,在目錄下建立

VolGroup00-LogVol03.ext3grep.stage1 (inodes和blocks對照表),
VolGroup00-LogVol03.ext3grep.stage2(目錄inodes和blocks對照表)
這兩個檔案,第一步先去尋找被刪掉的檔案所在的目錄inode 例如我要找回 /home/ipv6/html:

2747253 'ipv6/html' 5529600 
inode        目錄          block   

利用 --ls 去看這個 inode
# ext3grep /dev/mapper/VolGroup00-LogVol03 --ls --inode 2747253

結果發現被自己刪掉想救回的檔案(灰色)沒在裡面。下面是事後還原的內容:

=========+==========+----------------data-from-inode------+-----------+=========
   0    1    d 2747253                                         drwxrwxr-x  .
   1    2    d 2747246                                         drwx-----x  ..
   2    3    r 2747318                                         rrw-r--r--  init.php
   3    4    d 2747260                                         drwxrwxr-x  adodb5
   4    5    d 2747256                                         drwxrwxr-x  js
   5    6    r 2747322                                         rrw-r--r--  classes.php
   6    7    r 2747319                                         rrw-r--r--  index.php
   7    8    r 2747331                                         rrw-rw-r--  tccipv6_html.tgz

   8  end    d 2747476                                         drwxrwxr-x  libs


沒在裡面的話就沒辦法還原,好在當初沒有下 -rf 的參數,還留有三個目錄,他的 inode 分別是 2747-256 260 476

六、暴力法還原

檔案建立時,inode 的選取會先使用空的 inode (例如先前被移除的檔案留下的空缺),全用滿時才會使用後面的inode,這樣也許inode 並不會連續,但可以試試他的左右臨兵:

# ext3grep /dev/mapper/VolGroup00-LogVol03  --restore-inode 2747257

程式會在 RESTORED_FILES/ 產生一個 inode.2747257 的檔案,再 cat 其內容以判斷是不是被刪的檔

原來我太天真了,他的左右臨兵254 255 257 258 259都不是,後來  2747200 - 300 全試了,弄了很久,都不是,發現這樣太慢了。再讀一下他的說明,原來可以用這樣連續還原:於是我用excel 建立了一串還原指令,一次100個檔.原指令太長也截短:

# ext3grep /dev/mapper/VolGroup00-LogVol03  --restore-inode 2747378,2747379,2747380,2747381,2747382,2747383,  ........  2747518,2747519,2747520

這樣會在還原目錄下產生數百個檔案,不可能一個個 cat,因此用 grep 分別找到了,雖然檔案差不多同時建立的,可是他的 inode 如下,還差滿遠的

2747477 /home/ipv6/html/init.php
2747480 /home/ipv6/html/classes.php
2747556 /home/ipv6/html/index.php

以上操作要會EXCEL、grep + 靈感 + 運氣才成功。

話說重寫大概三個小時,上面花了五個小時,到底值不值?

值!
have fun !    


原文 2009-10-19 17:23:07

現在 centos7 已經是ext4的檔案類型,此文可能幫助不大