荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Lg (创造人生的传奇), 信区: Linux
标  题: SCO UNIX文件卷结构分析及误删文件的恢复(2)[Fwd]
发信站: BBS 荔园晨风站 (Sun Jan 24 19:27:26 1999), 站内信件

【 以下文字转载自 Lg 的信箱 】
【 原文由 liugang.bbs@melon.gznet.edu.cn 所发表 】
发信人: yeal (?????????), 信区: Unix
标  题: SCO UNIX文件卷结构分析及误删文件的恢复(2)[Fwd]
发信站: 华南网木棉站 (Sun Jan 24 12:14:47 1999), 转信

二、误删文件的恢复
    在UNIX系统下, 常常发生误删文件的情况, 造成意外损失。其实, 只要在文件
恢复之前不向系统申请分配磁盘块和写数据, 误删的文件是完全可以恢复的。因为
删除一个文件, 只是释放了该文件所占用的i 节点和磁盘块资源, 而记录文件数据
的磁盘块的内容还未被清除。只要找到这些磁盘块, 重建文件的i 节点, 便可恢复
误删的文件了。

1.SCO UNIX分配磁盘块算法
    由于一个磁盘块的大小为1024字节, 所以一个位图块可以管理0x400*8=0x2000
个磁盘块。那么, 下一个位图块的块号就是0x61d+0x2000=0x261d。 这与位图索引
块中的数据是相符的。 那么, 位图块0x61d管理着块号为0x61d-0x261c的磁盘块。
由以上数据可见, 在这个位图块中, 第一个被使用的磁盘块块号是0x61d,  即位图
块本身。第一个空闲块块号由0x187401处字节0x1c的第2位指示, 是0x627。由于该
位图块是文件卷中的第一个位图块,  所以0x627号磁盘块也是文件卷中的第一个空
闲块。当我们向系统申请磁盘块时, 系统通过超级块、位图索引块、位图块来寻找
那些标志位为1的块, 然后将相应的标置位置0。当释放一个磁盘块时, 系统就将相
应的标志位置1。 现在, 我们就可以判断出文件卷中的每一个磁盘块是否被使用了
。但是仅赁这些还不能完全恢复误删的文件, 我们还得了解SCO UNIX分配磁盘块的
算法。为了使一个文件所占用的磁盘块相对集中, SCO UNIX是按照特定的算法来选
择空闲块分配给文件的。假设某文件所占用的最后一个磁盘块的块号为m,  现在要
再分配一磁盘块给该文件, 若该文件是新文件则m=0。
    现在我们在文件卷/dev/user下创建一个新文件1.tmp, 根据以上磁盘块分配算
法, 可以推测它将占据磁盘块0x627, 那么0x187401处的字节的第2位将置0,  变为
0x18。
    # cat> 1.tmp
    1234567 ^c
    # hd -abx -s 0x187400 -n 0x400 /dev/user
    187400 00 18 00 00 00 00 20 00 80 ff 00 00 07 9c ff ff
    187410 f8 ff 80 ff ff ff ff ff ff ff ff ff ff ff fe ff
    187420 00 00 ff ff 00 00 00 00 00 00 00 00 00 00 ff ff
    187430 ff ff bf ff 00 00 00 00 00 00 f8 ff ff ff ff ff
    187440 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    *
    187800
    磁盘块0x627的内容如下:
    # hd -s 0x189c00 -n 0x400 /dev/user
    189c00 31 32 33 34 35 36 37 1a 00 00 00 00 00 00 00 00 1234567……
    189c10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ……………
    *
    18a000
    我们再把1.tmp删除, 释放磁盘块0x62f, 则0x187401处字节又成为0x1c。
    # rm 1.tmp
    # hd -abx -s 0x187400 -n 0x400 /dev/user
    187400 00 1c 00 00 00 00 20 00 80 ff 00 00 07 9c ff ff
    187410 f8 ff 80 ff ff ff ff ff ff ff ff ff ff ff fe ff
    187420 00 00 ff ff 00 00 00 00 00 00 00 00 00 00 ff ff
    187430 ff ff bf ff 00 00 00 00 00 00 f8 ff ff ff ff ff
    187440 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    *
    187800
    磁盘块0x627的内容没有丢失:
    # hd -s 0x189c00 -n 0x400 /dev/user
    189c00 31 32 33 34 35 36 37 1a 00 00 00 00 00 00 00 00 1234567……
    189c10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ……………
    *
    18a000
    由于系统每次分配磁盘块给文件时, 都遵循这一算法, 所以当文件被删除后,
