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

前言

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

(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

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

执行命令

vim include/linux/syscalls.h 

添加

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

实现系统调用服务例程

执行命令:

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);
    if(flag == 1)
    {
        set_user_nice(task, nicevalue);/* 修改进程nice值 */
       /* printk("修改后的nice值:%d\n", nicevalue);*/
        n = task_nice(task);
        copy_to_user(nice,&n,sizeof(n));
        copy_to_user(prio,&p,sizeof(p));
        return 0;  
    }
    else if(flag == 0)
    {
       /* printk("该进程的nice值为%d\n", n);
        printk("进程优先级: %d\n", p);*/
        copy_to_user(nice,&n,sizeof(n));
        copy_to_user(prio,&p,sizeof(p));
        return 0;
    }
    return EFAULT;

}

解释一下:注释掉的是输出到内核,不注释掉可以通过dmesg 查看。

编译内核

这个已经在之前的博文中写到了,可以查看
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
运行截图

再次查看修改后的

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

猜你喜欢

转载自blog.csdn.net/babybabyup/article/details/79839734