Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 37825
b: refs/heads/master
c: 1651e14
h: refs/heads/master
i:
  37823: 8c65def
v: v3
  • Loading branch information
Serge E. Hallyn authored and Linus Torvalds committed Oct 2, 2006
1 parent c14e9f9 commit 4258394
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 40 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0437eb594e6e5e699248f865482e61034be846d0
refs/heads/master: 1651e14e28a2d9f446018ef522882e0709a2ce4f
22 changes: 8 additions & 14 deletions trunk/fs/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)

static inline int check_mnt(struct vfsmount *mnt)
{
return mnt->mnt_namespace == current->namespace;
return mnt->mnt_namespace == current->nsproxy->namespace;
}

static void touch_namespace(struct namespace *ns)
Expand Down Expand Up @@ -830,7 +830,7 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt,
if (parent_nd) {
detach_mnt(source_mnt, parent_nd);
attach_mnt(source_mnt, nd);
touch_namespace(current->namespace);
touch_namespace(current->nsproxy->namespace);
} else {
mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt);
commit_tree(source_mnt);
Expand Down Expand Up @@ -1441,7 +1441,7 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
*/
struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs)
{
struct namespace *namespace = tsk->namespace;
struct namespace *namespace = tsk->nsproxy->namespace;
struct namespace *new_ns;
struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
struct vfsmount *p, *q;
Expand Down Expand Up @@ -1508,7 +1508,7 @@ struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs)

int copy_namespace(int flags, struct task_struct *tsk)
{
struct namespace *namespace = tsk->namespace;
struct namespace *namespace = tsk->nsproxy->namespace;
struct namespace *new_ns;
int err = 0;

Expand All @@ -1531,7 +1531,7 @@ int copy_namespace(int flags, struct task_struct *tsk)
goto out;
}

tsk->namespace = new_ns;
tsk->nsproxy->namespace = new_ns;

