Question: n this project, you will write a kernel module that lists all current tasks in a Linux system. Be sure to review the programming project
n this project, you will write a kernel module that lists all current tasks in a Linux system. Be sure to review the programming project in Chapter 2, which deals with creating Linux kernel modules, before you begin this project. The project can be completed using the Linux virtual machine provided with this text.
Part IIterating over Tasks Linearly
As illustrated in Section 3.1, the PCB in Linux is represented by the structure task struct, which is found in the
#include
struct task struct *task;
for each process(task) { /* on each iteration task points to the next task */
}
The various fields in task struct can then be displayed as the program loops through the for each process() macro.
Part I Assignment
Design a kernel module that iterates through all tasks in the system using the for each process() macro. In particular, output the task name (known as executable name), state, and process id of each task. (You will probably have to read through the task struct structure in
ps -el
The two values should be very similar. Because tasks are dynamic, however, it is possible that a few tasks may appear in one listing but not the other.
Part IIIterating over Tasks with a Depth-First Search Tree
The second portion of this project involves iterating over all tasks in the system using a depth-first search (DFS) tree. (As an example: the DFS iteration of the processes in Figure 3.8 is 1, 8415, 8416, 9298, 9204, 2, 6, 200, 3028, 3610, 4005.)
Linux maintains its process tree as a series of lists. Examining the task struct in
children
and
sibling
These objects are pointers to a list of the tasks children, as well as its sib- lings. Linux also maintains references to the init task (struct task struct init task). Using this information as well as macro operations on lists, we can iterate over the children of init as follows:
struct task struct *task; struct list head *list;
list for each(list, &init task->children) { task = list entry(list, struct task struct, sibling); /* task points to the next child in the list */
}
The list for each() macro is passed two parameters, both of type struct list head:
Apointertotheheadofthelisttobetraversed Apointertotheheadnodeofthelisttobetraversed
At each iteration of list for each(), the first parameter is set to the list structure of the next child. We then use this value to obtain each structure in the list using the list entry() macro.
Part II Assignment
Beginning from the init task, design a kernel module that iterates over all tasks in the system using a DFS tree. Just as in the first part of this project, output the name, state, and pid of each task. Perform this iteration in the kernel entry module so that its output appears in the kernel log buffer.
If you output all tasks in the system, you may see many more tasks than appear with the ps -ael command. This is because some threads appear as children but do not show up as ordinary processes. Therefore, to check the output of the DFS tree, use the command
ps -eLf
This command lists all tasksincluding threadsin the system. To verify that you have indeed performed an appropriate DFS iteration, you will have to examine the relationships among the various tasks output by the ps command. 
ps pid 9298 init pid 1 login sshd kthreadd. pid 8415 pid 3028 pid 2 sshd helper pdflush bash pid. 6 pid 3610 pid 200 pid 8416 tcsch. pid 4005 pid 9204 Figure 3.8 A tree of processes on a typical Linux system
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
