Commit 2894d650cd9715d00ca196c711265819ef6ebd2d

Authored by Sukadev Bhattiprolu
Committed by Linus Torvalds
1 parent baf8f0f82d

pid namespaces: define and use task_active_pid_ns() wrapper

With multiple pid namespaces, a process is known by some pid_t in every
ancestor pid namespace.  Every time the process forks, the child process also
gets a pid_t in every ancestor pid namespace.

While a process is visible in >=1 pid namespaces, it can see pid_t's in only
one pid namespace.  We call this pid namespace it's "active pid namespace",
and it is always the youngest pid namespace in which the process is known.

This patch defines and uses a wrapper to find the active pid namespace of a
process.  The implementation of the wrapper will be changed in when support
for multiple pid namespaces are added.

Changelog:
	2.6.22-rc4-mm2-pidns1:
	- [Pavel Emelianov, Alexey Dobriyan] Back out the change to use
	  task_active_pid_ns() in child_reaper() since task->nsproxy
	  can be NULL during task exit (so child_reaper() continues to
	  use init_pid_ns).

	  to implement child_reaper() since init_pid_ns.child_reaper to
	  implement child_reaper() since tsk->nsproxy can be NULL during exit.

	2.6.21-rc6-mm1:
	- Rename task_pid_ns() to task_active_pid_ns() to reflect that a
	  process can have multiple pid namespaces.

Signed-off-by: Sukadev Bhattiprolu <sukadev@us.ibm.com>
Acked-by: Pavel Emelianov <xemul@openvz.org>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Cedric Le Goater <clg@fr.ibm.com>
Cc: Dave Hansen <haveblue@us.ibm.com>
Cc: Serge Hallyn <serue@us.ibm.com>
Cc: Herbert Poetzel <herbert@13thfloor.at>
Cc: Kirill Korotaev <dev@sw.ru>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 5 changed files with 11 additions and 5 deletions Side-by-side Diff

... ... @@ -776,7 +776,7 @@
776 776 * so it is safe to do it under read_lock.
777 777 */
778 778 if (unlikely(tsk->group_leader == child_reaper(tsk)))
779   - tsk->nsproxy->pid_ns->child_reaper = tsk;
  779 + task_active_pid_ns(tsk)->child_reaper = tsk;
780 780  
781 781 zap_other_threads(tsk);
782 782 read_unlock(&tasklist_lock);
... ... @@ -91,7 +91,8 @@
91 91 LOAD_INT(a), LOAD_FRAC(a),
92 92 LOAD_INT(b), LOAD_FRAC(b),
93 93 LOAD_INT(c), LOAD_FRAC(c),
94   - nr_running(), nr_threads, current->nsproxy->pid_ns->last_pid);
  94 + nr_running(), nr_threads,
  95 + task_active_pid_ns(current)->last_pid);
95 96 return proc_calc_metrics(page, start, off, count, eof, len);
96 97 }
97 98  
include/linux/pid_namespace.h
... ... @@ -39,6 +39,11 @@
39 39 kref_put(&ns->kref, free_pid_ns);
40 40 }
41 41  
  42 +static inline struct pid_namespace *task_active_pid_ns(struct task_struct *tsk)
  43 +{
  44 + return tsk->nsproxy->pid_ns;
  45 +}
  46 +
42 47 static inline struct task_struct *child_reaper(struct task_struct *tsk)
43 48 {
44 49 return init_pid_ns.child_reaper;
... ... @@ -87,7 +87,7 @@
87 87 goto out_ipc;
88 88 }
89 89  
90   - new_nsp->pid_ns = copy_pid_ns(flags, tsk->nsproxy->pid_ns);
  90 + new_nsp->pid_ns = copy_pid_ns(flags, task_active_pid_ns(tsk));
91 91 if (IS_ERR(new_nsp->pid_ns)) {
92 92 err = PTR_ERR(new_nsp->pid_ns);
93 93 goto out_pid;
... ... @@ -214,7 +214,7 @@
214 214 int nr = -1;
215 215 struct pid_namespace *ns;
216 216  
217   - ns = current->nsproxy->pid_ns;
  217 + ns = task_active_pid_ns(current);
218 218 pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL);
219 219 if (!pid)
220 220 goto out;
... ... @@ -364,7 +364,7 @@
364 364 pid = find_pid(nr);
365 365 if (pid)
366 366 break;
367   - nr = next_pidmap(current->nsproxy->pid_ns, nr);
  367 + nr = next_pidmap(task_active_pid_ns(current), nr);
368 368 } while (nr > 0);
369 369  
370 370 return pid;