out:
put_namespace(namespace);
Expand Down Expand Up @@ -1754,7 +1754,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
detach_mnt(user_nd.mnt, &root_parent);
attach_mnt(user_nd.mnt, &old_nd); /* mount old root on put_old */
attach_mnt(new_nd.mnt, &root_parent); /* mount new_root on / */
touch_namespace(current->namespace);
touch_namespace(current->nsproxy->namespace);
spin_unlock(&vfsmount_lock);
chroot_fs_refs(&user_nd, &new_nd);
security_sb_post_pivotroot(&user_nd, &new_nd);
Expand All @@ -1780,7 +1780,6 @@ static void __init init_mount_tree(void)
{
struct vfsmount *mnt;
struct namespace *namespace;
struct task_struct *g, *p;

mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
if (IS_ERR(mnt))
Expand All @@ -1796,13 +1795,8 @@ static void __init init_mount_tree(void)
namespace->root = mnt;
mnt->mnt_namespace = namespace;

init_task.namespace = namespace;
read_lock(&tasklist_lock);
do_each_thread(g, p) {
get_namespace(namespace);
p->namespace = namespace;
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
init_task.nsproxy->namespace = namespace;
get_namespace(namespace);

set_fs_pwd(current->fs, namespace->root, namespace->root->mnt_root);
set_fs_root(current->fs, namespace->root, namespace->root->mnt_root);
Expand Down
5 changes: 3 additions & 2 deletions trunk/fs/proc/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
#include <linux/cpuset.h>
#include <linux/audit.h>
#include <linux/poll.h>
#include <linux/nsproxy.h>
#include "internal.h"

/* NOTE:
Expand Down Expand Up @@ -473,7 +474,7 @@ static int mounts_open(struct inode *inode, struct file *file)

if (task) {
task_lock(task);
namespace = task->namespace;
namespace = task->nsproxy->namespace;
if (namespace)
get_namespace(namespace);
task_unlock(task);
Expand Down Expand Up @@ -544,7 +545,7 @@ static int mountstats_open(struct inode *inode, struct file *file)

if (task) {
task_lock(task);
namespace = task->namespace;
namespace = task->nsproxy->namespace;
if (namespace)
get_namespace(namespace);
task_unlock(task);
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/init_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ extern struct nsproxy init_nsproxy;
#define INIT_NSPROXY(nsproxy) { \
.count = ATOMIC_INIT(1), \
.nslock = SPIN_LOCK_UNLOCKED, \
.namespace = NULL, \
}

#define INIT_SIGHAND(sighand) { \
Expand Down
6 changes: 2 additions & 4 deletions trunk/include/linux/namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <linux/mount.h>
#include <linux/sched.h>
#include <linux/nsproxy.h>

struct namespace {
atomic_t count;
Expand All @@ -26,11 +27,8 @@ static inline void put_namespace(struct namespace *namespace)

static inline void exit_namespace(struct task_struct *p)
{
struct namespace *namespace = p->namespace;
struct namespace *namespace = p->nsproxy->namespace;
if (namespace) {
task_lock(p);
p->namespace = NULL;
task_unlock(p);
put_namespace(namespace);
}
}
Expand Down
3 changes: 3 additions & 0 deletions trunk/include/linux/nsproxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <linux/spinlock.h>
#include <linux/sched.h>

struct namespace;

/*
* A structure to contain pointers to all per-process
* namespaces - fs (mount), uts, network, sysvipc, etc.
Expand All @@ -19,6 +21,7 @@
struct nsproxy {
atomic_t count;
spinlock_t nslock;
struct namespace *namespace;
};
extern struct nsproxy init_nsproxy;

Expand Down
4 changes: 1 addition & 3 deletions trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,6 @@ extern signed long schedule_timeout_interruptible(signed long timeout);
extern signed long schedule_timeout_uninterruptible(signed long timeout);
asmlinkage void schedule(void);

struct namespace;
struct nsproxy;

/* Maximum number of active map areas.. This is a random (large) number */
Expand Down Expand Up @@ -897,8 +896,7 @@ struct task_struct {
struct fs_struct *fs;
/* open file information */
struct files_struct *files;
/* namespace */
struct namespace *namespace;
/* namespaces */
struct nsproxy *nsproxy;
/* signal handlers */
struct signal_struct *signal;
Expand Down
4 changes: 0 additions & 4 deletions trunk/kernel/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,11 +399,8 @@ void daemonize(const char *name, ...)
current->fs = fs;
atomic_inc(&fs->count);

exit_namespace(current);
exit_task_namespaces(current);
current->namespace = init_task.namespace;
current->nsproxy = init_task.nsproxy;
get_namespace(current->namespace);
get_task_namespaces(current);

exit_files(current);
Expand Down Expand Up @@ -923,7 +920,6 @@ fastcall NORET_TYPE void do_exit(long code)
exit_sem(tsk);
__exit_files(tsk);
__exit_fs(tsk);
exit_namespace(tsk);
exit_task_namespaces(tsk);
exit_thread();
cpuset_exit(tsk);
Expand Down
17 changes: 6 additions & 11 deletions trunk/kernel/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -1119,11 +1119,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
goto bad_fork_cleanup_mm;
if ((retval = copy_namespaces(clone_flags, p)))
goto bad_fork_cleanup_keys;
if ((retval = copy_namespace(clone_flags, p)))
goto bad_fork_cleanup_namespaces;
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;
/*
Expand Down Expand Up @@ -1215,7 +1213,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
spin_unlock(&current->sighand->siglock);
write_unlock_irq(&tasklist_lock);
retval = -ERESTARTNOINTR;
goto bad_fork_cleanup_namespace;
goto bad_fork_cleanup_namespaces;
}

if (clone_flags & CLONE_THREAD) {
Expand Down Expand Up @@ -1263,8 +1261,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
proc_fork_connector(p);
return p;

bad_fork_cleanup_namespace:
exit_namespace(p);
bad_fork_cleanup_namespaces:
exit_task_namespaces(p);
bad_fork_cleanup_keys:
Expand Down Expand Up @@ -1519,10 +1515,9 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
*/
static int unshare_namespace(unsigned long unshare_flags, struct namespace **new_nsp, struct fs_struct *new_fs)
{
struct namespace *ns = current->namespace;
struct namespace *ns = current->nsproxy->namespace;

if ((unshare_flags & CLONE_NEWNS) &&
(ns && atomic_read(&ns->count) > 1)) {
if ((unshare_flags & CLONE_NEWNS) && ns) {
if (!capable(CAP_SYS_ADMIN))
return -EPERM;

Expand Down Expand Up @@ -1655,8 +1650,8 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
}

if (new_ns) {
ns = current->namespace;
current->namespace = new_ns;
ns = current->nsproxy->namespace;
current->nsproxy->namespace = new_ns;
new_ns = ns;
}

Expand Down
32 changes: 31 additions & 1 deletion trunk/kernel/nsproxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <linux/version.h>
#include <linux/nsproxy.h>
#include <linux/init_task.h>
#include <linux/namespace.h>

struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);

Expand Down Expand Up @@ -55,6 +56,11 @@ struct nsproxy *dup_namespaces(struct nsproxy *orig)
{
struct nsproxy *ns = clone_namespaces(orig);

if (ns) {
if (ns->namespace)
get_namespace(ns->namespace);
}

return ns;
}

Expand All @@ -65,16 +71,40 @@ struct nsproxy *dup_namespaces(struct nsproxy *orig)
int copy_namespaces(int flags, struct task_struct *tsk)
{
struct nsproxy *old_ns = tsk->nsproxy;
struct nsproxy *new_ns;
int err = 0;

if (!old_ns)
return 0;

get_nsproxy(old_ns);

return 0;
if (!(flags & CLONE_NEWNS))
return 0;

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;
}

out:
put_nsproxy(old_ns);
return err;
}

void free_nsproxy(struct nsproxy *ns)
{
if (ns->namespace)
put_namespace(ns->namespace);
kfree(ns);
}

0 comments on commit 4258394

Please sign in to comment.