Hand out: Oct. 20, 2022
Deadline: Oct. 30 23:59 (GMT+8)
In this lab, you will learn how to achieve crash consistency in your standalone file system step by step, including:
If you have questions about this lab, either in programming environment or requirement, please ask TA Yiwen Zhang by email(besssszyw@gmail.com) or Wechat.
Please backup your solution of lab1 first.
First, save the lab1’s solution:
x
$ cd lab-cse$ git commit -a -m “solution for lab1”Then, pull from the repository:
x
$ git pullremote: Counting objects: 43, done.…[new branch] lab2A -> origin/lab2AAlready up-to-dateThen, change to lab2 branch:
xxxxxxxxxx$ git checkout lab2AMerge with lab1, and solve the conflict by yourself (probably mainly in extent_server.cc and chfs_client.cc):
x
$ git merge lab1Auto-merging fuse.ccCONFLICT (content): Merge conflict in chfs_client.ccAutomatic merge failed; fix conflicts and then commit the result......After merge all of the conflicts, you should be able to compile successfully:
xxxxxxxxxx$ makeMake sure there's no error in make.
Note: For this lab, you will not have to worry about concurrency problems. You also need not be concerned about malicious or buggy applications.
In lab1, we have implemented a basic file system on a single machine. In this lab, we will extend the file system to a transactional file system, which is robust against crashes.
Below is the architecture of our transactional filesystem in lab2A. As you see a new component named persister has been added to the system, its function is to do logging, checkpoint, and data restoration. Skeleton code of persister has been provided in file persister.h.
In our transactional filesystem, we regard chfs_client as the transaction layer, which means each chfs_client function(such as create, write, symlink…) should be treated as a transaction. Except from BEGIN and COMMIT, a transaction in ChFS usually consists of several other operations in extent_server layer. For example, the ‘create’ transaction(in chfs_client) consists of ‘create’ and ‘put’ operations(in extent_server).

