一文学会使用Linux内核模块&proc实例统计所有进程信息

2023-12-05 0 733
目录
  • 实例要求
  • 解决方案
    • archlinux 下的makefile

实例要求

编写一个Linux的内核模块,其功能是遍历操作系统所有进程。该内核模块输出系统中:每个进程的名字、进程pid、进程的状态、父进程的名字;以及统计系统中进程个数,包括统计系统中TASK_RUNNING、TASK_INTERRUPTIBLE、TASK_UNINTERRUPTIBLE、TASK_ZOMBIE、TASK_STOPPED等(还有其他状态)状态进程的个数。同时还需要编写一个用户态下执行的程序,显示内核模块输出的内容。

学习资料:

《边干边学—Linux内核指导》 ArchLinux Wiki

解决方案

#include <linux/module.h> //needed by all modules
#include <linux/kernel.h> //needed for KERN_INFO
#include <linux/sched.h> //defined struct task_struct
#include <linux/proc_fs.h> //create proc file
#include <linux/seq_file.h> //use seq_file
#define FILENAME \”osexp\” //defile proc file name
int myshow(struct seq_file *,void *);
int myopen(struct inode *,struct file *);
/* custom the operations to the seq_file */
static const struct file_operations myops = {
.owner = THIS_MODULE,
.open = myopen,
.read = seq_read,
.release = single_release
};
/* do when open the seq file */
int myopen(struct inode *inode,struct file *file){
single_open(file,myshow,NULL);//bind seq_file with myshow function
return 0;
}
/* create proc file */
int init_proc(void){
struct proc_dir_entry * myfile;
myfile = proc_create(FILENAME,0444,NULL,&myops);//create proc file
if(myfile == NULL) //deal with error
return -ENOMEM;
return 0;
}
/* remove proc file */
void remove_proc(void){
remove_proc_entry(FILENAME,NULL);//remove proc file
printk(KERN_INFO \”[m] proc file:%s removed\\n\”,FILENAME);//print debug message
}
/*description: output process\’s info to log */
int myshow(struct seq_file *file,void *v){
int num_running = 0; //the number of process whose status is running
int num_interruptible = 0; //the number of process whose status is interruptible
int num_uninterruptible = 0; //the … status is uninterruptible
int num_zombie = 0; //the process exited with status zombie
int num_stopped = 0; //the … status is stopped
int num_traced = 0; //the … status is traced
int num_dead = 0; //the process has deaded;
int num_unknown = 0; //the process whose status is unknown
int num_total = 0; //the total number of process
int t_exit_state; //temp var to store task_struct.exit_state
int t_state; //temp var to store task_struct.state
struct task_struct *p; //pointer to task_struct
//printk(\”[m] All processes\’ info:\\n\”);//print boot info
seq_printf(file,\”[m] All processes\’ info:\\n\”);
for(p=&init_task;(p=next_task(p))!=&init_task;){ //go througn the linklist
//printk(KERN_INFO \”[m] Name:%s Pid:%d State:%ld ParName:%s\\n\”,p->comm,p->pid,p->state,p->real_parent->comm); //print the process\’s info to log
seq_printf(file,\”[m] Name:%s Pid:%d State:%ld ParName:%s\\n\”,p->comm,p->pid,p->state,p->real_parent->comm);
num_total++; //total number of process plus one
t_state = p->state; //put p->state to variable t_state
t_exit_state = p->exit_state;//similar to above
if(t_exit_state!=0){ //if the process has exited
switch(t_exit_state){
case EXIT_ZOMBIE://if the exit state is zombie
num_zombie++;//variable plus one
break; //break switch
case EXIT_DEAD://if the exit state is dead
num_dead++;//variable plus one
break;//break switch
default: //other case
break;//break switch
}
}else{ // if the proess hasn\’t exited
switch(t_state){
case TASK_RUNNING://if the state is running
num_running++;//variable plus one
break;//break switch
case TASK_INTERRUPTIBLE://state is interruptible
num_interruptible++;//variable plus one
break;//break switch
case TASK_UNINTERRUPTIBLE://state is uninterruptible
num_uninterruptible++;//var + 1
break;//break switch
case TASK_STOPPED://state is stopped
num_stopped++;//var +1
break;//break switch
case TASK_TRACED://state is traced
num_traced++;//var +1
break;//break switch
default://other case
num_unknown++;
break;
}
}
}
//below instruction is to print the statistics result in above code
// printk(KERN_INFO \”[m] total tasks: %10d\\n\”,num_total);
// printk(KERN_INFO \”[m] TASK_RUNNING: %10d\\n\”,num_running);
// printk(KERN_INFO \”[m] TASK_INTERRUPTIBLE: %10d\\n\”,num_interruptible);
// printk(KERN_INFO \”[m] TASK_UNINTERRUPTIBLE: %10d\\n\”,num_uninterruptible);
// printk(KERN_INFO \”[m] TASK_TRACED: %10d\\n\”,num_stopped);
// printk(KERN_INFO \”[m] TASK_TRACED: %10d\\n\”,num_stopped);
// printk(KERN_INFO \”[m] EXIT_ZOMBIE: %10d\\n\”,num_zombie);
// printk(KERN_INFO \”[m] EXIT_DEAD: %10d\\n\”,num_dead);
// printk(KERN_INFO \”[m] UNKNOWN: %10d\\n\”,num_unknown);
seq_printf(file,\”[m] total tasks: %10d\\n\”,num_total);
seq_printf(file,\”[m] TASK_RUNNING: %10d\\n\”,num_running);
seq_printf(file,\”[m] TASK_INTERRUPTIBLE: %10d\\n\”,num_interruptible);
seq_printf(file,\”[m] TASK_UNINTERRUPTIBLE: %10d\\n\”,num_uninterruptible);
seq_printf(file,\”[m] TASK_TRACED: %10d\\n\”,num_stopped);
seq_printf(file,\”[m] TASK_TRACED: %10d\\n\”,num_stopped);
seq_printf(file,\”[m] EXIT_ZOMBIE: %10d\\n\”,num_zombie);
seq_printf(file,\”[m] EXIT_DEAD: %10d\\n\”,num_dead);
seq_printf(file,\”[m] UNKNOWN: %10d\\n\”,num_unknown);
return 0;
}
int init_module(void){// init the kernel module
printk(KERN_INFO \”[m] exp_process started\\n\”);//print start message
return init_proc();//create proc file
}
void cleanup_module(void){ //clean up the resources when module finished
remove_proc();//remove proc file
printk(KERN_INFO \”[m] exp_process finished\\n\”);//print finish message
}
MODULE_LICENSE(\”GPL\”);//show that this code follow GUN General Public License

archlinux 下的makefile

TARGET = os_1_2
KDIR = /lib/modules/$(shell uname -r)/build
PWD = $(shell pwd)
obj-m += $(TARGET).o
all:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean

以上就是一文学会使用Linux内核模块&amp;proc实例统计所有进程信息的详细内容,更多关于Linux内核模块&amp;proc的资料请关注悠久资源网其它相关文章!

您可能感兴趣的文章:

  • 一文学会使用Linux内核模块&proc实例统计所有进程信息
  • Linux内核设备驱动之Linux内核模块加载机制笔记整理
  • Linux查看进程的所有信息的方法示例
  • Linux如何查看进程栈信息示例
  • Linux系统下利用C程序输出某进程的内存占用信息

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悠久资源 linux shell 一文学会使用Linux内核模块&proc实例统计所有进程信息 https://www.u-9.cn/jiaoben/linuxshell/101558.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务