From 25b21cb2f6d69b0475b134e0a3e8e269137270fa Mon Sep 17 00:00:00 2001 From: Kirill Korotaev Date: Mon, 2 Oct 2006 02:18:19 -0700 Subject: [PATCH] IPC namespace core This patch set allows to unshare IPCs and have a private set of IPC objects (sem, shm, msg) inside namespace. Basically, it is another building block of containers functionality. This patch implements core IPC namespace changes: - ipc_namespace structure - new config option CONFIG_IPC_NS - adds CLONE_NEWIPC flag - unshare support [clg@fr.ibm.com: small fix for unshare of ipc namespace] [akpm@osdl.org: build fix] Signed-off-by: Pavel Emelianov Signed-off-by: Kirill Korotaev Signed-off-by: Cedric Le Goater Cc: "Eric W. Biederman" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/fork.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'kernel/fork.c') diff --git a/kernel/fork.c b/kernel/fork.c index 208dd99f13bc..d6cc56558507 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1608,13 +1608,15 @@ asmlinkage long sys_unshare(unsigned long unshare_flags) struct sem_undo_list *new_ulist = NULL; struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL; struct uts_namespace *uts, *new_uts = NULL; + struct ipc_namespace *ipc, *new_ipc = 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_NEWUTS)) + CLONE_VM|CLONE_FILES|CLONE_SYSVSEM| + CLONE_NEWUTS|CLONE_NEWIPC)) goto bad_unshare_out; if ((err = unshare_thread(unshare_flags))) @@ -1633,18 +1635,20 @@ asmlinkage long sys_unshare(unsigned long unshare_flags) goto bad_unshare_cleanup_fd; if ((err = unshare_utsname(unshare_flags, &new_uts))) goto bad_unshare_cleanup_semundo; + if ((err = unshare_ipcs(unshare_flags, &new_ipc))) + goto bad_unshare_cleanup_uts; - if (new_ns || new_uts) { + if (new_ns || new_uts || new_ipc) { old_nsproxy = current->nsproxy; new_nsproxy = dup_namespaces(old_nsproxy); if (!new_nsproxy) { err = -ENOMEM; - goto bad_unshare_cleanup_uts; + goto bad_unshare_cleanup_ipc; } } if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist || - new_uts) { + new_uts || new_ipc) { task_lock(current); @@ -1692,12 +1696,22 @@ asmlinkage long sys_unshare(unsigned long unshare_flags) new_uts = uts; } + if (new_ipc) { + ipc = current->nsproxy->ipc_ns; + current->nsproxy->ipc_ns = new_ipc; + new_ipc = ipc; + } + task_unlock(current); } if (new_nsproxy) put_nsproxy(new_nsproxy); +bad_unshare_cleanup_ipc: + if (new_ipc) + put_ipc_ns(new_ipc); + bad_unshare_cleanup_uts: if (new_uts) put_uts_ns(new_uts); -- cgit v1.2.3-55-g7522