linux内核设计与实现 epub_为linux内核增加系统新调用实现获取进程数的方法

阅读本文之前还是建议读者先了解下系统调用,可参考之前的文章说一说linux的系统调用

大部分人都是通过ps获取机器的进程数,但ps不但消耗大量的系统调用,而且在异常情况下可能会卡死,因为ps命令主要是通过读取/proc目录下的文件获取进程相关信息的。

因此本文通过为linux内核增加系统调用,实现一次系统调用获取系统进程数。

 本文使用内核版本:5.5.0

首先在arch/x86/entry/syscalls/syscall_64.tbl增加系统调用表,当前系统调用号已经到了547,因此我们使用的系统调用号从548开始。

9ef2da2979c6e2630e34cf4562417b92.png

在include/linux/syscalls.h增加系统调用函数声明

b71eecaa256c8963c1fcee91cd67aced.png

在kernel/sys.c增加函数定义

4561af43e5c812a6ecd15177eee6f57a.png

内核每个进程的结构(PCB)是task_struct,用链表进行管理。因此只需要遍历链表获取链表长度就是进程数。

make menuconfig (load->save->exit)

make –j8 (8是机器的cpu核数,具体根据机器配置设置)

make modules

make modules_install

make install

查看/lib/modules目录下是否生成新内核

 a0e46b98da09614a5cf3dda8429fbfe4.png

设置启动引导,启动默认使用5.5内核启动。

1573dc6210a8a2f77dca1626b48485cd.png

重启系统。。。。。。

查看系统内核版本,已经是最新内核了

a9a9fb10bf76f68ccdf2566bf36a0752.png

OK,接下来编译测试程序t.c

测试程序如下:

#include

#include

#include

int main(int argc, char* argv[])

{

    intproc_count = syscall(548);

   printf("current system has process counts: %ld\n",proc_count);

   return 0;

}

注:由于没有修改GLIBC,所以测试程序直接通过系统调用号调用。

编译:gcc –o t t.c

测试结果:

 1c82c987eee810a853932e3382c22b17.png

和ps的耗时对比:

c6f05f06b5318bcdc2dd3bfc8482af27.png

可能有些人看到上面时间相差不大,主要是由于我自己的测试机没有业务进程,当有成千上万个进程的时候,耗时还是比较明显的。

总结:本文主要通过增加系统调用方式获取当前系统的进程数,之前都是通过ps获取进程数信息,但ps消耗系统性能,而且当系统异常时可能出现卡住问题,不靠谱。但通过增加系统调用,直接获取PCB链表的长度,大大减少了系统调用,提高了效率,减少了性能损耗。

其实之前一直想这个问题怎么去实现,但一直没有动手操作过,花了2个小时(编译内核比较久,而且中间又出现过失败)才搞定。

其实除了这种方法,还有其他方式(不编译内核)可以实现,那就是增加内核模块(KO),通过增加KO也是可以实现的。

另外,在内核安全方面,通过增加特定系统调用捕获恶意访问或调用,实现类似audit审计系统及时发现异常;另外也可以通过增加系统调用和KO实现截获系统调用(例如挖矿程序),及时发现是否有人利用线上机器进行挖矿。(PS:请将技术用在正道上^_^)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值