Fork me on GitHub

Linux上简单的文件恢复操作

  在 Linux 使用 rm 删除文件后,恢复起来还是有点麻烦的,不像 windows 上还有回收站和各种文件恢复软件;而且在删除文件,后执行了大量的 IO 操作,恢复起来更是困难,甚至无法恢复。

  rm 删除的本质是执行unlink() 函数,删除目录是执行 remove() 函数;而 unlink() 函数主要做的就是删除文件目录项并减少一个连接数,如果链接数为0并且没有任何进程打开该文件,文件将会被删除,但是其 inode 节点信息和data bloack仍然存在,只是解除了链接。如果是最后一个连接但是有进程打开文件,文件仍会存在,直到打开的文件被关闭。

  关于 inode表、super block、inode节点、data block不在此赘叙。

  rm 的防护措施:

1
2
3
4
alias rm='rm -i'
###强制删除确认,应写到配置文件中去
alias rm='mv -f $@ ~/backup'
###将rm 换成 mv,每隔一段时间清理 backup文件夹

  文件恢复操作:

  删除的文件正在被运行的进程使用(I/O操作): lsof

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[free@hurd]$ cat file
total 240
drwxrwxr-x 2 free free 4096 Sep 13 11:20 asciiquarium_1.1
-rw-rw-r-- 1 free free 15436 Mar 9 2013 asciiquarium.tar.gz
drwxrwxr-x 5 free free 4096 Apr 25 16:36 bumblebee-Old-and-abbandoned
drwxrwxr-x 2 free free 4096 Apr 23 16:01 cmatrix-1.2a
-rw-r--r-- 1 root root 74376 Apr 23 15:35 cmatrix-1.2a.tar.gz
drwxr-xr-x 3 free free 4096 Sep 30 10:08 extundelete-0.2.4
-rw-rw-r-- 1 free free 108472 Jan 4 2013 extundelete-0.2.4.tar.bz2
-rw-rw-r-- 1 free free 0 Sep 30 11:35 file
drwxrwxr-x 3 free free 4096 Sep 30 10:21 recovertest
-rw-rw-r-- 1 free free 18785 Dec 17 2006 Term-Animation-2.4.tar.gz
[free@hurd]$ cat >> file
test rm file

  重新开启一个终端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
