sys_kill
не существует для архитектур, использующих оболочки syscall (те архитектуры, которые определяют CONFIG_ARCH_HAS_SYSCALL_WRAPPER
). Даже если он существует, следует соблюдать рекомендации из "include / linux / syscalls.h":
* Please note that these prototypes here are only provided for information
* purposes, for static analysis, and for linking from the syscall table.
* These functions should not be called elsewhere from kernel code.
Кроме того, определение функции asmlinkage int sys_get_tag(int pid)
будет неэффективным на тех архитектурах, которые используют перенос syscall. Чтобы работать на всех архитектурах, и поскольку он имеет один параметр, он должен быть записан как SYSCALL_DEFINE1(get_tag, int, pid)
.
. Нет необходимости отправлять сигнал задаче из пространства ядра, чтобы определить, существует ли она. , Любая найденная задача существует, хотя найденная задача может быть помечена как мертвая, и, возможно, такие задачи должны игнорироваться системным вызовом OP. Это можно сделать, проверив p->state & TASK_DEAD
.
Вызовы на find_task_by_vpid
должны быть защищены с помощью rcu_read_lock()
, и если ссылка на структуру задачи не увеличена на get_task_struct(task)
перед соответствующим rcu_read_unlock()
, структура задачи найдено больше не действует. Существует функция find_get_task_by_vpid
, которая объединяет эффекты find_task_by_vpid
и get_task_struct
с правильной блокировкой RCU.
Вместо того, чтобы возвращать -1
, системный вызов должен возвращать соответствующее отрицательное значение errno
. Это заставит пользовательский системный вызов вернуть -1
и установить переменную errno
. Если процесс не может быть найден, соответствующее значение errno
равно ESRCH
, поэтому реализация системного вызова ядра должна возвращать -ESRCH
, если процесс не найден.
Вот две возможные реализации Системный вызов. Первый использует блокировку RCU напрямую:
SYSCALL_DEFINE1(get_tag, int, pid)
{
struct task_struct *p; // pointer to the struct
int rc = -ESRCH; // default return value when not found
rcu_read_lock();
p = find_task_by_vpid(pid); // p = process found by PID
if (p && !(p->state & TASK_DEAD)) // process exists and is not dead
rc = p->tag; // the tag we are looking for
rcu_read_unlock();
return rc;
}
Второй использует find_get_task_vpid
и put_task_struct
вместо явной блокировки RCU (блокировка и разблокировка RCU выполняется в рамках вызова к find_get_task_vpid
):
SYSCALL_DEFINE1(get_tag, int, pid)
{
struct task_struct *p; // pointer to the struct
int rc = -ESRCH; // default return value when not found
p = find_get_task_by_vpid(pid); // p = process found by PID
if (p) { // process exists ...
if (!(p->state & TASK_DEAD)) // ... and is not dead
rc = p->tag; // the tag we are looking for
put_task_struct(p);
}
return rc;
}