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

Is there a way to check whether a given pid matches any process in kernel space?

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

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

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

这是因为如果使用了无效的 PID,我的虚拟机就会崩溃。所以我想检查一下 return 错误值 -ESRCH 返回给用户 space.

是否有检查功能?

或者是否可以通过检查find_task_by_vpid(pid) == NULL来判断PID是否有效?当 pid 无效时,我找不到指定 find_task_by_vpid(pid) 的 return 的文档。

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;
}

检查 find_task_by_vpid() 的 return 值应该足以确保 pid 有效。如果不是,它一开始就不会有关联的 task_struct。如果您需要确认,这正是 getsid syscall 处理从用户空间传递的 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() instead of find_task_by_vpid(). This function will call get_task_struct() for you, incrementing the task_struct refcount to avoid race conditions (since as it seems from your code, your syscall can sleep). After that, you can use 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 直接做 tsk->wrr.weight = weight;.