Due:

Thursday, April 14, 10pm

Starter code:

See Assignment 10 on Canvas for the Github Classroom link. Yes, it is the entire xv6 source code.

Submission:

This is a pair assignment, but you can work alone, if you so choose.

Submit the contents of your repository via Gradescope. See Deliverables below for what to submit. If you are working with a partner, do not forget to include their name with the submission.

There will be no autograder for this assignment ahead of the deadline. Read the requirements and run tests locally.

The purpose of this assignment is for you to explore the xv6 source code and find the appropriate things to modify to implement a system call collecting stats about open files.

After this assignment, you should be familiar with:

  • The execution flow of a system call.
  • Where data about open files is stored in the kernel data structures.
  • How process-related data is stored and handled in the kernel in general.

Before you start, make sure you are able to run xv6 on your machine. Follow the directions given in Lab 10.

Since familiarizing yourself with an unknown source code base might be a little daunting, we have generated an interlinked browsable version of xv6 for your convenience.

Note: The goal is for you to search around and find stuff. It would be best if you avoid posting exact function names or the line numbers that need to be changed to complete this assignment on Piazza or anywhere else.

Task

For this assignment you’ll be adding a system call which returns a struct containing the following information:

struct iostats {
    uint read_bytes;     // the total number of bytes read
    uint write_bytes;    // the total number of bytes written
};

The system call should have the following signature:

int getiostats(int fd, struct iostats* stats);

Given a file descriptor, getiostats gets the total number of bytes read and written on that file descriptor since it was opened. This information is returned in the user-supplied iostats structure. Returns 0 on success, or -1 on failure (e.g. bad file descriptor).

Plan

For this task, you will need to do the following:

  1. Modify the structure xv6 uses for open files to track the number of bytes read and written.
  2. Modify the implementations of the open, read and write system calls to update these new fields.
  3. Add the new getiostats system call to read these fields.
  4. Add the struct iostats definition to stat.h

Hint: Look at how the other system calls that use a file descriptor work.

Setting up for the tests

The three test programs included with the starter code—test1.c, test2.c and test3.c—are not built into the xv6 image by default, since they rely on a system call that doesn’t exist yet.

Make sure to add them to the UPROGS list in the Makefile.

Manual Testing

  • Run xv6 with make qemu-nox. This will start the QEMU emulator with xv6 in your current terminal.
  • Run test1, test2, test3, or any additional test program you choose to write for debugging.
  • Press Ctrl-a x (while holding Ctrl, press a, then press x without any modifiers) to exit the QEMU/xv6 session.

Debugging

  • Plan A: Use cprintf from kernel code to print debug messages.
  • Plan B: Use the make qemu-gdb command to run the whole system in GDB.

Deliverables

All Tasks
Implement your modification to the OS sources in the xv6 directory.

Commit the code to your repository. Do not include any executables, .o files, or other binary, temporary, or hidden files (unless they were part of the starter code).

Once you are done, remember to submit your solution to Gradescope and do not forget to include your partner.