Как перебрать PCB для отображения информации в модуле ядра Linux? - PullRequest
3 голосов
/ 06 апреля 2011

Я хочу написать небольшой модуль ядра 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 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 и имя процесса, но я использую current , и я знаю о существовании некоторой двойной связи Круговой список, содержащий все печатные платы, поэтому главный вопрос: Что мне нужно добавить, чтобы перебрать этот связанный риск с помощью p-next_task и p-prev_task, чтобы getProcInfo работал? Спасибо!

Ответы [ 2 ]

6 голосов
/ 06 апреля 2011

Следующие макросы из 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.

5 голосов
/ 26 июня 2012

На самом деле, для более новых ядер (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();                       

Также может быть полезна документация о RCU в каталоге исходных кодов ядра Linux, и вы найдете ее в Documentation/RCU

...