From: "Serge E. Hallyn" <serue@us.ibm.com>
To: Dave Hansen <haveblue@us.ibm.com>
Cc: "Serge E. Hallyn" <serue@us.ibm.com>,
"Eric W. Biederman" <ebiederm@xmission.com>,
Andi Kleen <ak@suse.de>,
linux-kernel@vger.kernel.org, herbert@13thfloor.at, dev@sw.ru,
sam@vilain.net, xemul@sw.ru, clg@fr.ibm.com, frankeh@us.ibm.com
Subject: Re: [PATCH 2/9] nsproxy: incorporate fs namespace
Date: Fri, 12 May 2006 14:12:30 -0500 [thread overview]
Message-ID: <20060512191230.GA17153@sergelap.austin.ibm.com> (raw)
In-Reply-To: <1147448681.6623.10.camel@localhost.localdomain>
Quoting Dave Hansen (haveblue@us.ibm.com):
> On Fri, 2006-05-12 at 10:24 -0500, Serge E. Hallyn wrote:
> >
> > - exit_utsname(current);
> > - exit_namespace(current);
> > - exit_nsproxy(current);
> > + exit_task_namespaces(current);
> > current->nsproxy = init_task.nsproxy;
> > - get_nsproxy(current->nsproxy);
> > - get_namespace(current->nsproxy->namespace);
> > - get_uts_ns(current->nsproxy->uts_ns);
> > + get_namespaces(current);
>
> That really cleans up the main path quite a bit. Very nice.
>
> For parity with exit_task_namespaces(), should that be called
> get_task_namespaces()?
Here's a new patch:
Subject: [PATCH 10/11] nsproxy: code cleanup
consolidate nsproxy and namespace copy/get/exit.
Changelog:
renamed get_namespaces(tsk) to get_task_namespaces(tsk).
Signed-off-by: Serge Hallyn <serue@us.ibm.com>
---
include/linux/namespace.h | 8 ----
include/linux/nsproxy.h | 26 +++++--------
kernel/exit.c | 13 +-----
kernel/fork.c | 39 +++++++++----------
kernel/nsproxy.c | 92 ++++++++++++++++++++++++++++++++++++++++++---
5 files changed, 118 insertions(+), 60 deletions(-)
3f3ce98f9c6fc8c3ce31cb170bf281c8eb0d4c6a
diff --git a/include/linux/namespace.h b/include/linux/namespace.h
index d137009..fce3714 100644
--- a/include/linux/namespace.h
+++ b/include/linux/namespace.h
@@ -25,14 +25,6 @@ static inline void put_namespace(struct
__put_namespace(namespace);
}
-static inline void exit_namespace(struct task_struct *p)
-{
- struct namespace *namespace = p->nsproxy->namespace;
- if (namespace) {
- put_namespace(namespace);
- }
-}
-
static inline void get_namespace(struct namespace *namespace)
{
atomic_inc(&namespace->count);
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
index 18fcd8f..6046fc3 100644
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -14,28 +14,24 @@ struct nsproxy {
};
extern struct nsproxy init_nsproxy;
-static inline void get_nsproxy(struct nsproxy *nsp)
+struct nsproxy *dup_namespaces(struct nsproxy *orig);
+int copy_namespaces(int flags, struct task_struct *tsk);
+void get_task_namespaces(struct task_struct *tsk);
+void exit_namespaces(struct nsproxy *ns);
+
+static inline void exit_task_namespaces(struct task_struct *p)
{
- atomic_inc(&nsp->count);
+ struct nsproxy *ns = p->nsproxy;
+ if (ns) {
+ exit_namespaces(p->nsproxy);
+ p->nsproxy = NULL;
+ }
}
-struct nsproxy *clone_nsproxy(struct nsproxy *orig);
-int copy_nsproxy(int flags, struct task_struct *tsk);
-void free_nsproxy(struct nsproxy *nsp);
-
static inline void put_nsproxy(struct nsproxy *nsp)
{
if (atomic_dec_and_test(&nsp->count)) {
kfree(nsp);
}
}
-
-static inline void exit_nsproxy(struct task_struct *p)
-{
- struct nsproxy *nsp = p->nsproxy;
- if (nsp) {
- p->nsproxy = NULL;
- put_nsproxy(nsp);
- }
-}
#endif
diff --git a/kernel/exit.c b/kernel/exit.c
index 921a4b7..bdc273a 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -175,7 +175,6 @@ repeat:
write_unlock_irq(&tasklist_lock);
spin_unlock(&p->proc_lock);
proc_pid_flush(proc_dentry);
- exit_nsproxy(p);
release_thread(p);
call_rcu(&p->rcu, delayed_put_task_struct);
@@ -416,13 +415,9 @@ void daemonize(const char *name, ...)
current->fs = fs;
atomic_inc(&fs->count);
- exit_utsname(current);
- exit_namespace(current);
- exit_nsproxy(current);
+ exit_task_namespaces(current);
current->nsproxy = init_task.nsproxy;
- get_nsproxy(current->nsproxy);
- get_namespace(current->nsproxy->namespace);
- get_uts_ns(current->nsproxy->uts_ns);
+ get_task_namespaces(current);
exit_files(current);
current->files = init_task.files;
@@ -926,9 +921,7 @@ fastcall NORET_TYPE void do_exit(long co
exit_sem(tsk);
__exit_files(tsk);
__exit_fs(tsk);
- exit_utsname(current);
- exit_namespace(current);
- exit_nsproxy(current);
+ exit_task_namespaces(current);
exit_thread();
cpuset_exit(tsk);
exit_keys(tsk);
diff --git a/kernel/fork.c b/kernel/fork.c
index baeef86..f9b607c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -45,7 +45,6 @@
#include <linux/acct.h>
#include <linux/cn_proc.h>
#include <linux/nsproxy.h>
-#include <linux/utsname.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -1062,15 +1061,11 @@ static task_t *copy_process(unsigned lon
goto bad_fork_cleanup_signal;
if ((retval = copy_keys(clone_flags, p)))
goto bad_fork_cleanup_mm;
- if ((retval = copy_nsproxy(clone_flags, p)))
+ if ((retval = copy_namespaces(clone_flags, p)))
goto bad_fork_cleanup_keys;
- if ((retval = copy_utsname(clone_flags, p)))
- goto bad_fork_cleanup_nsproxy;
- if ((retval = copy_namespace(clone_flags, p)))
- goto bad_fork_cleanup_utsname;
retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
if (retval)
- goto bad_fork_cleanup_namespace;
+ goto bad_fork_cleanup_namespaces;
p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
/*
@@ -1157,7 +1152,7 @@ static task_t *copy_process(unsigned lon
spin_unlock(¤t->sighand->siglock);
write_unlock_irq(&tasklist_lock);
retval = -ERESTARTNOINTR;
- goto bad_fork_cleanup_namespace;
+ goto bad_fork_cleanup_namespaces;
}
if (clone_flags & CLONE_THREAD) {
@@ -1170,7 +1165,7 @@ static task_t *copy_process(unsigned lon
spin_unlock(¤t->sighand->siglock);
write_unlock_irq(&tasklist_lock);
retval = -EAGAIN;
- goto bad_fork_cleanup_namespace;
+ goto bad_fork_cleanup_namespaces;
}
p->group_leader = current->group_leader;
@@ -1222,12 +1217,8 @@ static task_t *copy_process(unsigned lon
proc_fork_connector(p);
return p;
-bad_fork_cleanup_namespace:
- exit_namespace(p);
-bad_fork_cleanup_utsname:
- exit_utsname(p);
-bad_fork_cleanup_nsproxy:
- exit_nsproxy(p);
+bad_fork_cleanup_namespaces:
+ exit_task_namespaces(p);
bad_fork_cleanup_keys:
exit_keys(p);
bad_fork_cleanup_mm:
@@ -1570,7 +1561,7 @@ asmlinkage long sys_unshare(unsigned lon
struct files_struct *fd, *new_fd = NULL;
struct sem_undo_list *new_ulist = NULL;
struct nsproxy *new_nsproxy, *old_nsproxy;
- struct uts_namespace *new_uts = NULL;
+ struct uts_namespace *uts, *new_uts = NULL;
check_unshare_flags(&unshare_flags);
@@ -1595,21 +1586,20 @@ asmlinkage long sys_unshare(unsigned lon
if ((err = unshare_semundo(unshare_flags, &new_ulist)))
goto bad_unshare_cleanup_fd;
if ((err = unshare_utsname(unshare_flags, &new_uts)))
- goto bad_unshare_cleanup_fd;
+ goto bad_unshare_cleanup_semundo;
if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist ||
new_uts) {
old_nsproxy = current->nsproxy;
- new_nsproxy = clone_nsproxy(old_nsproxy);
+ new_nsproxy = dup_namespaces(old_nsproxy);
if (!new_nsproxy) {
err = -ENOMEM;
- goto bad_unshare_cleanup_semundo;
+ goto bad_unshare_cleanup_uts;
}
task_lock(current);
current->nsproxy = new_nsproxy;
- put_nsproxy(old_nsproxy);
if (new_fs) {
fs = current->fs;
@@ -1645,13 +1635,20 @@ asmlinkage long sys_unshare(unsigned lon
}
if (new_uts) {
- put_uts_ns(current->nsproxy->uts_ns);
+ uts = current->nsproxy->uts_ns;
current->nsproxy->uts_ns = new_uts;
+ new_uts = uts;
}
task_unlock(current);
+
+ put_nsproxy(old_nsproxy);
}
+bad_unshare_cleanup_uts:
+ if (new_uts)
+ put_uts_ns(new_uts);
+
bad_unshare_cleanup_semundo:
bad_unshare_cleanup_fd:
if (new_fd)
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index 2390afb..d963af9 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -13,8 +13,36 @@
#include <linux/module.h>
#include <linux/version.h>
#include <linux/nsproxy.h>
+#include <linux/namespace.h>
+#include <linux/utsname.h>
-struct nsproxy *clone_nsproxy(struct nsproxy *orig)
+static inline void get_nsproxy(struct nsproxy *ns)
+{
+ atomic_inc(&ns->count);
+}
+
+static inline void get_namespaces(struct nsproxy *ns)
+{
+ get_nsproxy(ns);
+ if (ns->namespace)
+ get_namespace(ns->namespace);
+ if (ns->uts_ns)
+ get_uts_ns(ns->uts_ns);
+}
+
+void get_task_namespaces(struct task_struct *tsk)
+{
+ struct nsproxy *ns = tsk->nsproxy;
+ if (ns) {
+ get_namespaces(ns);
+ }
+}
+
+/*
+ * creates a copy of "orig" with refcount 1.
+ * This does not grab references to the contained namespaces.
+ */
+static inline struct nsproxy *clone_namespaces(struct nsproxy *orig)
{
struct nsproxy *ns;
@@ -26,7 +54,42 @@ struct nsproxy *clone_nsproxy(struct nsp
return ns;
}
-int copy_nsproxy(int flags, struct task_struct *tsk)
+/*
+ * copies the nsproxy, setting refcount to 1, and grabbing a
+ * reference to all contained namespaces. Called from
+ * sys_unshare()
+ */
+struct nsproxy *dup_namespaces(struct nsproxy *orig)
+{
+ struct nsproxy *ns = clone_namespaces(orig);
+
+ if (ns) {
+ if (ns->namespace)
+ get_namespace(ns->namespace);
+ if (ns->uts_ns)
+ get_uts_ns(ns->uts_ns);
+ }
+
+ return ns;
+}
+
+/*
+ * Put refcount on nsproxy and each namespace therein
+ */
+void exit_namespaces(struct nsproxy *ns)
+{
+ if (ns->namespace)
+ put_namespace(ns->namespace);
+ if (ns->uts_ns)
+ put_uts_ns(ns->uts_ns);
+ put_nsproxy(ns);
+}
+
+/*
+ * called from clone. This now handles copy for nsproxy and all
+ * namespaces therein.
+ */
+int copy_namespaces(int flags, struct task_struct *tsk)
{
struct nsproxy *old_ns = tsk->nsproxy;
struct nsproxy *new_ns;
@@ -35,19 +98,36 @@ int copy_nsproxy(int flags, struct task_
if (!old_ns)
return 0;
- get_nsproxy(old_ns);
+ get_namespaces(old_ns);
- if (!(flags & CLONE_NEWNS))
+ if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS)))
return 0;
- new_ns = clone_nsproxy(old_ns);
+ new_ns = clone_namespaces(old_ns);
if (!new_ns) {
err = -ENOMEM;
goto out;
}
+
tsk->nsproxy = new_ns;
+ err = copy_namespace(flags, tsk);
+ if (err) {
+ tsk->nsproxy = old_ns;
+ put_nsproxy(new_ns);
+ goto out;
+ }
+
+ err = copy_utsname(flags, tsk);
+ if (err) {
+ if (new_ns->namespace)
+ put_namespace(new_ns->namespace);
+ tsk->nsproxy = old_ns;
+ put_nsproxy(new_ns);
+ goto out;
+ }
+
out:
- put_nsproxy(old_ns);
+ exit_namespaces(old_ns);
return err;
}
--
1.1.6
next prev parent reply other threads:[~2006-05-12 19:12 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <29vfyljM-1.2006059-s@us.ibm.com>
2006-05-10 2:11 ` [PATCH 2/9] nsproxy: incorporate fs namespace Serge E. Hallyn
2006-05-10 12:46 ` Eric W. Biederman
2006-05-10 13:26 ` Serge E. Hallyn
2006-05-10 19:07 ` Eric W. Biederman
2006-05-10 20:34 ` Serge E. Hallyn
2006-05-10 20:50 ` Eric W. Biederman
2006-05-12 15:24 ` Serge E. Hallyn
2006-05-12 15:44 ` Dave Hansen
2006-05-12 16:54 ` Serge E. Hallyn
2006-05-12 19:12 ` Serge E. Hallyn [this message]
2006-05-12 19:14 ` Serge E. Hallyn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060512191230.GA17153@sergelap.austin.ibm.com \
--to=serue@us.ibm.com \
--cc=ak@suse.de \
--cc=clg@fr.ibm.com \
--cc=dev@sw.ru \
--cc=ebiederm@xmission.com \
--cc=frankeh@us.ibm.com \
--cc=haveblue@us.ibm.com \
--cc=herbert@13thfloor.at \
--cc=linux-kernel@vger.kernel.org \
--cc=sam@vilain.net \
--cc=xemul@sw.ru \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.