pid namespaces: define and use task_active_pid_ns() wrapper
authorSukadev Bhattiprolu <sukadev@us.ibm.com>
Fri, 19 Oct 2007 06:39:49 +0000 (23:39 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 19 Oct 2007 18:53:37 +0000 (11:53 -0700)
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>
fs/exec.c
fs/proc/proc_misc.c
include/linux/pid_namespace.h
kernel/nsproxy.c
kernel/pid.c

index 0b09447ae0404eac3c70b27db9224ee5598066b1..6ffb769ed955cc95d680bcf78961e68285e40b2c 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -776,7 +776,7 @@ static int de_thread(struct task_struct *tsk)
         * so it is safe to do it under read_lock.
         */
        if (unlikely(tsk->group_leader == child_reaper(tsk)))
-               tsk->nsproxy->pid_ns->child_reaper = tsk;
+               task_active_pid_ns(tsk)->child_reaper = tsk;
 
        zap_other_threads(tsk);
        read_unlock(&tasklist_lock);
index d6dc72c78bc1bd9a1d36fb29e6728450fcbb34e5..e0d064e9764ef55422cf79119b7624b3e6b87373 100644 (file)
@@ -91,7 +91,8 @@ static int loadavg_read_proc(char *page, char **start, off_t off,
                LOAD_INT(a), LOAD_FRAC(a),
                LOAD_INT(b), LOAD_FRAC(b),
                LOAD_INT(c), LOAD_FRAC(c),
-               nr_running(), nr_threads, current->nsproxy->pid_ns->last_pid);
+               nr_running(), nr_threads,
+               task_active_pid_ns(current)->last_pid);
        return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
index c471c0c6e9cee28218ed88598d9f55e1c36d620c..d10cb5f75c0621d5e41de188005f61f55c7d3ff0 100644 (file)
@@ -39,6 +39,11 @@ static inline void put_pid_ns(struct pid_namespace *ns)
        kref_put(&ns->kref, free_pid_ns);
 }
 
+static inline struct pid_namespace *task_active_pid_ns(struct task_struct *tsk)
+{
+       return tsk->nsproxy->pid_ns;
+}
+
 static inline struct task_struct *child_reaper(struct task_struct *tsk)
 {
        return init_pid_ns.child_reaper;
index ac99837e7a04c53304a46f72ac57f13d4e3a855d..e981c61304f15980eb4010945bdd99f152000045 100644 (file)
@@ -87,7 +87,7 @@ static struct nsproxy *create_new_namespaces(unsigned long flags,
                goto out_ipc;
        }
 
-       new_nsp->pid_ns = copy_pid_ns(flags, tsk->nsproxy->pid_ns);
+       new_nsp->pid_ns = copy_pid_ns(flags, task_active_pid_ns(tsk));
        if (IS_ERR(new_nsp->pid_ns)) {
                err = PTR_ERR(new_nsp->pid_ns);
                goto out_pid;
index 42de9af8c5247b6863bab82a85b6a6e3701188c2..78c0dbffde654c22e4f6c14482e6aaf3f89e1147 100644 (file)
@@ -214,7 +214,7 @@ struct pid *alloc_pid(void)
        int nr = -1;
        struct pid_namespace *ns;
 
-       ns = current->nsproxy->pid_ns;
+       ns = task_active_pid_ns(current);
        pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL);
        if (!pid)
                goto out;
@@ -364,7 +364,7 @@ struct pid *find_ge_pid(int nr)
                pid = find_pid(nr);
                if (pid)
                        break;
-               nr = next_pidmap(current->nsproxy->pid_ns, nr);
+               nr = next_pidmap(task_active_pid_ns(current), nr);
        } while (nr > 0);
 
        return pid;