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

 更新时间:2023年05月14日 11:05:01   作者:chnmagnus  
这篇文章主要介绍了使用Linux内核模块&proc实例统计所有进程信息详解,
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

实例要求

编写一个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?java?shell启动脚本

    使用linux?java?shell启动脚本

    这篇文章主要为大家介绍了使用linux?java?shell启动脚本,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • 一些Linux Shell中的权限相关知识总结

    一些Linux Shell中的权限相关知识总结

    这篇文章主要介绍了一些Linux Shell中的权限相关知识总结,使Linux入门学习中的基础知识,需要的朋友可以参考下
    2015-07-07
  • 防止shell脚本重复执行的代码

    防止shell脚本重复执行的代码

    利用锁机制,让一个特定的shell脚本,每次只能运行一个实例。具体来说,获得锁的脚本实例,能够继续往下执行临界区代码;没有获得锁的实例,则只能等待
    2013-01-01
  • Shell alias给命令设置别名的实现方法

    Shell alias给命令设置别名的实现方法

    这篇文章主要介绍了Shell alias给命令设置别名的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Linux Shell 数组的创建及使用技巧

    Linux Shell 数组的创建及使用技巧

    这篇文章主要介绍了Linux Shell 数组的创建及使用技巧,本文讲解了数组定义、数组读取与赋值以及特殊使用,需要的朋友可以参考下
    2015-07-07
  • linux下命令行操作快捷键及技巧(分享)

    linux下命令行操作快捷键及技巧(分享)

    下面小编就为大家带来一篇linux下命令行操作快捷键及技巧(分享)。小编觉的挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • Shell脚本监控网站页面正常打开情况

    Shell脚本监控网站页面正常打开情况

    这篇文章主要介绍了Shell脚本监控网站页面正常打开情况的代码分享,本文实现监控打开情况,若出错则发送邮件通知,需要的朋友可以参考下
    2014-12-12
  • linux定时备份mysql并同步到其它服务器

    linux定时备份mysql并同步到其它服务器

    这篇文章主要介绍了linux定时备份mysql并同步到其它服务器,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • shell脚本中case条件控制语句的一个bug分析

    shell脚本中case条件控制语句的一个bug分析

    在shell脚本中,发现case语句的一个问题。就是指定小写字母[a-z]和大写字母[A-Z]的这种方法不管用了
    2013-11-11
  • shell产生随机数七种方法的实现

    shell产生随机数七种方法的实现

    这篇文章主要介绍了shell产生随机数七种方法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12

最新评论

?


http://www.vxiaotou.com