我们同样可以按照这一算法推算出原本属于该文件的磁盘块号, 这样我们就能完全
恢复误删的文件了。

2.误删文件的恢复
    根据以上SCO UNIX文件卷结构和磁盘块管理的特点, 笔者编制了一恢复误删文
件的程序并投入使用, 挽救了许多数据。限于篇幅, 这里只给出软件的构思和磁盘
块分配算法函数getNextFreeBlock(long BN)的源代码。 软件构思是这样的, 首先
在被误删文件的文件卷下, 创建一新文件, 不向该文件写任何数据即关闭它, 然后
调用系统函数stat (char* path, structstat* buf) 得到该文件的i节点, 再根据
磁盘块分配算法在文件卷上寻找将分配的空闲块, 将块号填入i 节点的磁盘块地址
表并把相应位图块中的标志位置0; 由于SCO UNIX 把已分配磁盘块中未被使用的字
节全部署0, 所以我们只要找到一个尾部字节全部为0的磁盘块, 就可以认为它是文
件的最后一个磁盘块了, 由这些磁盘块的数量和最后一个磁盘块中有效字节的长度
, 可以算出文件的字节长度, 将此长度值也填入i节点, 再把该i节点写回文件卷即
可。i节点的数据结构在<sys/ino.h>文件中, 如下:
    struct dinode
    {
    ushort dimode;
    short dinlink;
    ushort diuid;
    ushort digid;
    off-t disize;
    char diaddr[40]; /*磁盘块地址表*/
    .
    .
    .
    };
    对于大文件的一次间址块、二次间址块和三次间址块的块号, 只要稍做处理即
可找到, 这里不再赘述, 留给读者思考。
    函数getNextFreeBlock (long BN)的返回值是文件卷中下一个将要分配的空闲
块的块号, 失败时返回-1, 表明已无空闲块可分配。输入参数是起始块号, 若是分
配给文件的第一块, 则BN为0。 源代码如下, 其中BBIT存放的是文件卷位图索引块
的数据。函数readABlock (longBN, void* buf)的功能是将文件卷的BN号磁盘块的
内容读入缓冲区buf。
    extern long BBIT[0x100];
    long getNextFreeBlock(long BN)
    {
    long lg;
    ushort uBuf[0x200];
    int i, k, m, n;
    if (BN>superBlock, s-fsize)
    return -1;
    sync();
    for (k=BN<BBIT[0]?0:(BN-BBIT[0])/(BS*8);BIT[k]!=0;k++)
    {
    readABlock(BBIT[k], uBuf);
    for (m=(BBIT[k]<BN)?((BN-BBIT[k])/0x10):0; m<(BS/2);m++)
    {
    n=(BBIT[k]+m*0x10)>BN?0:(BN-BBIT[k]-m*0x10+1);
    while (n<0x10&&(uBuf[m]&(1<<n))==0)
    ++n;
    if (n!=0x10)
    {
    lg=BBIT[k]+m*0x10+n;
    i=0x10-(BN-BBIT[0])%0x10;
    if (BN==0||lg<BN+i)||(BN+1)==lg||
    (((lg-BBIT[0])%0x10)=0&&uBuf[m]==0xffff))
    return lg;
    }
    }
    }
    return -1;
    }
    注意, 在恢复文件之后, 为了使系统的内存超级块和文件卷上的超级块保持一
致, 对于子文件卷和根文件卷, 应分别执行以下命令:
    # fsck -f y /dev/user
    # fsck -f y -b /dev/root
    显然, 掌握了SCO UNIX文件卷的结构特点和磁盘块的管理方式后, 我们还能进
行更多的应用。比如磁盘块使用情况图、文件磁盘块规整等等。由于当前涉及 SCO
UNIX内核设计方面的资料太少, 笔者对它也只有一个初步地探索。在这里, 笔者殷
切地希望此篇拙作还能起一抛砖引玉之用。

--------------------------------------------------------------------------------

--
※ 来源:.华南网木棉站 bbs.gznet.edu.cn.[FROM: 202.38.240.203]
--
※ 转寄:.华南网木棉站 bbs.gznet.edu.cn.[FROM: 202.96.144.222]
--
※ 转载:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: 192.168.0.1]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店