Kernel module that iterates over the tree of children of a task using depth first search
Solution 1
This is a bit old, but I came across it as it seems to be one of the programming projects found in chapter 3 of Operating System Concepts 9th Edition, so others may yet come looking.
The code you started with is straight from the book, but it is a good starting point. You just need to implement the DFS. Here is the code that will accomplish it, it should be pretty self explanatory:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
/**
* Performs a DFS on a given task's children.
*
* @void
*/
void DFS(struct task_struct *task)
{
struct task_struct *child;
struct list_head *list;
printk("name: %s, pid: [%d], state: %li\n", task->comm, task->pid, task->state);
list_for_each(list, &task->children) {
child = list_entry(list, struct task_struct, sibling);
DFS(child);
}
}
/**
* This function is called when the module is loaded.
*
* @return 0 upon success
*/
int task_lister_init(void)
{
printk(KERN_INFO "Loading Task Lister Module...\n");
DFS(&init_task);
return 0;
}
/**
* This function is called when the module is removed.
*
* @void
*/
void task_lister_exit(void)
{
printk(KERN_INFO "Removing Task Lister Module...\n");
}
// Macros for registering module entry and exit points.
module_init(task_lister_init);
module_exit(task_lister_exit);
Solution 2
you can get the state with task->state /* -1 unrunnable, 0 runnable, >0 stopped */
get the parent pid with task->parent->pid
Hassan Jalil
Masters in Computer Science at Vrije Universiteit Amsterdam Specialization in High Performance Computing
Updated on July 25, 2022Comments
-
Hassan Jalil over 1 year
So I know how to create a kernel and to iterate over the processes linearly by simply including
linux/sched.h
and using the following code:struct task_struct *task; for_each_process(task) { printk("Name: %s PID: [%d]\n", task->comm, task->pid); }
How can I print these tasks using a depth first search? I want my output to be similar to the one of
ps -eLf
.The following patch of code has been given for reference:
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 */ }
and I know that
task->comm
returns the name andtask->pid
returns the PID for that task.What fields are used to for the state and parent PID?
-
Hassan Jalil over 10 yearsany help with getting dfs ?
-
Vivek Maran over 5 yearsI was under the impression that
list_entry(list, struct task_struct, sibling);
should belist_entry(list, struct task_struct, children);
but it doesent work. Can you please explain to me what am missng?