首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

如何恢复 Linux 上删除的文件-特殊文件的恢复(4)

如何恢复 Linux 上删除的文件-特殊文件的恢复(4)

符号链接我们知道,在 ext2 文件系统中,链接可以分为两种:硬链接和符号链接(或称为软链接)。实际上,目录中的每个文件名都对应一个硬链接。硬链接的出现是为了解决使用不同的文件名来引用同一个文件的问题。如果没有硬链接,只能通过给现有文件新建一份拷贝才能通过另外一个名字来引用这个文件,这样做的问题是在文件内容发生变化的情况下,势必会造成引用这些文件的进程所访问到的数据不一致的情况出现。而虽然每个硬链接在文件目录项中都是作为一个单独的项存在的,但是其索引节点号完全相同,这就是说它们引用的是同一个索引节点,因此对应的文件数据也完全相同。下面让我们通过一个例子来验证一下:
清单21.硬链接采用相同的索引节点号
1
2
3
4
5
6
7
8
9
10
# ln testfile.10M hardlink.10M

# ls -li
total 20592
     12 -rwxr-xr-x 1 root root     1406 Nov 29 19:19 createfile.sh
1205313 drwxr-xr-x 2 root root     4096 Nov 29 19:29 dir1
     14 -rw-r--r-- 2 root root 10485760 Nov 29 19:21 hardlink.10M
     11 drwx------ 2 root root    16384 Nov 29 19:19 lost+found
     14 -rw-r--r-- 2 root root 10485760 Nov 29 19:21 testfile.10M
     13 -rw-r--r-- 1 root root    35840 Nov 29 19:20 testfile.35K




我们可以看到,使用 ln 建立的硬链接 hardlink.10M 的索引节点号也是 14,这与 testfile.10M 的索引节点号完全相同,因此通过这两个名字所访问到的数据是完全一致的。
因此,硬链接的恢复与普通文件的恢复非常类似,唯一的区别在于如果索引节点指向的数据已经恢复出来了,现在就无需再恢复数据了,只需要恢复其父目录中的对应目录项即可,这可以通过 debugfs 的 link 命令实现。
硬件链接的出现虽然可以满足通过不同名字来引用相同文件的需要,但是也存在一些问题,包括:
  • 不能对目录建立硬链接,否则就会引起循环引用的问题,从而导致最终正常路径的无法访问。
  • 不能建立跨文件系统的硬链接,这是由于每个文件系统中的索引节点号都是单独进行编号的,跨文件系统就会导致索引节点号变得非常混乱。而这在现代 Linux/Unix 操作系统上恰恰是无法接受的,因为每个文件系统中都可能会有很多挂载点来挂载不同的文件系统。
为了解决上面的问题,符号链接就应运而生了。符号链接与硬链接的区别在于它要占用一个单独的索引节点来存储相关数据,但却并不存储链接指向的文件的数据,而是存储链接的路径名:如果这个路径名小于60个字符,就其存储在符号链接索引节点的 i_block 域中;如果超过 60 个字符,就使用一个单独的数据块来存储。下面让我们来看一个例子:
清单22. 符号链接采用不同的索引节点号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# ln -s testfile.10M softlink.10M

# ls -li
total 20596
     12 -rwxr-xr-x 1 root root     1406 Nov 29 19:19 createfile.sh
1205313 drwxr-xr-x 2 root root     4096 Nov 29 19:29 dir1
     14 -rw-r--r-- 2 root root 10485760 Nov 29 19:21 hardlink.10M
     11 drwx------ 2 root root    16384 Nov 29 19:19 lost+found
     15 lrwxrwxrwx 1 root root       12 Nov 29 19:41 softlink.10M -> testfile.10M
     14 -rw-r--r-- 2 root root 10485760 Nov 29 19:21 testfile.10M
     13 -rw-r--r-- 1 root root    35840 Nov 29 19:20 testfile.35K

# echo "stat <15>" | debugfs /dev/sdb6
debugfs 1.39 (29-May-2006)
debugfs:  Inode: 15   Type: symlink    Mode:  0777   Flags: 0x0   Generation: 2344716327
User:     0   Group:     0   Size: 12
File ACL: 1542    Directory ACL: 0
Links: 1   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x474ea56f -- Thu Nov 29 19:41:35 2007
atime: 0x474ea571 -- Thu Nov 29 19:41:37 2007
mtime: 0x474ea56f -- Thu Nov 29 19:41:35 2007
Fast_link_dest: testfile.10M




