aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorKirill Korotaev <dev@openvz.org>2006-10-02 05:18:19 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-02 10:57:22 -0400
commit25b21cb2f6d69b0475b134e0a3e8e269137270fa (patch)
treecd9c3966408c0ca5903249437c35ff35961de544 /kernel
parentc0b2fc316599d6cd875b6b8cafa67f03b9512b4d (diff)
[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 <xemul@openvz.org> Signed-off-by: Kirill Korotaev <dev@openvz.org> Signed-off-by: Cedric Le Goater <clg@fr.ibm.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/fork.c22
-rw-r--r--kernel/nsproxy.c41
2 files changed, 46 insertions, 17 deletions
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)
1608 struct sem_undo_list *new_ulist = NULL; 1608 struct sem_undo_list *new_ulist = NULL;
1609 struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL; 1609 struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL;
1610 struct uts_namespace *uts, *new_uts = NULL; 1610 struct uts_namespace *uts, *new_uts = NULL;
1611 struct ipc_namespace *ipc, *new_ipc = NULL;
1611 1612
1612 check_unshare_flags(&unshare_flags); 1613 check_unshare_flags(&unshare_flags);
1613 1614
1614 /* Return -EINVAL for all unsupported flags */ 1615 /* Return -EINVAL for all unsupported flags */
1615 err = -EINVAL; 1616 err = -EINVAL;
1616 if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND| 1617 if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
1617 CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|CLONE_NEWUTS)) 1618 CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
1619 CLONE_NEWUTS|CLONE_NEWIPC))
1618 goto bad_unshare_out; 1620 goto bad_unshare_out;
1619 1621
1620 if ((err = unshare_thread(unshare_flags))) 1622 if ((err = unshare_thread(unshare_flags)))
@@ -1633,18 +1635,20 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1633 goto bad_unshare_cleanup_fd; 1635 goto bad_unshare_cleanup_fd;
1634 if ((err = unshare_utsname(unshare_flags, &new_uts))) 1636 if ((err = unshare_utsname(unshare_flags, &new_uts)))
1635 goto bad_unshare_cleanup_semundo; 1637 goto bad_unshare_cleanup_semundo;
1638 if ((err = unshare_ipcs(unshare_flags, &new_ipc)))
1639 goto bad_unshare_cleanup_uts;
1636 1640
1637 if (new_ns || new_uts) { 1641 if (new_ns || new_uts || new_ipc) {
1638 old_nsproxy = current->nsproxy; 1642 old_nsproxy = current->nsproxy;
1639 new_nsproxy = dup_namespaces(old_nsproxy); 1643 new_nsproxy = dup_namespaces(old_nsproxy);
1640 if (!new_nsproxy) { 1644 if (!new_nsproxy) {
1641 err = -ENOMEM; 1645 err = -ENOMEM;
1642 goto bad_unshare_cleanup_uts; 1646 goto bad_unshare_cleanup_ipc;
1643 } 1647 }
1644 } 1648 }
1645 1649
1646 if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist || 1650 if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist ||
1647 new_uts) { 1651 new_uts || new_ipc) {
1648 1652
1649 task_lock(current); 1653 task_lock(current);
1650 1654
@@ -1692,12 +1696,22 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1692 new_uts = uts; 1696 new_uts = uts;
1693 } 1697 }
1694 1698
1699 if (new_ipc) {
1700 ipc = current->nsproxy->ipc_ns;
1701 current->nsproxy->ipc_ns = new_ipc;
1702 new_ipc = ipc;
1703 }
1704
1695 task_unlock(current); 1705 task_unlock(current);
1696 } 1706 }
1697 1707
1698 if (new_nsproxy) 1708 if (new_nsproxy)
1699 put_nsproxy(new_nsproxy); 1709 put_nsproxy(new_nsproxy);
1700 1710
1711bad_unshare_cleanup_ipc:
1712 if (new_ipc)
1713 put_ipc_ns(new_ipc);
1714
1701bad_unshare_cleanup_uts: 1715bad_unshare_cleanup_uts:
1702 if (new_uts) 1716 if (new_uts)
1703 put_uts_ns(new_uts); 1717 put_uts_ns(new_uts);
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index 8246813335cc..8d6c852dc51e 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -7,6 +7,10 @@
7 * modify it under the terms of the GNU General Public License as 7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2 of the 8 * published by the Free Software Foundation, version 2 of the
9 * License. 9 * License.
10 *
11 * Jun 2006 - namespaces support
12 * OpenVZ, SWsoft Inc.
13 * Pavel Emelianov <xemul@openvz.org>
10 */ 14 */
11 15
12#include <linux/module.h> 16#include <linux/module.h>
@@ -62,6 +66,8 @@ struct nsproxy *dup_namespaces(struct nsproxy *orig)
62 get_namespace(ns->namespace); 66 get_namespace(ns->namespace);
63 if (ns->uts_ns) 67 if (ns->uts_ns)
64 get_uts_ns(ns->uts_ns); 68 get_uts_ns(ns->uts_ns);
69 if (ns->ipc_ns)
70 get_ipc_ns(ns->ipc_ns);
65 } 71 }
66 72
67 return ns; 73 return ns;
@@ -82,7 +88,7 @@ int copy_namespaces(int flags, struct task_struct *tsk)
82 88
83 get_nsproxy(old_ns); 89 get_nsproxy(old_ns);
84 90
85 if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS))) 91 if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC)))
86 return 0; 92 return 0;
87 93
88 new_ns = clone_namespaces(old_ns); 94 new_ns = clone_namespaces(old_ns);
@@ -94,24 +100,31 @@ int copy_namespaces(int flags, struct task_struct *tsk)
94 tsk->nsproxy = new_ns; 100 tsk->nsproxy = new_ns;
95 101
96 err = copy_namespace(flags, tsk); 102 err = copy_namespace(flags, tsk);
97 if (err) { 103 if (err)
98 tsk->nsproxy = old_ns; 104 goto out_ns;
99 put_nsproxy(new_ns);
100 goto out;
101 }
102 105
103 err = copy_utsname(flags, tsk); 106 err = copy_utsname(flags, tsk);
104 if (err) { 107 if (err)
105 if (new_ns->namespace) 108 goto out_uts;
106 put_namespace(new_ns->namespace); 109
107 tsk->nsproxy = old_ns; 110 err = copy_ipcs(flags, tsk);
108 put_nsproxy(new_ns); 111 if (err)
109 goto out; 112 goto out_ipc;
110 }
111 113
112out: 114out:
113 put_nsproxy(old_ns); 115 put_nsproxy(old_ns);
114 return err; 116 return err;
117
118out_ipc:
119 if (new_ns->uts_ns)
120 put_uts_ns(new_ns->uts_ns);
121out_uts:
122 if (new_ns->namespace)
123 put_namespace(new_ns->namespace);
124out_ns:
125 tsk->nsproxy = old_ns;
126 put_nsproxy(new_ns);
127 goto out;
115} 128}
116 129
117void free_nsproxy(struct nsproxy *ns) 130void free_nsproxy(struct nsproxy *ns)
@@ -120,5 +133,7 @@ void free_nsproxy(struct nsproxy *ns)
120 put_namespace(ns->namespace); 133 put_namespace(ns->namespace);
121 if (ns->uts_ns) 134 if (ns->uts_ns)
122 put_uts_ns(ns->uts_ns); 135 put_uts_ns(ns->uts_ns);
136 if (ns->ipc_ns)
137 put_ipc_ns(ns->ipc_ns);
123 kfree(ns); 138 kfree(ns);
124} 139}