欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

添加一个系统调用,实现对指定进程的nice值的修改或读取功能,并返回系统最新的nice值即优先级prio。-Linux(2)

程序员文章站 2022-05-02 20:43:54
...

前言

  • 本文的所有操作已经实践过的,只要每一步照做,一定会跑通的。

(1)添加一个系统调用,实现对指定进程的nice值的修改或读取功能,并返回系统最新的nice值即优先级prio。
建议调用原型为:
int mysetnice(pid_t pid, int flag, int nicevalue,void_user*prio,void_user*nice)
参数含义:

  • pid:进程ID
  • flag:若值为0,表示读取nice值;若值为1表示修改nice值。
  • prio,nice:指向进程当前优先级及nice值。
  • 返回值:系统调用成功时返回0,失败时返回错误码EFAULT。

(2)写一个简单的应用程序测试(3)添加的系统调用

添加系统调用

添加系统调用的主要步骤为:

  • 修改系统调用表
  • 申明系统调用服务例程原型
  • 实现系统调用服务例程

修改系统调用表

以root用户在linux-4.16 目录下工作:

vim arch/x86/entry/syscalls/syscall_64.tbl

添加系统调用号334 的系统调用,系统调用名为mysetnice,服务例程入口为sys_mysetnice
截图如下:
添加一个系统调用,实现对指定进程的nice值的修改或读取功能,并返回系统最新的nice值即优先级prio。-Linux(2)

申明系统调用服务例程原型

执行命令

vim include/linux/syscalls.h 

添加

asmlinkage long sys_mysetnice(pid_t pid,int flag,int nicevalue,void __user*prio,void __user*nice);

添加一个系统调用,实现对指定进程的nice值的修改或读取功能,并返回系统最新的nice值即优先级prio。-Linux(2)

实现系统调用服务例程

执行命令:

vim kernel/sys.c 

添加

SYSCALL_DEFINE5(mysetnice,pid_t,pid,int,flag,int,nicevalue,void __user*,prio,void __user*,nice){
    struct pid * kpid;
    struct task_struct * task;
    kpid = find_get_pid(pid);/* 返回pid */
    task = pid_task(kpid, PIDTYPE_PID);/* 返回task_struct */
    int n;
    n = task_nice(task);/* 返回进程当前nice值 */
    int p;
    p = task_prio(task);/*返回进程当前prio值*/
    if(flag == 1)
    {
        set_user_nice(task, nicevalue);/* 修改进程nice值 */
        n = task_nice(task);/*重新取得进程nice值*/
        copy_to_user(nice,&n,sizeof(n));/*将nice值拷贝到用户空间*/
        copy_to_user(prio,&p,sizeof(p));/*将prio值拷贝到用户空间*/
        return 0;  
    }
    else if(flag == 0)
    {
        copy_to_user(nice,&n,sizeof(n));/*将nice值拷贝到用户空间*/
        copy_to_user(prio,&p,sizeof(p));/*将prio值拷贝到用户空间*/
        return 0;
    }
    return EFAULT;

}

添加一个系统调用,实现对指定进程的nice值的修改或读取功能,并返回系统最新的nice值即优先级prio。-Linux(2)

编译内核

这个已经在之前的博文中写到了,可以查看
https://blog.csdn.net/babybabyup/article/details/79720082

慢慢等编译完成

编写测试函数

  • 服务例程:
    SYSCALL_DEFINE5(mysetnice,pid_t,pid,int,flag,int,nicevalue,void __user*,prio,void __user*,nice) ,系统调用号为334。在传参数的时候要格外注意。

  • 具体思路:手动设定pid(用ps命令查看),flag,nice,然后输出最新的prio以及nice。

  • 具体函数:
#define _GNU_SOURCE
#include <unistd.h>
#include<sys/syscall.h>
#include<stdio.h>
#include<stdlib.h>
int main(){
    pid_t pid;
    int nicevalue;
    int flag;
    int p = 0;
    int n = 0;
    int *prio;
    int *nice;
    prio = &p;
    nice = &n;
    /*
 *     获取pid
 *         */
    printf("请输入pid:\n");
    scanf("%d",&pid);
    /*
 *     获取nice;
 *         */
    printf("pid赋值成功\n请输入nice:\n");
    scanf("%d",&nicevalue);
    /*
 *     获取flag;
 *         */
    printf("nice赋值成功\n请输入flag:\n");
    scanf("%d",&flag);
    /*
 *     调用添加的系统调用;
 *         */
    syscall(334,pid,flag,nicevalue,prio,nice);
    /*
 *     输出最新的prio以及nice;
 *         */
    printf("现在的nice为%d\n,prio为%d\n",n,p);
    return 0;
}

nice的取值范围为-20~19
运行截图
添加一个系统调用,实现对指定进程的nice值的修改或读取功能,并返回系统最新的nice值即优先级prio。-Linux(2)
再次查看修改后的
添加一个系统调用,实现对指定进程的nice值的修改或读取功能,并返回系统最新的nice值即优先级prio。-Linux(2)

今天看了整个下午的源代码,但是现在还是两眼一抹黑。。。验收的时候还神奇的过了。。部分源代码可以参考一下
https://blog.csdn.net/babybabyup/article/details/80102576
找源代码找的好辛苦。。。