如何迭代PCB以在Linux内核模块中显示信息?

时间:2011-04-06 00:36:20

标签: process module kernel pid

我想编写一个可以向我展示所有正在运行的进程的PID的Linux内核模块。 我有以下代码:

/*
 * procInfo.c  My Kernel Module for process info
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

/*
 * The init function, called when the module is loaded.
 * Returns zero if successfully loaded, nonzero otherwise.
 */
static int mod_init(void)
{
        printk(KERN_ALERT "ProcInfo sucessfully loaded.\n");
        return 0;
}

/*
 * The exit function, called when the module is removed.
 */
static void mod_exit(void)
{
        printk(KERN_ALERT "ProcInfo sucessfully unloaded.\n");
}

void getProcInfo()
{
        printk(KERN_INFO "The process is \"%s\" (pid %i)\n",
        current->comm, current->pid);
}

module_init(mod_init);
module_exit(mod_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Rodrigo");

正如你所看到的,我知道我必须使用* struct task_struct *结构来获取PID和进程名称,但我正在使用当前,而且我知道存在一些双包含所有PCB的链接循环列表,因此主要问题是: 我需要添加什么来迭代这个链接的lisk与p-next_task和p-prev_task所以getProcInfo工作? 谢谢!

2 个答案:

答案 0 :(得分:6)

include/linux/sched.h中的以下宏可能很有用:

#define next_task(p) \
    list_entry_rcu((p)->tasks.next, struct task_struct, tasks)

#define for_each_process(p) \
    for (p = &init_task ; (p = next_task(p)) != &init_task ; )

在调用这些宏之前,您可能需要按住tasklist_lock;有关如何锁定,迭代和解锁的几个示例位于mm/oom_kill.c

答案 1 :(得分:5)

实际上,对于较新的内核(2.6.18和更新版本),列出任务的正确方法是持有rcu锁,因为任务列表现在是RCU列表。另外tasklist_lock不再是导出符号 - 这意味着当您编译可加载内核模块时,此符号将不会对您可见。

要使用的示例代码

struct task_struct *task;
rcu_read_lock();                                                    
for_each_process(task) {                                             
      task_lock(task);                                             

      /* do something with your task :) */

      task_unlock(task);                                           
}                                                                    
rcu_read_unlock();                       

关于Linux内核源代码目录中RCU的文档也很有用,您可以在Documentation/RCU

中找到它。