[free@hurd]$ cat file
total 240
drwxrwxr-x 2 free free 4096 Sep 13 11:20 asciiquarium_1.1
-rw-rw-r-- 1 free free 15436 Mar 9 2013 asciiquarium.tar.gz
drwxrwxr-x 5 free free 4096 Apr 25 16:36 bumblebee-Old-and-abbandoned
drwxrwxr-x 2 free free 4096 Apr 23 16:01 cmatrix-1.2a
-rw-r--r-- 1 root root 74376 Apr 23 15:35 cmatrix-1.2a.tar.gz
drwxr-xr-x 3 free free 4096 Sep 30 10:08 extundelete-0.2.4
-rw-rw-r-- 1 free free 108472 Jan 4 2013 extundelete-0.2.4.tar.bz2
-rw-rw-r-- 1 free free 0 Sep 30 11:35 file
drwxrwxr-x 3 free free 4096 Sep 30 10:21 recovertest
-rw-rw-r-- 1 free free 18785 Dec 17 2006 Term-Animation-2.4.tar.gz
test rm file
###可以看到新增的内容
###然后删除文件
[free@hurd]$ rm file
[free@hurd]$ sudo lsof | grep cat
cat 23877 free cwd DIR 253,1 4096 131380 /home/free/tmp
cat 23877 free rtd DIR 253,1 4096 2 /
cat 23877 free txt REG 253,1 54080 658390 /usr/bin/cat
cat 23877 free mem REG 253,1 106070960 677352 /usr/lib/locale/locale-archive
cat 23877 free mem REG 253,1 2173512 657095 /usr/lib64/libc-2.17.so
cat 23877 free mem REG 253,1 164240 657088 /usr/lib64/ld-2.17.so
cat 23877 free 0u CHR 136,4 0t0 7 /dev/pts/4
cat 23877 free 1w REG 253,1 639 132886 /home/free/tmp/file (deleted)
cat 23877 free 2u CHR 136,4 0t0 7 /dev/pts/4
###看到(deleted)了,找到其pid,进入/proc/pid/fd/
[free@hurd]$ cd /proc/23877/fd
[free@hurd]$ ls -l
total 0
lrwx------ 1 free free 64 Sep 30 11:40 0 -> /dev/pts/4
l-wx------ 1 free free 64 Sep 30 11:40 1 -> /home/free/tmp/file (deleted)
lrwx------ 1 free free 64 Sep 30 11:40 2 -> /dev/pts/4
###文件描述符1就是被删除的文件
###将其复制即可
[free@hurd]$ cp 1 /tmp/file.rec
[free@hurd]$ cat /tmp/file.rec
total 240
drwxrwxr-x 2 free free 4096 Sep 13 11:20 asciiquarium_1.1
-rw-rw-r-- 1 free free 15436 Mar 9 2013 asciiquarium.tar.gz
drwxrwxr-x 5 free free 4096 Apr 25 16:36 bumblebee-Old-and-abbandoned
drwxrwxr-x 2 free free 4096 Apr 23 16:01 cmatrix-1.2a
-rw-r--r-- 1 root root 74376 Apr 23 15:35 cmatrix-1.2a.tar.gz
drwxr-xr-x 3 free free 4096 Sep 30 10:08 extundelete-0.2.4
-rw-rw-r-- 1 free free 108472 Jan 4 2013 extundelete-0.2.4.tar.bz2
-rw-rw-r-- 1 free free 0 Sep 30 11:35 file
drwxrwxr-x 3 free free 4096 Sep 30 10:21 recovertest
-rw-rw-r-- 1 free free 18785 Dec 17 2006 Term-Animation-2.4.tar.gz
test rm file
###恢复成功

  删除的文件正在没有被任何进程使用:extundelete

  恢复数据之前停止对当前分区做任何I/O操作,防止inode被覆盖

  在此只是进行简单的操作,并没有使用dd对当前分区进行备份和使用 umount 分区

  安装extundelete

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
[free@hurd]$ wget https://nchc.dl.sourceforge.net/project/extundelete/extundelete/0.2.4/extundelete-0.2.4.tar.bz2
[free@hurd]$ sudo yum -y install gcc-c++ bzip2
[free@hurd]$ sudo yum -y install e2fsprogs e2fsprogs-devel
[free@hurd]$ tar jxvf extundelete-0.2.4.tar.bz2
extundelete-0.2.4/
extundelete-0.2.4/acinclude.m4
extundelete-0.2.4/missing
extundelete-0.2.4/autogen.sh
extundelete-0.2.4/aclocal.m4
extundelete-0.2.4/configure
extundelete-0.2.4/LICENSE
extundelete-0.2.4/README
extundelete-0.2.4/install-sh
extundelete-0.2.4/config.h.in
extundelete-0.2.4/src/
extundelete-0.2.4/src/extundelete.cc
extundelete-0.2.4/src/block.h
extundelete-0.2.4/src/kernel-jbd.h
extundelete-0.2.4/src/insertionops.cc
extundelete-0.2.4/src/block.c
extundelete-0.2.4/src/cli.cc
extundelete-0.2.4/src/extundelete-priv.h
extundelete-0.2.4/src/extundelete.h
extundelete-0.2.4/src/jfs_compat.h
extundelete-0.2.4/src/Makefile.in
extundelete-0.2.4/src/Makefile.am
extundelete-0.2.4/configure.ac
extundelete-0.2.4/depcomp
extundelete-0.2.4/Makefile.in
extundelete-0.2.4/Makefile.am
[free@hurd]$ cd extundelete-0.2.4/
[free@hurd]$ ./configure
Configuring extundelete 0.2.4
Writing generated files to disk
[free@hurd]$ make
make -s all-recursive
Making all in src
extundelete.cc: In function ‘ext2_ino_t find_inode(ext2_filsys, ext2_filsys, ext2_inode*, std::string, int)’:
extundelete.cc:1272:29: warning: narrowing conversion of ‘search_flags’ from ‘int’ to ‘ext2_ino_t {aka unsigned int}’ inside { } [-Wnarrowing]
buf, match_name2, priv, 0};
^

[free@hurd]$ sudo make install
Making install in src
/usr/bin/install -c extundelete '/usr/local/bin'

