diff options
author | Serge E. Hallyn <serue@us.ibm.com> | 2006-10-02 02:18:17 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-02 07:57:22 -0700 |
commit | 071df104f808b8195c40643dcb4d060681742e29 (patch) | |
tree | e5c3355e526e0182797d59c7e80062fbc2bb7d77 /kernel/fork.c | |
parent | bf47fdcda65b44dbd674eeedcaa06e0aa28a5a00 (diff) |
[PATCH] namespaces: utsname: implement CLONE_NEWUTS flag
Implement a CLONE_NEWUTS flag, and use it at clone and sys_unshare.
[clg@fr.ibm.com: IPC unshare fix]
[bunk@stusta.de: cleanup]
Signed-off-by: Serge Hallyn <serue@us.ibm.com>
Cc: Kirill Korotaev <dev@openvz.org>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Herbert Poetzl <herbert@13thfloor.at>
Cc: Andrey Savochkin <saw@sw.ru>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Cedric Le Goater <clg@fr.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 33fcf0733ca..c08cf05dd59 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1607,13 +1607,14 @@ asmlinkage long sys_unshare(unsigned long unshare_flags) struct files_struct *fd, *new_fd = NULL; struct sem_undo_list *new_ulist = NULL; struct nsproxy *new_nsproxy, *old_nsproxy; + struct uts_namespace *uts, *new_uts = NULL; check_unshare_flags(&unshare_flags); /* Return -EINVAL for all unsupported flags */ err = -EINVAL; if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND| - CLONE_VM|CLONE_FILES|CLONE_SYSVSEM)) + CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|CLONE_NEWUTS)) goto bad_unshare_out; if ((err = unshare_thread(unshare_flags))) @@ -1630,14 +1631,17 @@ asmlinkage long sys_unshare(unsigned long unshare_flags) goto bad_unshare_cleanup_vm; 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_semundo; - if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist) { + if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist || + new_uts) { old_nsproxy = current->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); @@ -1676,10 +1680,20 @@ asmlinkage long sys_unshare(unsigned long unshare_flags) new_fd = fd; } + if (new_uts) { + 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) |