我正在尝试在内核实验室做额外的练习。提出的问题是通过编写linux驱动程序来打印所有正在运行的进程的PID和名称。
我的方法是通过递归地使用
init
中指向 real_parent
的指针回到 task_struct
过程。这部分工作正常。但是当我尝试获取子进程的 PID 时,我得到了奇怪的值。
这是我正在查看的
task_struct
中linux/sched.h
的定义的一部分(内核版本是5.14.10)。
/* Real parent process: */
struct task_struct __rcu *real_parent;
/* Recipient of SIGCHLD, wait4() reports: */
struct task_struct __rcu *parent;
/*
* Children/sibling form the list of natural children:
*/
struct list_head children; //I am trying to get the task_struct of the child process using this list_head
struct list_head sibling;
struct task_struct *group_leader;
这是我写的用于获取第一个和最后一个子进程的 pid 的内容:
struct task_struct *child;
struct task_struct *parent;
struct task_struct *init;
p = current;
pr_info("Current process name %s\t", p->comm);
pr_info("Current process id %d\n", p->pid);
/* Get the *task_struct for init process. Print for debugging*/
parent = p->real_parent;
do {
pr_info("Parent process name: %s, ", parent->comm);
pr_info("Parent process id: %d\n", parent->pid);
if (parent->pid == 1) {
init = parent;
break;
}
else {
parent = parent->real_parent;
}
} while (1);
/* Print some child processes of the init process */
pr_info("list_next_entry pid: %d\n", list_next_entry(init, children)->pid);
printk("list_first_entry pid = %d\n", list_first_entry(&init->children, struct task_struct, children)->pid);
printk("list_last_entry pid = %d\n", list_last_entry(&init->children, struct task_struct, children)->pid);
这是安装驱动程序后的输出:
Current process name insmod
Current process id 336
Parent process name: sh,
Parent process id: 308
Parent process name: init,
Parent process id: 1
list_next_entry pid: 2096789597
list_first_entry pid = 2096789597
list_last_entry pid = 1863549922
我做错了什么?另外如果有更好的方法请告诉我。
所以正确的方法是在 linux/sched/signal.h 中使用
for_each_process(p)
宏
for_each_process(p) {
pr_info("Process name: %s, PID: %d\n", p->comm, p->pid);
}