Есть ли способ проверить, соответствует ли данный pid любому процессу в пространстве ядра? - PullRequest
0 голосов
/ 30 апреля 2020

Есть ли способ проверить, соответствует ли данный PID какому-либо процессу в пространстве ядра?

Я создаю системный вызов, который изменяет вес настраиваемого взвешенного циклического планировщика.

I хотел бы проверить перед вызовом 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;
}

1 Ответ

2 голосов
/ 30 апреля 2020

Проверка возвращаемого значения 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_struct, чтобы избежать условий гонки (поскольку, как видно из вашего кода, ваш системный вызов может спать). После этого вы можете использовать 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;.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...