pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns) {

if (pid && ns->level <= pid->level) {

upid = &pid->numbers[ns->level]; if (upid->ns == ns)

return nr;

Because a parent namespace sees PIDs in child namespaces, but not vice versa, the kernel has to ensure that the current namespace level is less than or equal to the level in which the local PID was generated.

It is also important to note that the kernel need only worry about generating global PIDs: All other ID types in the global namespace will be mapped to PIDs, so there is no need to generate, for instance, global TGIDs or SIDs.

Instead of using pid_nr_ns in the second step, the kernel could also employ one of these auxiliary functions:

□ pid_vnr returns the local PID seen from the namespace to which the ID belongs.

□ pid_nr obtains the global PID as seen from the init process.

Both rely on pid_nr_ns and automatically select the proper level: 0 for the global PID, and pid->level for the local one.

The kernel provides several helper functions that combine the described steps: kernel/pid.c pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)

Their meaning is obvious from the function names, so we need not add anything further.

Now let us turn our attention to how the kernel can convert a numerical PID together with the namespace into a pid instance. Again two steps are required:

1. To determine the pid instance (the in-kernel representation of a PID) given the local numerical PID of a process and the associated namespace (the userspace representation of a PID), the kernel must employ a standard hashing scheme: First, the array index in pid_hash is computed from the PID and namespace pointers,5 and then the hash list is traversed until the desired element has been found. This is handled by the auxiliary function find_pid_ns:

Continue reading here: Kernelpidc

Was this article helpful?

0 0