Chapter 2: Process Management and Scheduling
namespace they are visible in. This must be reflected in the data structures. We have to distinguish
between local and global IDs:
❑ Global IDsare identification numbers that are valid within the kernel itself and in the initial
namespace to which theinittasks started during boot belongs. For each ID type, a given global
identifier is guaranteed to be unique in the whole system.
❑ Local IDsbelong to a specific namespace and are not globally valid. For each ID type, they are
valid within the namespace to which they belong, but identifiers of identical type may appear
with the same ID number in adifferentnamespace.
The global PID and TGID are directly stored in the task struct, namely, in the elementspidandtgid:
<sched.h>
struct task_struct {
...
pid_t pid;
pid_t tgid;
...
}
Both are of typepid_t, which resolves to the type__kernel_pid_t; this, in turn, has to be defined by
each architecture. Usually anintis used, which means that 2^32 different IDs can be used simultaneously.
The session and process group IDs are not directly contained in the task structure itself, but in the struc-
ture used for signal handling.task_struct->signal->__sessiondenotes the global SID, while the
global PGID is stored intask_struct->signal->__pgrp. The auxiliary functionsset_task_sessionand
set_task_pgrpare provided to modify the values.
ManagingPIDs
In addition to these two fields, the kernel needs to find a way to manage all local per-namespace quanti-
ties, as well as the other identifiers like TID and SID. This requires several interconnected data structures
and numerous auxiliary functions that are discussed in the following.
Data Structures
Below I use the term ID to refer toanyprocess identifier. I specify the identifier type explicitly (e.g., TGID
for ‘‘thread group identifier’’) where this is necessary.
A small subsystem known as apid allocatoris available to speed up the allocation of new IDs. Besides,
the kernel needs to provide auxiliary functions that allow for finding the task structure of a process by
reference to an ID and its type, and functions that convert between the in-kernel representation of IDs
and the numerical values visible to userspace.
Before I introduce the data structures required to represent IDs themselves, I need to discuss how PID
namespaces are represented. The elements required for our purposes are as follows:
<pid_namespace.h>
struct pid_namespace {
...
struct task_struct *child_reaper;