Kernel module that iterates over the tree of children of a task using depth first search

13,381

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

Share:
13,381
Hassan Jalil
Author by

Hassan Jalil

Masters in Computer Science at Vrije Universiteit Amsterdam Specialization in High Performance Computing

Updated on July 25, 2022

Comments

  • Hassan Jalil
    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 and task->pid returns the PID for that task.

    What fields are used to for the state and parent PID?

  • Hassan Jalil
    Hassan Jalil over 10 years
    any help with getting dfs ?
  • Vivek Maran
    Vivek Maran over 5 years
    I was under the impression that list_entry(list, struct task_struct, sibling); should be list_entry(list, struct task_struct, children); but it doesent work. Can you please explain to me what am missng?