###安装完成
###查看文件系统和挂载
[free@hurd]$ df -lh
Filesystem Type 1K-blocks Used Available Use% Mounted on
/dev/vda1 ext4 41151808 5292972 33745404 14% /
devtmpfs devtmpfs 497112 0 497112 0% /dev
tmpfs tmpfs 507704 0 507704 0% /dev/shm
tmpfs tmpfs 507704 428 507276 1% /run
tmpfs tmpfs 507704 0 507704 0% /sys/fs/cgroup
tmpfs tmpfs 101544 0 101544 0% /run/user/1001
###挂载在根目录下,文件系统是/dev/vda1
[free@hurd]$ mkdir recovertest
[free@hurd]$ cd recovertest
###创建目录以作恢复测试使用
###删除文件测试
[free@hurd]$ rm /home/free/file
###直接恢复所有文件
[free@hurd]$ sudo /usr/local/bin/extundelete /dev/vda1 --restore-all
NOTICE: Extended attributes are not restored.
WARNING: EXT3_FEATURE_INCOMPAT_RECOVER is set.
The partition should be unmounted to undelete any files without further data loss.
If the partition is not currently mounted, this message indicates
it was improperly unmounted, and you should run fsck before continuing.
If you decide to continue, extundelete may overwrite some of the deleted
files and make recovering those files impossible. You should unmount the
file system and check it with fsck before using extundelete.
Would you like to continue? (y/n)
y
Loading filesystem metadata ... 320 groups loaded.
Loading journal descriptors ... 29380 descriptors loaded.
Searching for recoverable inodes in directory / ...
22 recoverable inodes found.
Looking through the directory structure for deleted files ...
Unable to restore inode 266403 (var/lib/yum/transaction-done.2018-09-30.13:02.11): Space has been reallocated.
Unable to restore inode 266331 (var/lib/rsyslog/imjournal.state.tmp): Space has been reallocated.
Unable to restore inode 266320 (var/lib/ntp/drift.TEMP): Space has been reallocated.
Unable to restore inode 266319 (var/cache/yum/x86_64/7/base/repomd.xml.old.tmp): Space has been reallocated.
Unable to restore inode 266374 (var/cache/yum/x86_64/7/base/repomdGvOHrztmp.xml): Space has been reallocated.
Unable to restore inode 266325 (var/cache/yum/x86_64/7/epel/repomd.xml.old.tmp): Space has been reallocated.
Unable to restore inode 266326 (var/cache/yum/x86_64/7/extras/repomd.xml.old.tmp): Space has been reallocated.
Unable to restore inode 266328 (var/cache/yum/x86_64/7/updates/repomd.xml.old.tmp): Space has been reallocated.
Unable to restore inode 266327 (var/cache/yum/x86_64/7/gf/repomd.xml.old.tmp): Space has been reallocated.
8 recoverable inodes still lost.
Unable to restore inode 266323 (file.266323): Space has been reallocated.
Unable to restore inode 266324 (file.266324): Space has been reallocated.
Unable to restore inode 266334 (file.266334): Space has been reallocated.
Unable to restore inode 266371 (file.266371): Space has been reallocated.
Unable to restore inode 266372 (file.266372): Space has been reallocated.
Unable to restore inode 266386 (file.266386): Space has been reallocated.
Unable to restore inode 660679 (file.660679): Space has been reallocated.
Unable to restore inode 674046 (file.674046): Space has been reallocated.
[free@hurd]$ cd RECOVERED_FILES/
###恢复的文件都在 RECOVERED_FILES/目录下
[free@hurd]$ ls
home lost+found tmp var
[free@hurd]$ ls home/free
tmp
###此处可以看到我们恢复失败了
###此方法失败也很正常,因为各种 I/O可能会操作覆盖文件的inode信息
###但也是有可能成功恢复文件的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
###extundelete的用法
[free@hurd]$ extundelete --help
Usage: extundelete [options] [--] device-file
Options:
--version, -[vV] Print version and exit successfully.
--help, Print this help and exit successfully.
--superblock Print contents of superblock in addition to the rest.
If no action is specified then this option is implied.
--journal Show content of journal.
--after dtime Only process entries deleted on or after 'dtime'.
--before dtime Only process entries deleted before 'dtime'.
Actions:
--inode ino Show info on inode 'ino'.
--block blk Show info on block 'blk'.
--restore-inode ino[,ino,...]
Restore the file(s) with known inode number 'ino'.
The restored files are created in ./RECOVERED_FILES
with their inode number as extension (ie, file.12345).
--restore-file 'path' Will restore file 'path'. 'path' is relative to root
of the partition and does not start with a '/'
The restored file is created in the current
directory as 'RECOVERED_FILES/path'.
--restore-files 'path' Will restore files which are listed in the file 'path'.
Each filename should be in the same format as an option
to --restore-file, and there should be one per line.
--restore-directory 'path'
Will restore directory 'path'. 'path' is relative to the
root directory of the file system. The restored
directory is created in the output directory as 'path'.
--restore-all Attempts to restore everything.
-j journal Reads an external journal from the named file.
-b blocknumber Uses the backup superblock at blocknumber when opening
the file system.
-B blocksize Uses blocksize as the block size when opening the file
system. The number should be the number of bytes.
--log 0 Make the program silent.
--log filename Logs all messages to filename.
--log D1=0,D2=filename Custom control of log messages with comma-separated
Examples below: list of options. Dn must be one of info, warn, or
--log info,error error. Omission of the '=name' results in messages
--log warn=0 with the specified level to be logged to the console.
--log error=filename If the parameter is '=0', logging for the specified
level will be turned off. If the parameter is
'=filename', messages with that level will be written
to filename.
-o directory Save the recovered files to the named directory.
The restored files are created in a directory
named 'RECOVERED_FILES/' by default.
------ 本文结束 ------