MIT6.828 HW11: crash
阿新 • • 發佈:2019-01-01
在這次作業中,我們將探索xv6的log功能。主要就是建立1個crash,然後觀察recover的過程。
xv6的log重點是將檔案系統所有的磁碟更新操作原子化,比如在建立1個檔案時涉及到在目錄中新增新入口,並標記新檔案的inode為使用中。如果沒有log的話,在兩次操作之間傳送1個crash會導致重啟後文件系統處於不正確狀態。
第1步修改log.c如下:
#include "mmu.h"
#include "proc.h"
void
commit(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 void
recover_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的步驟,直接將快取寫入對應的塊即可。