Homework 5 -- Programming

Administrivia

This is a group assignment, per the instructions given at the beginning of the semester. Turn in one copy of the programming assignment; however, each of you must turn in individual written assignments.

In addition, each team member must turn in the group programming evaluation with their own written assignments.

Deliverables

You're going to be modifying a kernel. We do not want you to submit an entire kernel source tree; instead, you'll submit the output of "diff" -- the differences between your code and the original. You'll also need to submit a working or a non-working cover sheet. Finally, turn in any test programs or data, a README file documenting your work (including clear explanations of what each file is), and output from test runs.

Time of Day Permission Semantics

For this assignment, you're going to modify the file permission mechanism. In particular, even if no access is otherwise granted to a file, it can be granted depending on the time of day.

If the regular permission-checking code sees that the file mode is all 0s, it will call your kernel code. Your kernel code must pass the request to a user-level which will make the decision. That daemon will return the answer to the kernel.

To communicate with the daemon, implement a new system call. The first parameter is the operation: enable, receive, and reply. Receive is used to receive requests; reply is used to pass back answers. (A real implementation would do both in a single call, and in fact would permit arrays of requests and responses, but I'm not asking for that.) See below for the enable.

Requests and responses are tagged. Responses need not come in the same order as the requests; the tag --- an integer --- is used to match them up. You'll probably need a fixed-size buffer of requests in the kernel; a process seeking permission when the array is full has to block waiting for a slot. All such processes have to block while waiting for a response. Similarly, a process doing a receive call blocks if there are no pending requests. Your code must support more than one simultaneous process doing receive operations.

The purpose of enable is to tell the kernel that this facility is in use. An enable request specifies that some number of requests will be accepted. If more than that number are outstanding, your kernel code just returns a "permission denied" value and purges the queue; it's a failure that indicates that the daemon isn't running. This number is larger than the maximum size of the buffer queue. The normal operation of the user-level program is to issue a new enable request frequently. In fact, the usual sequence is

while(true) {
	enable(N);  /* Or maybe do this every N/2 cycles */
	getrequest();
	(think)
	sendreply();
}

For simplicity's sake, the daemon is operating on inode numbers, not filenames. Read a configuration file whose lines look like this:

filename hhmm hhmm op
where the two hhmm fields are the start and stop times, and op is some combination of rwx. Build a simple array (it can be fixed-size) of inode, start time, stop time, and operations. When a request arrives, see if the inode number and operation match an entry; if so, see if the time of day is within the range. Don't worry about having multiple entries with different times. You'll need the stat() and time() system calls, and the localtime() library routine.

The system call takes two parameters, an operation and the following union:

enum todperm_op {enable, request, reply};
union tod_perm {
        int enable_num;
        struct {
                int tag;
		dev_t device;
                long inode;
        } request;
        struct {
                int tag;
                enum {yes, no} response;
        } reply;
};

A production implementation of a scheme like this would use file names, and would use a character device rather than a system call. But those would add a lot of complexity to what is already a challenging assignment.

You'll need to review how a process can block in the kernel. Also remember about masking interrupts and/or spinlocks, as appropriate.

Cautions

Your vmware directory is not backed up. For safety's sake, make a copy of your changes — not the whole kernel tree! — on another machine.

Danger, Will Robinson

If two people boot the same virtual machine at the same time, it will corrupt the (virtual) disk. Please co-ordinate usage with other members of your team.