diff options
author | Kirill Korotaev <dev@openvz.org> | 2006-10-02 05:18:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-02 10:57:22 -0400 |
commit | 25b21cb2f6d69b0475b134e0a3e8e269137270fa (patch) | |
tree | cd9c3966408c0ca5903249437c35ff35961de544 /kernel | |
parent | c0b2fc316599d6cd875b6b8cafa67f03b9512b4d (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.c | 22 | ||||
-rw-r--r-- | kernel/nsproxy.c | 41 |
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 | ||
1711 | bad_unshare_cleanup_ipc: | ||
1712 | if (new_ipc) | ||
1713 | put_ipc_ns(new_ipc); | ||
1714 | |||
1701 | bad_unshare_cleanup_uts: | 1715 | bad_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 | ||
112 | out: | 114 | out: |
113 | put_nsproxy(old_ns); | 115 | put_nsproxy(old_ns); |
114 | return err; | 116 | return err; |
117 | |||
118 | out_ipc: | ||
119 | if (new_ns->uts_ns) | ||
120 | put_uts_ns(new_ns->uts_ns); | ||
121 | out_uts: | ||
122 | if (new_ns->namespace) | ||
123 | put_namespace(new_ns->namespace); | ||
124 | out_ns: | ||
125 | tsk->nsproxy = old_ns; | ||
126 | put_nsproxy(new_ns); | ||
127 | goto out; | ||
115 | } | 128 | } |
116 | 129 | ||
117 | void free_nsproxy(struct nsproxy *ns) | 130 | void 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 | } |