In Part 1 your job is to use log mechanism to persist ChFS data into disk, and make sure data can be recovered completed after ChFS restart. The code you cope with in Part 1 is mainly in persister.h and extent_server.cc. After implementing the logging and recovering logic, your code should pass all Part 1 test scripts.
The test in Part 1 is basic, it only crashes ChFS after a filesystem operation has done(e.g. create, write, symlink). Therefore, just focus on persistency in this part. There are 3 scripts for this part, test-lab2a-part1-a.pl, test-lab2a-part1-b.pl and test-lab2a-part1-c.sh. You can run them one by one, for example:
xxxxxxxxxx$ make clean && make$ ./start.shstarting ./chfs_client /home/stu/cse-lab/chfs1 > chfs_client1.log 2>&1 &$ perl ./test-lab2a-part1-a.pl chfs1create file-yyuvjztagkprvmxjnzrbczmvmfhtyxhwloulhggy-18674-0create file-hcmaxnljdgbpirprwtuxobeforippbndpjtcxywf-18674-1...dircheck ===== ChFS Crash ===== ===== ChFS Restart =====...Passed all tests!All three test scripts will restart ChFS for several times, each restart generates corresponding output, and follows with checks for previous filesystem operations. If test file exits without printing "Passed all tests!", then there must be something wrong with your code. If the error happens after a restart of ChFS, then check your code for logging and recovering; but if the error happens before any crash, it is probably due to your bug in lab1 code.
After passing 3 scripts one by one, run overall part 1 test scripts with:
xxxxxxxxxx$ make clean && make$ ./test-lab2a-part1.sh starting ./chfs_client /home/stu/cse-lab/chfs1 > chfs_client1.log 2>&1 &Passed APassed BPassed C
Part1 score: 40/40Now you get full score in part 1, start part 2!
In Part 2 your job is to use log mechanism in ChFS client layer to achieve crash consistency, make sure each transaction(create, mkdir, write…) is atomic under crash condition.
Here you need to implement log logic for transaction in ChFS client. You may consider:
Note that in practice, system crash may also occur when a log entry is being written to the log file. But in this lab we consider each log operation as an atomic operation, so you do not have to worry about this issue.
The test is a little bit harder than part 1, in part 2 ChFS crashes any time, it could occur in the middle of an inode layer operation or an extent_server layer operation. In this way we can examine whether your filesystem achieves atomicity under crash conditions. There are 2 test scripts for this part, test-lab2a-part2-a.pl and test-lab2a-part2-b.pl. You can run them one by one, for example:
xxxxxxxxxx$ make clean && make$ ./start.shstarting ./chfs_client /home/stu/cse-lab/chfs1 > chfs_client1.log 2>&1 &$ perl ./test-lab2a-part2-a.pl chfs1create file-yyuvjztagkprvmxjnzrbczmvmfhtyxhwloulhggy-18674-0...===== ChFS Crash =====test-lab2a-part2-a: cannot create chfs1/file-xerlcfysgkttqpkclweqlnsszmffexdaqwotdcfq-14912-21 due to system crash: Software caused connection abort===== ChFS Restart =====...dircheckPassed all tests!All 2 test scripts will restart ChFS in the middle of filesystem operations for several times. If test file exits without printing "Passed all tests!", then there must be something wrong with your code.
After passing 2 scripts one by one, run overall part 2 test scripts with:
xxxxxxxxxx$ make clean && make$ ./test-lab2a-part2.sh starting ./chfs_client /home/stu/cse-lab/chfs1 > chfs_client1.log 2>&1 &Passed APassed B
Part1 score: 40/40Now you get full score in part 2, start part 3!
In Part 3 your job is to implement checkpoint mechanism. Without checkpointing, log file grows indefinitely. In order to keep log file size within acceptable range, you have to use checkpoint mechanism to clear committed logs from time to time.
The test is fairly simple, it mainly checks the size of your log files. Log file bigger than MAX_LOG_SZ and checkpoint file bigger than DISK_SIZE will result in test failure. There are only 1 test scripts for this part, test-lab2a-part3-a.pl:
xxxxxxxxxx$ make clean && make$ ./start.shstarting ./chfs_client /home/stu/cse-lab/chfs1 > chfs_client1.log 2>&1 &$ perl ./test-lab2a-part3-a.pl chfs1Write and read one file: OK...Check directory listing: OK===== ChFS Crash =====Check logfile and checkpoint file size: logfile xxx bytes, checkpoint xxx bytes===== ChFS Restart =====...Passed all testsTest script prints out your log file and checkpoint file size. If you see any error like “Logfile too big” or “Checkpoint too big”, do some optimization to control your file size.
Finally, after you've implemented all these features, run the grading script:
xxxxxxxxxx$ ./grade.shstarting ./chfs_client /home/stu/cse-lab/chfs1 > chfs_client1.log 2>&1 &Passed APassed BPassed C
Part1 score: 40/40starting ./chfs_client /home/stu/cse-lab/chfs1 > chfs_client1.log 2>&1 &Passed APassed B
Part2 score: 40/40starting ./chfs_client /home/stu/cse-lab/chfs1 > chfs_client1.log 2>&1 &Passed A
Part3 score: 20/20Note that if you encounter a "chfs_client DIED", your filesystem is not working. In such cases the requests are served by the system's file system (usually EXT3 or btrfs or tmpfs). You would not be awarded credits if your chfs_client crashes, but could get partial credit if it produces incorrect result for some test cases. So do look out for such mistakes. We've seen dozens of students every year thinking that they've passed lots of tests before realizing this.
After all above done:
xxxxxxxxxx$ make handin
That should produce a file called lab2a.tgz. Change the file name to your student id:
xxxxxxxxxx$ mv lab.tgz lab2a_[your student id].tgz
Then upload lab2a_[your student id].tgz file to Canvas before the deadline. Make sure your implementation has passed all the tests before final submit. (If you must re-submit a new version, add explicit version number such as "V2" to indicate).
You will receive full credit if your software passes the same tests we gave you when we run your software on our machines.