1. 程式人生 > >核心模組遍歷程序和任務佇列儲存到proc檔案中

核心模組遍歷程序和任務佇列儲存到proc檔案中

實現一個模組用它遍歷當前程序的父程序和任務佇列,並將遍歷的結果輸出到一個proc 檔案中(遍歷可以從 current 當前程序開始,父程序遍歷到初始化程序,遍歷任務佇列可以利用 for_each_process 巨集)。

下面是我的核心模組的實現部分:

/************************************************************
*   使用核心模組從當前程序開始先前遍歷,知道找到第一個程序為止  *
*   並將遍歷的結果儲存到proc檔案中                           *
***********************************************************/
#include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/proc_fs.h> #include <linux/jiffies.h> #include <asm/uaccess.h> #include <linux/moduleparam.h> #include <linux/list.h> #include <linux/sched.h> #include <asm/current.h>
#define MODULE_NAME "MyProcess" #define MYDATA_LEN 10000 //放使用者空間的資料 struct my_proc_data{ char value[MYDATA_LEN]; }; struct my_proc_data mydata,fathers_data; //proc結構變數 struct proc_dir_entry *example_dir; //存放任務佇列 struct proc_dir_entry *date_file; //存放父程序 struct proc_dir_entry *father_file; static int
param; module_param(param,int,0644); //讀檔案驅動函式 static int proc_read(char *page,char **start,off_t off,int count,int *eof,void *data) { int len; struct my_proc_data *mydatap = (struct my_poroc_data *)data; len += sprintf(page,"%s",mydatap->value); return len; } //寫檔案驅動函式 static int proc_write(struct file *file,const char *buffer,unsigned long count,void *data) { int len; struct my_proc_data *mydatap = (struct my_proc_data *)data; if(count > MYDATA_LEN) len = MYDATA_LEN; else len = count; if(copy_from_user(mydatap->value,buffer,len)){ return -EFAULT; } mydatap->value[len-1] = '\0'; return len; } //載入模組 int init_module(void) { //建立dir資料夾 example_dir = (struct proc_dir_entry *)proc_mkdir("mydir",0); if(example_dir == 0){ printk("mkdir fail!!\n"); return -1; } //建立檔案 date_file = (struct proc_dir_entry *)create_proc_entry("myfile",0666,example_dir); if(date_file == 0){ printk("create file fails!!\n"); return -ENOMEM; } //建立檔案 father_file = (struct proc_dir_entry *)create_proc_entry("fathers",0666,example_dir); if(father_file == 0){ printk("create file fails!!\n"); return -ENOMEM; } struct task_struct *pos = get_current(); for_each_process(pos){ strcat(mydata.value,pos->comm); strcat(mydata.value,"\n"); } date_file->data = &mydata; date_file->read_proc = &proc_read; date_file->write_proc = &proc_write; date_file->owner = THIS_MODULE; pos = get_current(); while(pos != &init_task){ strcat(fathers_data.value,pos->parent->comm); strcat(fathers_data.value,"=>"); strcat(fathers_data.value,pos->comm); strcat(fathers_data.value,"\n"); pos = pos->parent; } father_file->data = &fathers_data; father_file->read_proc = &proc_read; father_file->write_proc = &proc_write; father_file->owner = THIS_MODULE; return 0; } //解除安裝模組 void cleanup_module(void) { remove_proc_entry("myfile",example_dir); remove_proc_entry("fathers",example_dir); remove_proc_entry("mydir",NULL); printk("GoodBye!!\n"); } MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("This is the description"); MODULE_AUTHOR("bobo");

其中的Makefile檔案為:

obj-m := process.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean 

現在我們使用make命令編譯,編譯完成時候,我們動態載入核心模組

sudo insmod process.ko

然後我們檢視proc文件下我們建立的檔案:

cat /proc/mydir/myfile

執行後的效果為:

下面我們檢視一下所有的父程序的檔案:

cat /proc/mydir/fathers

執行效果為: