Individual written problems are to be done individually. Group
programming problems are to be done in your assigned programming
groups. The deadline for group programming problems applies to both
CVN and non-CVN students. All homework submissions are to be made via
the submit programs. Refer to the homework policy page on the
class web site for further details.
Exercise numbers refer to the course textbook, Applied Operating System Concepts. Each problem is worth 5 points.
Please complete and submit a private group programming assignment evaluation. The evaluation should be in a separate file called evaluation.txt that is submitted with your individual written assignment submission.
Programming problems are to be done in your assigned groups using the VM that has been assigned to your group. For all programming problems you will be required to submit source code, a README file documenting your files and code, and a test run of your programs. In addition, you should submit a cover sheet using either homework_work.txt or homework_nonwork.txt, depending on whether or not the programming assignment is completely working or not. For source code submissions, you only need to submit new source code files that you created and kernel source code files that you changed. You should clearly indicate your names, email addresses, and assigned group number on your submission. Each group is required to submit one writeup for the programming assignment.
You will build your own Linux kernel for this class. For each homework assignment, you will build a new Linux kernel. The image of the kernel you build for this assignment should be vmlinuz.hmwk2. Grading for this assignment will be done based on vmlinuz.hmwk2. Note that the version of Linux running as the Host OS on the CLIC machines is different from that of the Guest OS that you will modify running in VMware.
After you have patched the kernel, the Documentation/ subdirectory will contain man pages on kdb. Read them to familiarize yourself with its operation. You can also read a summary of kernel debugging techniques (which include kdb) at: http://www.xml.com/ldd/chapter/book/ch04.html. At any time you may press the pause button to enter the debugger and, once in the the debugger, type go to exit to the ordinary command prompt. Though we won't require you to use the debugger for this assignment, we will be testing to make sure it is installed!
The prototype for your system call will be:
int pinfo(pid_t pid, struct pinfo *info);
pid_t
is defined in /usr/include/sys/types.h.
You should define struct pinfo
as
struct pinfo { int pid; /* process id */ long state; /* current state of process */ long priority; /* process priority */ int parent_pid; /* process id of parent */ int youngest_child_pid; /* pid of youngest child */ int younger_sibling_pid; /* pid of younger sibling */ int older_sibling_pid; /* pid of older sibling */ unsigned long start_time; /* process start time */ long user_time; /* CPU time spent in user mode */ long sys_time; /* CPU time spent in system mode */ long cutime; /* total user time of children */ long cstime; /* total system time of children */ long uid; /* user id of process owner */ char comm[16]; /* name of program executed */ };
in /usr/src/linux/include/linux/pinfo.h as part of your solution.
Your system call should return 0 if it is able to locate the process information for the target pid. At a minimum, your system call should detect the following conditions and respond as described:
The referenced error codes are defined as ESRCH and EINVAL, respectively, in /usr/src/linux/asm/errno.h
You should start by reviewing the "How System Calls Work in Linux/i86" section of the Linux Kernel Hacker's (LKH) Guide. Note that because the Linux kernel changes over time, the procedure is no longer exactly correct. However, there are messages appended at the end of the section that will help significantly. Two more recent articles that discuss how to add system calls can be found here and here.
You will also want to review Chapter 3 on "Processes" in the class linux reference book, Understanding the Linux Kernel.
As explained in the LKH guide, each system call must be assigned a number. Your system call should be assigned number 222.
Big Hint: Linux maintains a list of all processes in a doubly linked list. Each entry in this list is a task_struct structure, which is defined in /usr/src/linux/include/linux/sched.h. In /usr/src/linux/include/asm/current.h, current is defined to inline a function which returns the address of the task_struct of the currently running process. All of the information to be returned in the pinfo structure can be determined by starting with current.
Bigger Hint:
In order to learn about system calls, you may also find it helpful to
search the Linux kernel for other system calls and see how they are
defined. The file kernel/sched.c
might give some useful
examples of this. The getpid
and getuid
system calls might be useful starting points. The system call
sys_getpid defined in /usr/src/linux/kernel/sched.c uses
current and provides a good reference point for defining your
system call.
FINAL NOTE: Your kernel has partially reserved a slot in the syscall table for ni_syscall (when you see it, you will know what we are talking about). Since ni_syscall means "not implemented", do not be afraid to commandeer that slot.
NOTE: Although system calls are generally accessed through a library (libc), your test program should access your system call directly. This is accomplished by utilizing the appropriate _syscall macro in /usr/include/asm/unistd.h. As explained in LKH, which _syscall macro you use is determined by the number of arguments passed to your system call.
The output of the program should be easy to read, and the program should check for errors such as invalid input or too many/few arguments, and invalid PID. The ps command will provide valuable help in verifying the accuracy of information printed by your program. You can access detailed information on the ps command by entering man ps.
Your writeup should include the program output from the following two testcases:
printk
statements in system calls will print their
output to the console whenever they are invoked. To request
printk
messages be sent to a log file, insert the
following line into the /etc/syslog.conf file:
kern.* /var/kern.logThis will cause
printk
messages to be written to /var/kern.log.
You can send a signal to request the syslog daemon re-read the updated
/etc/syslog.conf file, with the command "kill -1 pid" where
pid is the pid of the syslogd process.