credentials(7) идентификаторы процесса

ОПИСАНИЕ

ID (PID) процесса

Каждый процесс имеет уникальный неотрицательный целочисленный идентификатор (PID), который ему назначается при создании с помощью fork(2). Процесс может узнать свой PID с помощью вызова getpid(2). PID имеет тип pid_t (определён в <sys/types.h>).

PID используется в различных системных вызовах для указания процесса, с которым работает вызов, например: kill(2), ptrace(2), setpriority(2) setpgid(2), setsid(2), sigqueue(3) и waitpid(2).

PID процесса сохраняется после execve(2).

Родительский ID (PPID) процесса

ID родительского процесса — это ID процесса, который создал данный процесс с помощью fork(2). Процесс может получить свой PPID с помощью getppid(2). PPID имеет тип pid_t.

PPID процесса сохраняется после execve(2).

ID группы процессов и сеанса

У каждого процесса есть ID сеанса и ID группы процессов; они имеют тип pid_t. Процесс может получить ID своего сеанса с помощью getsid(2), а ID своей группы процессов с помощью getpgrp(2).

Потомок, создаваемый с помощью fork(2), наследует ID сеанса и группы процессов своего родителя. Идентификатор сеанса и группы сохраняется после execve(2).

Сеансы и группы процессов — это абстракции, предназначенные для поддержки управления заданиями оболочки. Группа процессов (иногда называемая «заданием» (job)) — это набор процессов, у которых одинаковый ID группы процессов; оболочка создаёт новую группу процессов для процессов, используемых в одной команде или конвейере (например, два процесса, созданные командой «ls | wc», помещаются в одну группу процессов). Членство в группе процессов может быть определено с помощью setpgid(2). Процесс, чей ID процесса совпадает с его ID группы процессов, называется лидером группы процессов этой группы.

Сеанс — это набор процессов, у которых одинаковый ID сеанса. Все члены группы процессов также имеют одинаковый ID сеанса (т. е., все члены группы процессов всегда принадлежат одному сеансу; таким образом, сеансы и группы процессов формируют из процессов жёсткую двухуровневую иерархию). Новый сеанс создаётся при вызове процессом setsid(2), который создаёт новый сеанс, чей ID сеанса совпадает с PID процесса, который вызвал setsid(2). Создатель сеанса также называется лидером сеанса.

Все процессы в сеансе используют общий управляющий терминал. Управляющий терминал назначается в момент, когда лидер сеанса впервые открывает терминал (если при вызове open(2) не указан флаг O_NOCTTY). Терминал может быть управляющим терминалом не более чем для одного сеанса.

В сеансе может быть только одно активное задание (foreground job); все остальные задания в сеансе считаются фоновыми заданиями (background jobs). Только активное задание может читать данные из терминала; когда процесс в фоне пытается прочитать данные с терминала, его группе процессов посылается сигнал SIGTTIN, который приостанавливает (suspends) задание. Если у терминала установлен флаг TOSTOP (смотрите termios(3)), то только активное задание может писать в терминал; попытка записи из фонового задания приводит к генерации сигнала SIGTTOU, который приостанавливает задание. Если нажимаются клавиши терминала, которые генерируют сигнал (например клавиша interrupt, обычно это комбинация control-C), то сигнал посылается процессам в активном задании.

С членами группы процессов могут работать различные системные вызовы и библиотечные функции, такие как: kill(2), killpg(2), getpriority(2), setpriority(2), ioprio_get(2), ioprio_set(2), waitid(2) и waitpid(2). Также смотрите обсуждение операций F_GETOWN, F_GETOWN_EX, F_SETOWN и F_SETOWN_EX в fcntl(2).

Идентификаторы пользователя и группы

С каждым процессом связаны идентификаторы различных групп и пользователя. Эти ID представляются в виде целых чисел с типами gid_t и uid_t, соответственно (определены в <sys/types.h>).

В Linux каждый процесс имеет следующие идентификаторы пользователя и групп:

