首页 > 解决方案 > 有没有办法检查给定的 pid 是否与内核空间中的任何进程匹配?

问题描述

有没有办法检查给定的 PID 是否与内核空间中的任何进程匹配?

我正在构建一个系统调用来更改自定义加权循环调度程序的权重。

find_task_by_vpid(pid)如果 PID 无效(即没有具有此 PID 值的进程),我想在调用之前进行检查以避免调用该函数。

这是因为如果使用了无效的 PID,我的虚拟机就会崩溃。所以我想做一个检查并将错误值-ESRCH返回给用户空间。

有检查功能吗?

或者是否可以检查是否find_task_by_vpid(pid) == NULL确定PID是否有效?我找不到指定无效find_task_by_vpid(pid)时返回的内容的文档。pid

SYSCALL_DEFINE2(set_wrr_weight, pid_t, pid, int, weight){
   struct sched_wrr_entity *wrr_se;
   // I want to do a check here to see if given pid is valid or not
   wrr_se = &find_task_by_vpid(pid)->wrr;
   wrr_se->wrr_weight = weight;
   return 0;
}

标签: ckernelsystem-callspid

解决方案


检查的返回值find_task_by_vpid()应该足以确保它pid是有效的。如果不是,它一开始就没有关联task_struct。如果您需要确认,这正是getsid系统调用处理从用户空间传递的 PID 的方式:

// ...
    retval = -ESRCH;
    p = find_task_by_vpid(pid);
    if (!p)
        goto out;
// ...
out:
    rcu_read_unlock();
    return retval;
}

但是,您的代码中有一个不同的问题:据我所知,您没有task_struct正确处理。您应该使用find_get_task_by_vpid()而不是find_task_by_vpid(). 这个函数会调用get_task_struct()你,增加task_structrefcount 以避免竞争条件(因为从你的代码看来,你的系统调用可以休眠)。之后,您可以使用put_task_struct()来减少引用计数。

像这样的东西:

SYSCALL_DEFINE2(set_wrr_weight, pid_t, pid, int, weight) {
    struct sched_wrr_entity *wrr_se;
    struct task_struct *tsk;

    tsk = find_get_task_by_vpid(pid);
    if (!tsk)
        return -ESRCH;

    wrr_se = &tsk->wrr;
    wrr_se->wrr_weight = weight;

    put_task_struct(tsk);
    return 0;
}

顺便说一句,我不知道你是否在做wrr_se = &tsk->wrr;,因为你在代码的其他地方需要它,但如果你不这样做,那么你应该可以weight直接设置 do tsk->wrr.weight = weight;


推荐阅读