MIT6.828 HW11: crash

来源:互联网 发布:java逻辑思维测试题 编辑:程序博客网 时间:2024/06/16 09:24

  在这次作业中,我们将探索xv6的log功能。主要就是创建1个crash,然后观察recover的过程。
  xv6的log重点是将文件系统所有的磁盘更新操作原子化,比如在创建1个文件时涉及到在目录中添加新入口,并标记新文件的inode为使用中。如果没有log的话,在两次操作之间发送1个crash会导致重启后文件系统处于不正确状态。
  第1步修改log.c如下:

#include "mmu.h"#include "proc.h"voidcommit(void){  if (log.lh.n > 0) {    write_log()    write_head();    if(proc->pid > 1)       // AAA      log.lh.block[0] = 0; // BBB    install_trans();    if(proc->pid > 1)       // AAA      panic("commit mimicking crash"); // CCC    log.lh.n = 0;     write_head();  }}

  在创建文件时log的第1个扇区应该存的是修改后的inode号(即type不为0,否则会标示这个块未分配),而BBB行导致log的第1个扇区写到磁盘上的扇区0。CCC行迫使发生1次crash。AAA行保证init进程不会做这一愚蠢的操作,因为它要为shell创建文件。
  第2步修改recover_from_log函数如下:

static voidrecover_from_log(void){  read_head();        cprintf("recovery: n=%d but ignoring\n", log.lh.n);  // install_trans();  log.lh.n = 0;  // write_head();}

  这里的修改会阻止log的recovery。
  然后进行测试,运行xv6,并在shell里创建1个文件,将发送panic:
这里写图片描述
  重新运行xc6,查看文件的内容,也会发生panic:
这里写图片描述
  原因是文件的修改后的inode,并被写入磁盘log,但是在commit时并没有被写入原来inode对应的块,内容被也如对应的块,并且重启时没有修复。
  恢复recover_from_log函数,将会看到文件,但是内容为空:
  这里写图片描述
  由于没有仔细研究xv6文件系统的源码,不是很清楚这一步的原因。原先认为在commit时修改了内存中log_head的内容(使log的第1个扇区指向扇区0),导致磁盘上的log_head与内存中的不一致,但是内容应该被写入对应的块,系统在重启时检查到log中有完整的事务,则进行恢复,文件修改后的inode被写入对应的块,会再一次将内容写入对应的块(该块已经被占用??),应该会有内容的。。。。
  要解决的问题是在在commit期间将缓存中修改的块写入log,在之后从log中读取到缓存,再写入对应的块,这中间其实缓存是没变化的,所以可以取消读log的步骤,直接将缓存写入对应的块即可。
  

0 0
原创粉丝点击