Process 如何迭代PCB';在Linux内核模块中显示信息?
我想写一个小的Linux内核模块,它可以显示所有运行进程的PID。 我有以下代码:Process 如何迭代PCB';在Linux内核模块中显示信息?,process,module,kernel,pid,Process,Module,Kernel,Pid,我想写一个小的Linux内核模块,它可以显示所有运行进程的PID。 我有以下代码: /* * 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 loade
/*
* 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");
/*
*c进程信息的我的内核模块
*/
#包括
#包括
#包括
/*
*init函数,在加载模块时调用。
*如果成功加载,则返回零,否则返回非零。
*/
静态int mod_init(void)
{
printk(KERN_警报“ProcInfo”已成功加载。\n);
返回0;
}
/*
*退出功能,在移除模块时调用。
*/
静态void mod_exit(void)
{
printk(KERN_警报“ProcInfo”已成功卸载。\n);
}
void getProcInfo()
{
printk(内核信息“进程是\%s\”(pid%i)\n),
当前->通信,当前->pid);
}
模块初始化(模块初始化);
模块出口(模块出口);
模块许可证(“GPL”);
模块作者(“Rodrigo”);
如您所见,我知道我必须使用*struct task_struct*结构来获取PID和进程名称,但我使用的是current,我知道存在一些包含所有PCB的双链接循环列表,因此主要问题是:
我需要添加什么来使用p-next_任务和p-prev_任务迭代这个链接的lisk,以便getProcInfo工作?
谢谢 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 ; )
在调用这些宏之前,您可能需要按住
任务列表\u锁
;在mm/oom_kill.c
中有几个关于如何锁定、迭代和解锁的示例。实际上,对于较新的内核(2.6.18和更新版本),列出任务的正确方法是持有一个rcu锁,因为任务列表现在是一个rcu列表。另外,tasklist\u 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的文档也很有帮助,您可以在
文档/RCU
中找到它,这不是一个直接的答案,但它帮助我找到了答案!谢谢!