ln 命令的 –s 参数就用来指定创建一个符号链接。从结果中可以看出,新创建的符号链接使用的索引节点号是 15,索引节点中的 i_block 中存储的值就是这个符号链接所指向的目标:testfile.10M(Fast_link_dest 的值)。
现在再来看一个指向长路径的符号链接的例子:
清单23. 长名符号链接
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
# touch abcdwfghijklmnopqrstuvwxyz0123456789abcdwfghijklmnopqrstuvwxyz0123456789.sh

# ln -s abcdwfghijklmnopqrstuvwxyz0123456789abcdwfghijklmnopqrstuvwxyz0123456789.sh \
longsoftlink.sh

# ls -li
total 20608
     16 -rw-r--r-- 1 root root        0 Nov 29 19:52 \
     abcdwfghijklmnopqrstuvwxyz0123456789abcdwfghijklmnopqrstuvwxyz0123456789.sh
     12 -rwxr-xr-x 1 root root     1406 Nov 29 19:19 createfile.sh
1205313 drwxr-xr-x 2 root root     4096 Nov 29 19:29 dir1
     14 -rw-r--r-- 2 root root 10485760 Nov 29 19:21 hardlink.10M
     17 lrwxrwxrwx 1 root root       75 Nov 29 19:53 longsoftlink.sh -> \
     abcdwfghijklmnopqrstuvwxyz0123456789abcdwfghijklmnopqrstuvwxyz0123456789.sh
     11 drwx------ 2 root root    16384 Nov 29 19:19 lost+found
     15 lrwxrwxrwx 1 root root       12 Nov 29 19:41 softlink.10M -> testfile.10M
     14 -rw-r--r-- 2 root root 10485760 Nov 29 19:21 testfile.10M
     13 -rw-r--r-- 1 root root    35840 Nov 29 19:20 testfile.35K

# echo "stat <17>" | debugfs /dev/sdb6
debugfs 1.39 (29-May-2006)
debugfs:  Inode: 17   Type: symlink    Mode:  0777   Flags: 0x0   Generation: 744523175
User:     0   Group:     0   Size: 75
File ACL: 1542    Directory ACL: 0
Links: 1   Blockcount: 16
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x474ea824 -- Thu Nov 29 19:53:08 2007
atime: 0x474ea826 -- Thu Nov 29 19:53:10 2007
mtime: 0x474ea824 -- Thu Nov 29 19:53:08 2007
BLOCKS0):6144TOTAL: 1




此处我们创建了一个名字长度为 75 个字符的文件,并建立一个符号链接(其索引节点号是 17)指向这个文件。由于链接指向的位置路径名超过了 60 个字符,因此还需要使用一个数据块(6144)来存储这个路径名。手工恢复方法如下:
清单24. 恢复长名符号链接
1
2
3
4
5
6
7
8
9
# dd if=/dev/sdb6 of=longsoftlink.6144 bs=4096 count=1 skip=6144

# xxd longsoftlink.6144 | more
0000000: 6162 6364 7766 6768 696a 6b6c 6d6e 6f70  abcdwfghijklmnop
0000010: 7172 7374 7576 7778 797a 3031 3233 3435  qrstuvwxyz012345
0000020: 3637 3839 6162 6364 7766 6768 696a 6b6c  6789abcdwfghijkl
0000030: 6d6e 6f70 7172 7374 7576 7778 797a 3031  mnopqrstuvwxyz01
0000040: 3233 3435 3637 3839 2e73 6800 0000 0000  23456789.sh.....
0000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................




这样符号链接的数据就可以完整地恢复出来了。
需要注意的是,为了保证整个文件系统的完整性,在恢复硬链接时,还需要修改链接指向的索引节点的引用计数值,这可以使用 e2fsck 帮助完成,详细步骤请参看上一节目录的恢复。
小结本文介绍了 ext2 文件系统中比较特殊的一些文件的存储和恢复机制,包括文件洞、目录和链接,并介绍了如何结合使用 debugfs 和 e2fsck 等工具完整恢复 ext2 文件系统的方法。在本系列的后续文章中,我们将介绍几个可以自动恢复 ext2 文件系统中已删除文件的工具,以及对 ext2 文件系统的后继者 ext3 和 ext4 文件系统的一些考虑。
返回列表