BBS水木清华站∶精华区

发信人: seis (矛), 信区: Linux        
标  题: UNIX系统被删文件的恢复策略 
发信站: BBS 水木清华站 (Sat Jan 20 11:08:39 2001) 
 
 
 
 
             作者: 李贵林 陈朝晖  
 
             与DOS/Windows不同,UNIX文件被删除后很难恢复,这是由UNIX独特 
             的文件系统结构决定的。UNIX文件目录不像DOS/Windows那样,文 
             件即使被删除之后仍保存有完整的文件名、文件长度、始簇号(即 
             文件占有的第一个磁盘块号)等重要信息;相反,它的文件信息全部 
             依靠一种被称为i节点的数据结构来描述,而i节点在相应文件被删 
             除之后即被清空,因此,要想直接恢复被删除的文件内容几乎是 
             不可能的,必须另辟蹊径。本文结合实际,讨论几种文件恢复策 
             略及其关键步骤的具体实现。  
 
               一、UNIX文件系统结构  
 
               我们知道,UNIX是以文件卷作为其文件系统存储格式的,而 
             不同的UNIX系统,文件卷格式是有差异的,甚至即使是同一UNIX 
             操作系统的不同版本,其文件系统未必完全相同,例如:SCO UNIX 
             4.1版与5.0版文件系统结构就有明显差异,但只要是UNIX系统,其 
             文件卷的基本结构是一致的。分析如下:  
 
               不管是什么UNIX系统,不管什么版本,其文件卷至少包括引 
             导块、超级块、i节点表、数据区等几个部分。除此之外,不同 
             UNIX版本可能还有不同的差异。例如:SCO UNIX系统的位图索引块 
             和位图块AIX的逻辑卷表等。这些系统的特殊性不影响下文的恢复 
             策略,故这里不作讨论,仅介绍标准UNIX文件卷结构。  
 
               1. 引导块  
 
               位于文件卷最开始的第一扇区,这512字节是文件系统的引导 
             代码,为根文件系统所特有,其他文件系统这512字节为空。  
 
               2. 超级块  
 
               位于文件系统第二扇区,紧跟引导块之后,用于描述本文件 
             系统的结构。如i节点长度、文件系统大小等,其结构存放于 
             /usr/include/sys/filsys.h中,其结构如下:  
 
               struct filsys  
 
               {  
 
               ushort s_isize; /*磁盘索引节点区所占用的数据块数*/  
 
               daddr_t s_fsize; /*整个文件系统的数据块数*/  
 
               short s_nfree; /*在空闲块登录表中当前登记的空闲块数目*/  
 
               daddr_t s_free[NICFREE]; /*空闲块登记表*/  
 
               short s_ninode; /*空闲索引节点数*/  
 
               ino_t s_inode[NICINOD]; /*空闲节点登记表*/  
 
               char s_flock; /*加锁标志位*/  
 
               char s_ilock; /*节点加锁标志位*/  
 
               char s_fmod; /*超级块修改标志*/  
 
               char s_ronly; /*文件系统只读标志*/  
 
               time_t s_time; /*超级块上次修改的时间*/  
 
               short s_dinfo[4]; /*设备信息*/  
 
               daddr_t s_tfree; /*空闲块总数*/  
 
               ino_t s_tinode; /*空闲节点总数*/  
 
               char s_fname[6]; /*文件系统名称*/  
 
               char s_fpack[6];  
 
               long s_fill[13]; /*填空位*/  
 
               long s_magic; /*指示文件系统的幻数*/  
 
               long s_type; /*新文件系统类型*/  
 
               };  
 
               3. i节点表  
 
               i节点表存放在超级块之后,其长度是由超级块中的s_isize字段 
             决定的,其作用是用来描述文件的属性、长度、属主、属组、数 
             据块表等,其数据结构在/usr/include/sys/ino.h中,如下:  
 
               struct dinode  
 
               {  
 
               ushort di_mode;  
 
               short di_nlink;  
 
               ushort di_uid;  
 
               ushort di_gid;  
 
               off_t di_size;  
 
               char di_addr[40];  
 
               time_t di_atime;  
 
               time_t di_mtime;  
 
               time_t di_ctime;  
 
               };  
 
               4. 目录结构  
 
               UNIX所有文件均存放于目录中,目录本身也是一个文件。目 
             录存放文件的机制如下:首先,目录文件本身也象普通文件一 
             样,占用一个索引节点,其次,由这个索引节点得到目录内容的 
             存放位置,再次,从其内容中取出一个个的文件名和它对应的节 
             点号,从而访问一个文件。目录结构如下:  
 
               索引节点号(2字节) .(本目录)(14字节)  
 
               索引节点号(2字节) ..(父目录)(14字节)  
 
               索引节点号(2字节) 文件名(14字节)  
 
               索引节点号(2字节) 文件名(14字节)  
 
               索引节点号(2字节) 文件名(14字节)  
 
               由上可知文件名是依靠目录来描述的,文件的内容和其他信 
             息则由索引节点来描述。  
 
               二、文件的删除过程  
 
               UNIX下删除一个文件的过程很简单,那就是释放索引节点表 
             和文件占用的数据块,清空文件占用的索引节点,但不清除文件 
             内容。但删除文件与删除目录的处理不尽相同,不同命令删除文 
             件的过程也不相同。  
 
               1. 删除一个文件  
 
               UNIX 删除一个文件的具体步骤是:根据文件i节点的地址表逐 
             一释放文件占用的磁盘数据块,然后清空相应的节点,最后释放i 
             节点。  
 
               2. 删除一个目录  
 
               删除一个目录的过程:首先逐一删除目录里的所有文件,然 
             后删除目录。目录本身也是一个文件,故删除方法与删除文件一 
             致。  
 
               3. 几种不同的删除命令  
 
               .rm 命令  
 
               一般删除命令,删除过程上述已说明。  
 
               .mv命令  
 
               格式:mv 文件1 文件2  
 
               处理过程是将文件2的数据块释放,然后将文件1的名称改为 
             文件2,再释放文件2所占的i节点。  
 
               . > 命令  
 
               格式:>文件名  
 
               若产生一个新文件,>命令仅仅申请一个i节点,而不写入任何 
             文件内容;若清空一个已经存在的文件,则释放文件所占的数据 
             块,并将文件长度清零。  
 
               三、被删文件的恢复策略  
 
               要恢复被删除的文件,只能根据删除后留下的东西去做文 
             章。文件被删除后留下了什么呢?由上述分析可知:其一、留下 
             了文件的内容;其二、留下了“现场”。文件的恢复策略只能从 
             这两个方面来分析。以下谈几种恢复策略。  
 
               1.根据磁盘现场进行恢复  
 
               如果文件被删除,现场未被破坏(即文件被删除后硬盘未发生 
             过写操作),而且假定只删除了一个文件,那么可根据系统的分配 
             算法进行恢复。因为系统建立一个文件时,必定根据某一特定的 
             分配算法决定文件占用的数据块位置。而当该文件被删除后,它 
             所占用的数据块被释放,又回到系统的分配表中,这时如果重新 
             建立一个文件,系统根据原来的分配算法分配出的数据块必定跟 
             该文件原来占用的数据块一致,而且我们知道,UNIX文件最后一 
             数据块尾部多出的字节是全部置0的,据此只要调用系统的数据分 
             配算法,在系统中一块块的申请数据块,因为UNIX文件最后一个 
             数据块尾部多出的字节全部为0,所以,只要发现一个分配出的数 
             据块中尾部全为0,即可认为文件结束,由此可确定文件长度和内 
             容,进而实现恢复。方法如下:  
 
               ⑴申请一个索引节点,即向系统申请创建一个新文件名而不 
             写入任何内容。如:#>/tmp/xx  
 
               ⑵调用系统分配数据块算法getnextfreeblock()得到一个数据块 
             号,记入某一地址表变量中。  
 
               ⑶读出这个数据块,判断其尾部是否全部连续为0,若不是, 
             则回到(2),若是,则进行(4)。  
 
               ⑷首先用系统函数fstat得到/tmp/xx的i节点号,然后将(2)步所得 
             的地址表写入索引节点的地址表中(注意间址问题),并根据数据块 
             个数和最后一块中有效数据长度计算出文件大小,写入i节点的 
             di_size字段。  
 
               ⑸回写系统的索引节点表即可。  
 
               需要说明的是,第一,系统分配数据块的算法因不同的UNIX 
             版本而不同;第二,有的UNIX如SCO UNIX 5.0版,其空闲数据块的 
             分配和回收是使用一种动态链表的数据结构来实现的,它们的文 
             件恢复更加容易,只要在空闲链表中的表尾去寻找即可,笔者另 
             行描述。  
 
               2. 根据内容恢复。  
 
               若现场已被破坏,即硬盘发生过写操作,那么只好根据内容 
             来恢复。而且,由于UNIX是一个多进程、多用户系统,它每一次 
             开关机或硬件、通讯故障等都会记录系统日志、.sh_history等,硬盘 
             现场被破坏可能性极大。因此讨论按内容恢复的方法具有更大的 
             实用价值。笔者经过实际探索得出下列四种恢复策略供参考。  
 
               ⑴关键字搜索法  
 
               如果知道被删除的文件内容中若干字节的内容,而且该文件 
             长度又不超过一个磁盘块,那么可以在整个文件系统中搜索这一 
             字节串,得出一个文件所在的数据块,将它们的块号填入一个i节 
             点,即可恢复一个文件,搜索文件系统的算法很简单,说明如 
             下:  
 
               a. #df -k 确定文件系统的设备文件名(如/dev/root)  
 
               b.用下述函数搜索,若成功,返回数据块号,反之返回-1。其 
             中fsname是文件系统的设备名,如/dev/root,comp()参数是实现搜索条 
             件的函数。  
 
               long searchfs(char *fsname , int comp())  
 
               {  
 
               FILE *fp;  
 
               char buf[1024];  
 
               long i=0;  
 
               fp=fopen(fsname,"r");  
 
               while (!feof(fp))  
 
               {  
 
               fread(buf,1024,1,fp);  
 
               if (comp()) /* 检查是否符合搜索条件 */  
 
               return i; /* 若成功返回块号 */  
 
               i++;  
 
               }  
 
               fclose(fp);  
 
               return -1; /* 未找到符合条件的块,返回-1*/  
 
               }  
 
               ⑵精确长度搜索法  
 
               如果知道被删除文件的精确长度(字节数),那么可根据一个数 
             据块的大小,计算出文件的最后一个数据块中数据的精确长度, 
             该数据块中其他字节必然是全0。根据这一条件,通过搜索整个文 
             件系统,找出其中符合条件的数据块,若出现多个块符合要求, 
             则还需要根据其他条件区分。但不管怎样,根据精确长度分析也 
             是恢复数据的一个策略。  
 
               ⑶内容关联法  
 
               如果知道文件内容中存在某种可实现的关联,例如文件的校 
             验和,或者文件内容的某种上下文关系,那么也可通过搜索整个 
             文件系统,通过反复尝试寻找符合关联条件的磁盘数据块,进而 
             恢复一个文件。  
 
               ⑷环境比较法  
 
               如果知道删除文件所在的文件系统的安装过程,那么,另行 
             找一台完全相的机器,按原来完全相同的步骤安装相同版本的 
             UNIX和相应的其他软件,可以想象,新的机器环境会与原来的环 
             境基本相同,比较两个机器上相同文件系统的内容,可以推断出 
             被删除文件的大致位置,至少可以大大减少查找的范围,一旦查 
             找的范围足够小时,可以用逐个观察和尝试的方法结合其他条件 
             恢复数据,降低恢复的难度,增加恢复的可靠性。  
 
               UNIX系统下文件系统恢复的具体实现依赖于不同操作系统和 
             不同版本的具体文件系统结构和磁盘块分配算法。本文试图总结 
             出一种一般性的思路和策略,限于篇幅,不能详细讨论它们的具 
             体实现过程。  
 
-- 
 
※ 来源:·BBS 水木清华站 smth.org·[FROM: 159.226.41.166] 

BBS水木清华站∶精华区