*
ID реального пользователя (real user) и ID реальной группы. Эти ID определяют кто владелец процесса. ID реального пользователя (группы) процесса можно получить с помощью getuid(2) (getgid(2)).
*
ID эффективного пользователя (effective user) и ID эффективной группы. Эти ID используются ядром для определения прав, которые будет иметь процесс при доступе к общим ресурсам, таким как очереди сообщений, общая память и семафоры. В большинстве систем UNIX эти ID также определяют права доступа к файлам. Однако в Linux для этой задачи используются ID файловой системы, описанные далее. ID эффективного пользователя (группы) процесса можно получить с помощью geteuid(2) (getegid(2)).
*
Сохранённые set-user-ID и set-group-ID. Эти ID используются в программах с set-user-ID и set-group-ID битами для сохранения копии соответствующих эффективных ID, которые были установлены в момент запуска программы (смотрите execve(2)). Программа с set-user-ID может повышать и понижать права, переключая свой ID эффективного пользователя туда и обратно между значениями её ID реального пользователя и сохранённым set-user-ID. Такое переключение производится с помощью вызовов seteuid(2), setreuid(2) или setresuid(2). Программа с set-group-ID выполняет аналогичные задачи с помощью setegid(2), setregid(2) или setresgid(2). Сохранённый set-user-ID (set-group-ID) процесса можно получить с помощью getresuid(2) (getresgid(2)).
*
ID пользователя файловой системы и ID группы файловой системы (есть только в Linux). Эти ID, совместно с ID дополнительных групп (supplementary group), описанных ниже, используются для определения прав доступа к файлам; подробней смотрите path_resolution(7). Каждый раз при изменении ID эффективного пользователя (группы) ядро также автоматически изменяет ID пользователя (группы) файловой системы на то же значение. Следовательно, ID файловой системы, обычно, равны соответствующим эффективным ID, а семантика проверки прав доступа к файлам в Linux такая же как и у других систем UNIX. ID файловой системы можно сделать отличным от эффективных ID с помощью вызова setfsuid(2) и setfsgid(2).
*
ID дополнительных групп (supplementary group). Определяет ID добавочных групп, которые используются при проверке доступа к файлам и другим общим ресурсам. В ядрах Linux до версии 2.6.4 процесс может быть членом 32 дополнительных групп; начиная с версии 2.6.4 процесс может быть членом 65536 дополнительных групп. В помощью вызова sysconf(_SC_NGROUPS_MAX) можно узнать количество дополнительных групп, в которых процесс может быть членом. Процесс может получить список ID дополнительных групп с помощь getgroups(2), и изменить этот список с помощью setgroups(2).

Дочерний процесс, созданный fork(2), наследует копии ID пользователя и группы своего предка. При execve(2) сохраняются ID реального пользователя и группы процесса, а также ID дополнительных групп; эффективный и сохранённый ID могут измениться (описано в execve(2)).

Кроме целей, отмеченных выше, идентификаторы пользователя процесса также используются:

*
при определении права на отправку сигналов (смотрите kill(2));
*
при определении права на установку параметров планировщика процесса (значение уступчивости, политика и приоритет планирования в реальном времени, увязывание ЦП, приоритет ввода-вывода) с помощью setpriority(2), sched_setaffinity(2), sched_setscheduler(2), sched_setparam(2), sched_setattr(2) и ioprio_set(2);
*
при проверке ограничения по ресурсам (смотрите getrlimit(2));
*
при проверке ограничения на количество экземпляров inotify, которые процесс может создать (смотрите inotify(7)).

СООТВЕТСТВИЕ СТАНДАРТАМ

ID процесса, ID родительского процесса, ID группы процессов и ID сеанса определены в POSIX.1. ID реального, эффективного и сохранённого пользователя и группы, а также ID дополнительных групп определены в POSIX.1. ID пользователя и группы файловой системы являются расширением Linux.

ЗАМЕЧАНИЯ

Согласно спецификации на нити POSIX требуется, чтобы идентификаторы были одинаковыми у всех нитей процесса. Однако на уровне ядра в Linux ведутся отдельные идентификаторы пользователя и группы для каждой нити. Реализация нитей NPTL выполняет дополнительные действия, чтобы любое изменение идентификаторов пользователя и группы (например, с помощью setuid(2), setresuid(2)) отражалось на всех нитях POSIX процесса. Дополнительную информацию смотрите в nptl(7).