|
|
背景见此帖http://www.linuxsir.cn/bbs/showt ... mp;page=1&pp=15
如果系统提供什么unmkswap之类的命令,我就不必在此婆婆妈妈了.可惜一直没找到,我才有机会在此唠叨.
本方法的适用前提大概有一下几点
1.mkswap前的分区的文件系统必须是ext2/ext3
2.尚未swapon该分区
3.必须有另一个linux系统(有root权限)或livecd
其实,修复的步骤很简单,直须要一两个命令就行了.但最重要的是知其所以然.
1.原理
先熟悉一下文件系统吧.
ext2/3最重要应该要算超级块了.超级块存储在文件系统的块1(从0开始编号)中,包含了编档系统配置的所有信息,而且用mount命令装载文件系统时,是要检查超级块的,如果不符合要求则会装载失败.
至于mkswap的实现可以在util-linux包的disk-utils目录下找到(开源的好处呵呵).
看一下代码可知mkswap调用init_signature_page()和write_signature()函数处理signature_page指针指向的内存区,然后把该内存区的内容通过write系统调用写回磁盘分区的前1536-4096(version 1)或512-4096(version 0)处, 而该处正是分区超级块的位置.
难怪mkswap后文件系统就mount不上去了
超级块都被覆盖了,难道只能束手待毙吗?
不,文件系统的设计者早就留了一手后招
看一下ext2fs的结构图:- ---------------------------------------
- |引导扇区 | 块组0 |...... | 块组N-1 | 块组N | <== 分区结构
- ---------------------------------------
- / \
- / \
- / \
- / \
- / \
- |----------------------------------------------------|
- | 超级块 | 组描 | 块位图 | 信息节点 | 信息节|数据 |
- | |述符 | | 位图 |点表 | | <== 块组结构
- |----------------------------------------------------|
复制代码 磁盘上块与块之间并不是孤立的,为了访问的效率,许多相邻的块又被组织成块组.基于超级块的重要性,它的备份副本存储在整个文件系统的块组中(啊,早就知道天无绝人之路^_^).我看的资料上说每个块组都会保留一份副本,但以我的实践来看,并不全然,也许是为了节省空间吧.
- # mke2fs -n /dev/hda5
- mke2fs 1.35 (28-Feb-2004)
- Filesystem label=
- OS type: Linux
- Block size=4096 (log=2)
- Fragment size=4096 (log=2)
- 647680 inodes, 1293224 blocks
- 64661 blocks (5.00%) reserved for the super user
- First data block=0
- 40 block groups
- 32768 blocks per group, 32768 fragments per group
- 16192 inodes per group
- Superblock backups stored on blocks:
- 32768, 98304, 163840, 229376, 294912, 819200, 884736
复制代码
注意,-n使mke2fs不真正格式化分区,而只打印分区后的信息.
留意一下最后两行以及每个块组中包含的块的数目,就可算出到底哪几个块组中存在备份的超级块了
其次,分区中超级块的副本数目也是和块大小息息相关的- # mke2fs -n /dev/hda5 -b 1024
- mke2fs 1.35 (28-Feb-2004)
- Filesystem label=
- OS type: Linux
- Block size=1024 (log=0)
- Fragment size=1024 (log=0)
- 647168 inodes, 5172896 blocks
- 258644 blocks (5.00%) reserved for the super user
- First data block=1
- 632 block groups
- 8192 blocks per group, 8192 fragments per group
- 1024 inodes per group
- Superblock backups stored on blocks:
- 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409, 663553,
- 1024001, 1990657, 2809857, 5120001
复制代码 可以看出,前者的块大小是4k,而后者是1k,块越小,每个块组包含的块数也会减少,超级块的副本数会增加.
虽然文件系统中超级块存在不止一份,但在装载文件系统时,通常只读取块组0中的超级块.如果超级块损坏,则装载出错,并且提示运行e2fsck.
e2fsck默认也是读取块组0中的超级块,但这一行为会受-b参数的影响.
- # mount /dev/hda5 /mnt
- /dev/hda9 looks like swapspace - not mounted
- mount: you must specify the filesystem type
- # e2fsck /dev/hda5
- e2fsck 1.35 (28-Feb-2004)
- e2fsck: Bad magic number in super-block while trying to open /dev/hda5
- The superblock could not be read or does not describe a correct ext2
- filesystem. If the device is valid and it really contains an ext2
- filesystem (and not swap or ufs or something else), then the superblock
- is corrupt, and you might try running e2fsck with an alternate superblock:
- e2fsck -b 8193 <device>
-
- # e2fsck /dev/hda5 -b 8139 [color=DarkGreen]<==看到了吧,8139块上并不一定有超级块的备份[/color]
- e2fsck 1.35 (28-Feb-2004)
- e2fsck: Bad magic number in super-block while trying to open /dev/hda5
- The superblock could not be read or does not describe a correct ext2
- filesystem. If the device is valid and it really contains an ext2
- filesystem (and not swap or ufs or something else), then the superblock
- is corrupt, and you might try running e2fsck with an alternate superblock:
- e2fsck -b 8193 <device>
复制代码 由此可知8193块中并不一定有超级块的副本,这是由块组中块的数目决定的,而归根结底又取决于块的大小.如果你创建分区时用了默认的块大小,则可用mke2fs -n命令打印出超级块副本所在块的块号,然后以所得块号为参数,运行e2fsck,系统会自动修复块组0中的超级块. 修复完后就可以成功挂载了.
2.修复
步骤很简单
因为我创建分区时用的是默认参数,现在只要用mke2fs -n找出超级块备份的位置,然后用e2fsck修复就行了
- # mke2fs -n /dev/hda5
- mke2fs 1.35 (28-Feb-2004)
- Filesystem label=
- OS type: Linux
- Block size=4096 (log=2)
- Fragment size=4096 (log=2)
- 611648 inodes, 1222940 blocks
- 61147 blocks (5.00%) reserved for the super user
- First data block=0
- 38 block groups
- 32768 blocks per group, 32768 fragments per group
- 16096 inodes per group
- Superblock backups stored on blocks:
- 32768, 98304, 163840, 229376, 294912, 819200, 884736
- #e2fsck -b 32768 /dev/hda5
复制代码 接下来只要一路按y,系统就会自动把超级块修好
3.未竞之业
理论上,了解了e2fsck的工作原理以及super-block的位置,应该可以自行编制程序备份和恢复super-block. 如果有时间或许会尝试一下.
还有另一个取巧想法是用dd把引导记录和块组0的super-block一起备份起来, 然后直接用dd恢复, 不知可行否
这些留待以后再说吧
我要说的差不多就这么多了,小弟浅陋,谬误之处请大虾们斧正
p.s. 感谢所有帮助过我的xdjm们 |
|