int fastcall attach_pid(struct task_struct *task, enum pid_type type, struct pid *pid)
struct pid_link *link;
link = &task->pids[type]; link->pid = pid;
hlist_add_head_rcu(&link->node, &pid->tasks[type]); return 0;
A connection is made in both directions: The task structure can access the pid instance via task_struct->pids[type]->pid. Starting from the pid instance, the task can be found by iterating over the tasks[type] list. hlist_add_head_rcu is a standard function to traverse a list that additionally ensures as per the RCU mechanism (see Chapter 5) that the iteration is safe against race conditions that could arise when other kernel components manipulate the list concurrently.
The kernel provides a number of auxiliary functions to manipulate and scan the data structures described above. Essentially the kernel must be able to fulfill two different tasks:
1. Given a local numerical ID and the corresponding namespace, find the task structure that is described by this tuple.
2. Given a task structure, an ID type, and a namespace, obtain the local numerical ID.
Let us first concentrate on the case in which a task_struct instance must be converted into a numerical ID. This is a two-step process:
1. Obtain the pid instance associated with the task structure. The auxiliary functions task_pid, task_tgid, task_pgrp, and task_session are provided for the different types of IDs. This is simple for PIDs:
Continue reading here: Kernelpidc
Was this article helpful?