Commit ab516013ad9ca47f1d3a936fa81303bfbf734d52
Committed by
Linus Torvalds
1 parent
b1ba4ddde0
Exists in
master
and in
4 other branches
[PATCH] namespaces: add nsproxy
This patch adds a nsproxy structure to the task struct. Later patches will move the fs namespace pointer into this structure, and introduce a new utsname namespace into the nsproxy. The vserver and openvz functionality, then, would be implemented in large part by virtualizing/isolating more and more resources into namespaces, each contained in the nsproxy. [akpm@osdl.org: build fix] 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: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 27 changed files with 196 additions and 2 deletions Side-by-side Diff
- arch/alpha/kernel/init_task.c
- arch/arm/kernel/init_task.c
- arch/arm26/kernel/init_task.c
- arch/frv/kernel/init_task.c
- arch/h8300/kernel/init_task.c
- arch/i386/kernel/init_task.c
- arch/ia64/kernel/init_task.c
- arch/m32r/kernel/init_task.c
- arch/m68knommu/kernel/init_task.c
- arch/mips/kernel/init_task.c
- arch/parisc/kernel/init_task.c
- arch/powerpc/kernel/init_task.c
- arch/s390/kernel/init_task.c
- arch/sh/kernel/init_task.c
- arch/sh64/kernel/init_task.c
- arch/sparc/kernel/init_task.c
- arch/sparc64/kernel/init_task.c
- arch/um/kernel/init_task.c
- arch/v850/kernel/init_task.c
- arch/x86_64/kernel/init_task.c
- include/linux/init_task.h
- include/linux/nsproxy.h
- include/linux/sched.h
- kernel/Makefile
- kernel/exit.c
- kernel/fork.c
- kernel/nsproxy.c
arch/alpha/kernel/init_task.c
... | ... | @@ -5,6 +5,7 @@ |
5 | 5 | #include <linux/init_task.h> |
6 | 6 | #include <linux/fs.h> |
7 | 7 | #include <linux/mqueue.h> |
8 | +#include <linux/nsproxy.h> | |
8 | 9 | #include <asm/uaccess.h> |
9 | 10 | |
10 | 11 | |
... | ... | @@ -13,6 +14,7 @@ |
13 | 14 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
14 | 15 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
15 | 16 | struct mm_struct init_mm = INIT_MM(init_mm); |
17 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
16 | 18 | struct task_struct init_task = INIT_TASK(init_task); |
17 | 19 | |
18 | 20 | EXPORT_SYMBOL(init_mm); |
arch/arm/kernel/init_task.c
... | ... | @@ -8,6 +8,7 @@ |
8 | 8 | #include <linux/init.h> |
9 | 9 | #include <linux/init_task.h> |
10 | 10 | #include <linux/mqueue.h> |
11 | +#include <linux/nsproxy.h> | |
11 | 12 | |
12 | 13 | #include <asm/uaccess.h> |
13 | 14 | #include <asm/pgtable.h> |
... | ... | @@ -17,6 +18,7 @@ |
17 | 18 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
18 | 19 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
19 | 20 | struct mm_struct init_mm = INIT_MM(init_mm); |
21 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
20 | 22 | |
21 | 23 | EXPORT_SYMBOL(init_mm); |
22 | 24 |
arch/arm26/kernel/init_task.c
... | ... | @@ -11,6 +11,7 @@ |
11 | 11 | #include <linux/init.h> |
12 | 12 | #include <linux/init_task.h> |
13 | 13 | #include <linux/mqueue.h> |
14 | +#include <linux/nsproxy.h> | |
14 | 15 | |
15 | 16 | #include <asm/uaccess.h> |
16 | 17 | #include <asm/pgtable.h> |
... | ... | @@ -20,6 +21,7 @@ |
20 | 21 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
21 | 22 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
22 | 23 | struct mm_struct init_mm = INIT_MM(init_mm); |
24 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
23 | 25 | |
24 | 26 | EXPORT_SYMBOL(init_mm); |
25 | 27 |
arch/frv/kernel/init_task.c
... | ... | @@ -5,6 +5,7 @@ |
5 | 5 | #include <linux/init_task.h> |
6 | 6 | #include <linux/fs.h> |
7 | 7 | #include <linux/mqueue.h> |
8 | +#include <linux/nsproxy.h> | |
8 | 9 | |
9 | 10 | #include <asm/uaccess.h> |
10 | 11 | #include <asm/pgtable.h> |
... | ... | @@ -15,6 +16,7 @@ |
15 | 16 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
16 | 17 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
17 | 18 | struct mm_struct init_mm = INIT_MM(init_mm); |
19 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
18 | 20 | |
19 | 21 | EXPORT_SYMBOL(init_mm); |
20 | 22 |
arch/h8300/kernel/init_task.c
... | ... | @@ -8,6 +8,7 @@ |
8 | 8 | #include <linux/init_task.h> |
9 | 9 | #include <linux/fs.h> |
10 | 10 | #include <linux/mqueue.h> |
11 | +#include <linux/nsproxy.h> | |
11 | 12 | |
12 | 13 | #include <asm/uaccess.h> |
13 | 14 | #include <asm/pgtable.h> |
... | ... | @@ -17,6 +18,7 @@ |
17 | 18 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
18 | 19 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
19 | 20 | struct mm_struct init_mm = INIT_MM(init_mm); |
21 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
20 | 22 | |
21 | 23 | EXPORT_SYMBOL(init_mm); |
22 | 24 |
arch/i386/kernel/init_task.c
... | ... | @@ -5,6 +5,7 @@ |
5 | 5 | #include <linux/init_task.h> |
6 | 6 | #include <linux/fs.h> |
7 | 7 | #include <linux/mqueue.h> |
8 | +#include <linux/nsproxy.h> | |
8 | 9 | |
9 | 10 | #include <asm/uaccess.h> |
10 | 11 | #include <asm/pgtable.h> |
... | ... | @@ -15,6 +16,7 @@ |
15 | 16 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
16 | 17 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
17 | 18 | struct mm_struct init_mm = INIT_MM(init_mm); |
19 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
18 | 20 | |
19 | 21 | EXPORT_SYMBOL(init_mm); |
20 | 22 |
arch/ia64/kernel/init_task.c
... | ... | @@ -12,6 +12,7 @@ |
12 | 12 | #include <linux/sched.h> |
13 | 13 | #include <linux/init_task.h> |
14 | 14 | #include <linux/mqueue.h> |
15 | +#include <linux/nsproxy.h> | |
15 | 16 | |
16 | 17 | #include <asm/uaccess.h> |
17 | 18 | #include <asm/pgtable.h> |
... | ... | @@ -21,6 +22,7 @@ |
21 | 22 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
22 | 23 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
23 | 24 | struct mm_struct init_mm = INIT_MM(init_mm); |
25 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
24 | 26 | |
25 | 27 | EXPORT_SYMBOL(init_mm); |
26 | 28 |
arch/m32r/kernel/init_task.c
... | ... | @@ -7,6 +7,7 @@ |
7 | 7 | #include <linux/init_task.h> |
8 | 8 | #include <linux/fs.h> |
9 | 9 | #include <linux/mqueue.h> |
10 | +#include <linux/nsproxy.h> | |
10 | 11 | |
11 | 12 | #include <asm/uaccess.h> |
12 | 13 | #include <asm/pgtable.h> |
... | ... | @@ -16,6 +17,7 @@ |
16 | 17 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
17 | 18 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
18 | 19 | struct mm_struct init_mm = INIT_MM(init_mm); |
20 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
19 | 21 | |
20 | 22 | EXPORT_SYMBOL(init_mm); |
21 | 23 |
arch/m68knommu/kernel/init_task.c
... | ... | @@ -8,6 +8,7 @@ |
8 | 8 | #include <linux/init_task.h> |
9 | 9 | #include <linux/fs.h> |
10 | 10 | #include <linux/mqueue.h> |
11 | +#include <linux/nsproxy.h> | |
11 | 12 | |
12 | 13 | #include <asm/uaccess.h> |
13 | 14 | #include <asm/pgtable.h> |
... | ... | @@ -17,6 +18,7 @@ |
17 | 18 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
18 | 19 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
19 | 20 | struct mm_struct init_mm = INIT_MM(init_mm); |
21 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
20 | 22 | |
21 | 23 | EXPORT_SYMBOL(init_mm); |
22 | 24 |
arch/mips/kernel/init_task.c
... | ... | @@ -4,6 +4,7 @@ |
4 | 4 | #include <linux/init_task.h> |
5 | 5 | #include <linux/fs.h> |
6 | 6 | #include <linux/mqueue.h> |
7 | +#include <linux/nsproxy.h> | |
7 | 8 | |
8 | 9 | #include <asm/thread_info.h> |
9 | 10 | #include <asm/uaccess.h> |
... | ... | @@ -14,6 +15,7 @@ |
14 | 15 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
15 | 16 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
16 | 17 | struct mm_struct init_mm = INIT_MM(init_mm); |
18 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
17 | 19 | |
18 | 20 | EXPORT_SYMBOL(init_mm); |
19 | 21 |
arch/parisc/kernel/init_task.c
... | ... | @@ -28,6 +28,7 @@ |
28 | 28 | #include <linux/init.h> |
29 | 29 | #include <linux/init_task.h> |
30 | 30 | #include <linux/mqueue.h> |
31 | +#include <linux/nsproxy.h> | |
31 | 32 | |
32 | 33 | #include <asm/uaccess.h> |
33 | 34 | #include <asm/pgtable.h> |
... | ... | @@ -38,6 +39,7 @@ |
38 | 39 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
39 | 40 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
40 | 41 | struct mm_struct init_mm = INIT_MM(init_mm); |
42 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
41 | 43 | |
42 | 44 | EXPORT_SYMBOL(init_mm); |
43 | 45 |
arch/powerpc/kernel/init_task.c
... | ... | @@ -5,6 +5,7 @@ |
5 | 5 | #include <linux/init_task.h> |
6 | 6 | #include <linux/fs.h> |
7 | 7 | #include <linux/mqueue.h> |
8 | +#include <linux/nsproxy.h> | |
8 | 9 | #include <asm/uaccess.h> |
9 | 10 | |
10 | 11 | static struct fs_struct init_fs = INIT_FS; |
... | ... | @@ -12,6 +13,7 @@ |
12 | 13 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
13 | 14 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
14 | 15 | struct mm_struct init_mm = INIT_MM(init_mm); |
16 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
15 | 17 | |
16 | 18 | EXPORT_SYMBOL(init_mm); |
17 | 19 |
arch/s390/kernel/init_task.c
... | ... | @@ -11,6 +11,7 @@ |
11 | 11 | #include <linux/sched.h> |
12 | 12 | #include <linux/init_task.h> |
13 | 13 | #include <linux/mqueue.h> |
14 | +#include <linux/nsproxy.h> | |
14 | 15 | |
15 | 16 | #include <asm/uaccess.h> |
16 | 17 | #include <asm/pgtable.h> |
... | ... | @@ -20,6 +21,7 @@ |
20 | 21 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
21 | 22 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
22 | 23 | struct mm_struct init_mm = INIT_MM(init_mm); |
24 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
23 | 25 | |
24 | 26 | EXPORT_SYMBOL(init_mm); |
25 | 27 |
arch/sh/kernel/init_task.c
... | ... | @@ -3,6 +3,7 @@ |
3 | 3 | #include <linux/sched.h> |
4 | 4 | #include <linux/init_task.h> |
5 | 5 | #include <linux/mqueue.h> |
6 | +#include <linux/nsproxy.h> | |
6 | 7 | |
7 | 8 | #include <asm/uaccess.h> |
8 | 9 | #include <asm/pgtable.h> |
... | ... | @@ -12,6 +13,7 @@ |
12 | 13 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
13 | 14 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
14 | 15 | struct mm_struct init_mm = INIT_MM(init_mm); |
16 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
15 | 17 | |
16 | 18 | EXPORT_SYMBOL(init_mm); |
17 | 19 |
arch/sh64/kernel/init_task.c
... | ... | @@ -14,6 +14,7 @@ |
14 | 14 | #include <linux/sched.h> |
15 | 15 | #include <linux/init_task.h> |
16 | 16 | #include <linux/mqueue.h> |
17 | +#include <linux/nsproxy.h> | |
17 | 18 | |
18 | 19 | #include <asm/uaccess.h> |
19 | 20 | #include <asm/pgtable.h> |
... | ... | @@ -23,6 +24,7 @@ |
23 | 24 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
24 | 25 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
25 | 26 | struct mm_struct init_mm = INIT_MM(init_mm); |
27 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
26 | 28 | |
27 | 29 | struct pt_regs fake_swapper_regs; |
28 | 30 |
arch/sparc/kernel/init_task.c
... | ... | @@ -3,6 +3,7 @@ |
3 | 3 | #include <linux/sched.h> |
4 | 4 | #include <linux/init_task.h> |
5 | 5 | #include <linux/mqueue.h> |
6 | +#include <linux/nsproxy.h> | |
6 | 7 | |
7 | 8 | #include <asm/pgtable.h> |
8 | 9 | #include <asm/uaccess.h> |
... | ... | @@ -12,6 +13,7 @@ |
12 | 13 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
13 | 14 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
14 | 15 | struct mm_struct init_mm = INIT_MM(init_mm); |
16 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
15 | 17 | struct task_struct init_task = INIT_TASK(init_task); |
16 | 18 | |
17 | 19 | EXPORT_SYMBOL(init_mm); |
arch/sparc64/kernel/init_task.c
... | ... | @@ -3,6 +3,7 @@ |
3 | 3 | #include <linux/sched.h> |
4 | 4 | #include <linux/init_task.h> |
5 | 5 | #include <linux/mqueue.h> |
6 | +#include <linux/nsproxy.h> | |
6 | 7 | |
7 | 8 | #include <asm/pgtable.h> |
8 | 9 | #include <asm/uaccess.h> |
... | ... | @@ -13,6 +14,7 @@ |
13 | 14 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
14 | 15 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
15 | 16 | struct mm_struct init_mm = INIT_MM(init_mm); |
17 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
16 | 18 | |
17 | 19 | EXPORT_SYMBOL(init_mm); |
18 | 20 |
arch/um/kernel/init_task.c
... | ... | @@ -9,6 +9,7 @@ |
9 | 9 | #include "linux/sched.h" |
10 | 10 | #include "linux/init_task.h" |
11 | 11 | #include "linux/mqueue.h" |
12 | +#include "linux/nsproxy.h" | |
12 | 13 | #include "asm/uaccess.h" |
13 | 14 | #include "asm/pgtable.h" |
14 | 15 | #include "user_util.h" |
... | ... | @@ -17,6 +18,7 @@ |
17 | 18 | |
18 | 19 | static struct fs_struct init_fs = INIT_FS; |
19 | 20 | struct mm_struct init_mm = INIT_MM(init_mm); |
21 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
20 | 22 | static struct files_struct init_files = INIT_FILES; |
21 | 23 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
22 | 24 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
arch/v850/kernel/init_task.c
... | ... | @@ -16,6 +16,7 @@ |
16 | 16 | #include <linux/init_task.h> |
17 | 17 | #include <linux/fs.h> |
18 | 18 | #include <linux/mqueue.h> |
19 | +#include <linux/nsproxy.h> | |
19 | 20 | |
20 | 21 | #include <asm/uaccess.h> |
21 | 22 | #include <asm/pgtable.h> |
... | ... | @@ -25,6 +26,7 @@ |
25 | 26 | static struct signal_struct init_signals = INIT_SIGNALS (init_signals); |
26 | 27 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
27 | 28 | struct mm_struct init_mm = INIT_MM (init_mm); |
29 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
28 | 30 | |
29 | 31 | EXPORT_SYMBOL(init_mm); |
30 | 32 |
arch/x86_64/kernel/init_task.c
... | ... | @@ -5,6 +5,7 @@ |
5 | 5 | #include <linux/init_task.h> |
6 | 6 | #include <linux/fs.h> |
7 | 7 | #include <linux/mqueue.h> |
8 | +#include <linux/nsproxy.h> | |
8 | 9 | |
9 | 10 | #include <asm/uaccess.h> |
10 | 11 | #include <asm/pgtable.h> |
... | ... | @@ -15,6 +16,7 @@ |
15 | 16 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
16 | 17 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
17 | 18 | struct mm_struct init_mm = INIT_MM(init_mm); |
19 | +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); | |
18 | 20 | |
19 | 21 | EXPORT_SYMBOL(init_mm); |
20 | 22 |
include/linux/init_task.h
... | ... | @@ -68,6 +68,12 @@ |
68 | 68 | .session = 1, \ |
69 | 69 | } |
70 | 70 | |
71 | +extern struct nsproxy init_nsproxy; | |
72 | +#define INIT_NSPROXY(nsproxy) { \ | |
73 | + .count = ATOMIC_INIT(1), \ | |
74 | + .nslock = SPIN_LOCK_UNLOCKED, \ | |
75 | +} | |
76 | + | |
71 | 77 | #define INIT_SIGHAND(sighand) { \ |
72 | 78 | .count = ATOMIC_INIT(1), \ |
73 | 79 | .action = { { { .sa_handler = NULL, } }, }, \ |
... | ... | @@ -117,6 +123,7 @@ |
117 | 123 | .files = &init_files, \ |
118 | 124 | .signal = &init_signals, \ |
119 | 125 | .sighand = &init_sighand, \ |
126 | + .nsproxy = &init_nsproxy, \ | |
120 | 127 | .pending = { \ |
121 | 128 | .list = LIST_HEAD_INIT(tsk.pending.list), \ |
122 | 129 | .signal = {{0}}}, \ |
include/linux/nsproxy.h
1 | +#ifndef _LINUX_NSPROXY_H | |
2 | +#define _LINUX_NSPROXY_H | |
3 | + | |
4 | +#include <linux/spinlock.h> | |
5 | +#include <linux/sched.h> | |
6 | + | |
7 | +/* | |
8 | + * A structure to contain pointers to all per-process | |
9 | + * namespaces - fs (mount), uts, network, sysvipc, etc. | |
10 | + * | |
11 | + * 'count' is the number of tasks holding a reference. | |
12 | + * The count for each namespace, then, will be the number | |
13 | + * of nsproxies pointing to it, not the number of tasks. | |
14 | + * | |
15 | + * The nsproxy is shared by tasks which share all namespaces. | |
16 | + * As soon as a single namespace is cloned or unshared, the | |
17 | + * nsproxy is copied. | |
18 | + */ | |
19 | +struct nsproxy { | |
20 | + atomic_t count; | |
21 | + spinlock_t nslock; | |
22 | +}; | |
23 | +extern struct nsproxy init_nsproxy; | |
24 | + | |
25 | +struct nsproxy *dup_namespaces(struct nsproxy *orig); | |
26 | +int copy_namespaces(int flags, struct task_struct *tsk); | |
27 | +void get_task_namespaces(struct task_struct *tsk); | |
28 | +void free_nsproxy(struct nsproxy *ns); | |
29 | + | |
30 | +static inline void put_nsproxy(struct nsproxy *ns) | |
31 | +{ | |
32 | + if (atomic_dec_and_test(&ns->count)) { | |
33 | + free_nsproxy(ns); | |
34 | + } | |
35 | +} | |
36 | + | |
37 | +static inline void exit_task_namespaces(struct task_struct *p) | |
38 | +{ | |
39 | + struct nsproxy *ns = p->nsproxy; | |
40 | + if (ns) { | |
41 | + put_nsproxy(ns); | |
42 | + p->nsproxy = NULL; | |
43 | + } | |
44 | +} | |
45 | +#endif |
include/linux/sched.h
... | ... | @@ -239,6 +239,7 @@ |
239 | 239 | asmlinkage void schedule(void); |
240 | 240 | |
241 | 241 | struct namespace; |
242 | +struct nsproxy; | |
242 | 243 | |
243 | 244 | /* Maximum number of active map areas.. This is a random (large) number */ |
244 | 245 | #define DEFAULT_MAX_MAP_COUNT 65536 |
... | ... | @@ -898,6 +899,7 @@ |
898 | 899 | struct files_struct *files; |
899 | 900 | /* namespace */ |
900 | 901 | struct namespace *namespace; |
902 | + struct nsproxy *nsproxy; | |
901 | 903 | /* signal handlers */ |
902 | 904 | struct signal_struct *signal; |
903 | 905 | struct sighand_struct *sighand; |
kernel/Makefile
... | ... | @@ -8,7 +8,7 @@ |
8 | 8 | signal.o sys.o kmod.o workqueue.o pid.o \ |
9 | 9 | rcupdate.o extable.o params.o posix-timers.o \ |
10 | 10 | kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ |
11 | - hrtimer.o rwsem.o latency.o | |
11 | + hrtimer.o rwsem.o latency.o nsproxy.o | |
12 | 12 | |
13 | 13 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
14 | 14 | obj-y += time/ |
kernel/exit.c
... | ... | @@ -21,6 +21,7 @@ |
21 | 21 | #include <linux/tsacct_kern.h> |
22 | 22 | #include <linux/file.h> |
23 | 23 | #include <linux/binfmts.h> |
24 | +#include <linux/nsproxy.h> | |
24 | 25 | #include <linux/ptrace.h> |
25 | 26 | #include <linux/profile.h> |
26 | 27 | #include <linux/mount.h> |
27 | 28 | |
28 | 29 | |
29 | 30 | |
... | ... | @@ -397,9 +398,14 @@ |
397 | 398 | fs = init_task.fs; |
398 | 399 | current->fs = fs; |
399 | 400 | atomic_inc(&fs->count); |
401 | + | |
400 | 402 | exit_namespace(current); |
403 | + exit_task_namespaces(current); | |
401 | 404 | current->namespace = init_task.namespace; |
405 | + current->nsproxy = init_task.nsproxy; | |
402 | 406 | get_namespace(current->namespace); |
407 | + get_task_namespaces(current); | |
408 | + | |
403 | 409 | exit_files(current); |
404 | 410 | current->files = init_task.files; |
405 | 411 | atomic_inc(¤t->files->count); |
... | ... | @@ -918,6 +924,7 @@ |
918 | 924 | __exit_files(tsk); |
919 | 925 | __exit_fs(tsk); |
920 | 926 | exit_namespace(tsk); |
927 | + exit_task_namespaces(tsk); | |
921 | 928 | exit_thread(); |
922 | 929 | cpuset_exit(tsk); |
923 | 930 | exit_keys(tsk); |
kernel/fork.c
... | ... | @@ -27,6 +27,7 @@ |
27 | 27 | #include <linux/binfmts.h> |
28 | 28 | #include <linux/mman.h> |
29 | 29 | #include <linux/fs.h> |
30 | +#include <linux/nsproxy.h> | |
30 | 31 | #include <linux/capability.h> |
31 | 32 | #include <linux/cpu.h> |
32 | 33 | #include <linux/cpuset.h> |
33 | 34 | |
... | ... | @@ -1116,8 +1117,10 @@ |
1116 | 1117 | goto bad_fork_cleanup_signal; |
1117 | 1118 | if ((retval = copy_keys(clone_flags, p))) |
1118 | 1119 | goto bad_fork_cleanup_mm; |
1119 | - if ((retval = copy_namespace(clone_flags, p))) | |
1120 | + if ((retval = copy_namespaces(clone_flags, p))) | |
1120 | 1121 | goto bad_fork_cleanup_keys; |
1122 | + if ((retval = copy_namespace(clone_flags, p))) | |
1123 | + goto bad_fork_cleanup_namespaces; | |
1121 | 1124 | retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); |
1122 | 1125 | if (retval) |
1123 | 1126 | goto bad_fork_cleanup_namespace; |
... | ... | @@ -1262,6 +1265,8 @@ |
1262 | 1265 | |
1263 | 1266 | bad_fork_cleanup_namespace: |
1264 | 1267 | exit_namespace(p); |
1268 | +bad_fork_cleanup_namespaces: | |
1269 | + exit_task_namespaces(p); | |
1265 | 1270 | bad_fork_cleanup_keys: |
1266 | 1271 | exit_keys(p); |
1267 | 1272 | bad_fork_cleanup_mm: |
... | ... | @@ -1606,6 +1611,7 @@ |
1606 | 1611 | struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL; |
1607 | 1612 | struct files_struct *fd, *new_fd = NULL; |
1608 | 1613 | struct sem_undo_list *new_ulist = NULL; |
1614 | + struct nsproxy *new_nsproxy, *old_nsproxy; | |
1609 | 1615 | |
1610 | 1616 | check_unshare_flags(&unshare_flags); |
1611 | 1617 | |
1612 | 1618 | |
... | ... | @@ -1632,7 +1638,15 @@ |
1632 | 1638 | |
1633 | 1639 | if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist) { |
1634 | 1640 | |
1641 | + old_nsproxy = current->nsproxy; | |
1642 | + new_nsproxy = dup_namespaces(old_nsproxy); | |
1643 | + if (!new_nsproxy) { | |
1644 | + err = -ENOMEM; | |
1645 | + goto bad_unshare_cleanup_semundo; | |
1646 | + } | |
1647 | + | |
1635 | 1648 | task_lock(current); |
1649 | + current->nsproxy = new_nsproxy; | |
1636 | 1650 | |
1637 | 1651 | if (new_fs) { |
1638 | 1652 | fs = current->fs; |
1639 | 1653 | |
... | ... | @@ -1668,8 +1682,10 @@ |
1668 | 1682 | } |
1669 | 1683 | |
1670 | 1684 | task_unlock(current); |
1685 | + put_nsproxy(old_nsproxy); | |
1671 | 1686 | } |
1672 | 1687 | |
1688 | +bad_unshare_cleanup_semundo: | |
1673 | 1689 | bad_unshare_cleanup_fd: |
1674 | 1690 | if (new_fd) |
1675 | 1691 | put_files_struct(new_fd); |
kernel/nsproxy.c
1 | +/* | |
2 | + * Copyright (C) 2006 IBM Corporation | |
3 | + * | |
4 | + * Author: Serge Hallyn <serue@us.ibm.com> | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or | |
7 | + * modify it under the terms of the GNU General Public License as | |
8 | + * published by the Free Software Foundation, version 2 of the | |
9 | + * License. | |
10 | + */ | |
11 | + | |
12 | +#include <linux/module.h> | |
13 | +#include <linux/version.h> | |
14 | +#include <linux/nsproxy.h> | |
15 | + | |
16 | +static inline void get_nsproxy(struct nsproxy *ns) | |
17 | +{ | |
18 | + atomic_inc(&ns->count); | |
19 | +} | |
20 | + | |
21 | +void get_task_namespaces(struct task_struct *tsk) | |
22 | +{ | |
23 | + struct nsproxy *ns = tsk->nsproxy; | |
24 | + if (ns) { | |
25 | + get_nsproxy(ns); | |
26 | + } | |
27 | +} | |
28 | + | |
29 | +/* | |
30 | + * creates a copy of "orig" with refcount 1. | |
31 | + * This does not grab references to the contained namespaces, | |
32 | + * so that needs to be done by dup_namespaces. | |
33 | + */ | |
34 | +static inline struct nsproxy *clone_namespaces(struct nsproxy *orig) | |
35 | +{ | |
36 | + struct nsproxy *ns; | |
37 | + | |
38 | + ns = kmalloc(sizeof(struct nsproxy), GFP_KERNEL); | |
39 | + if (ns) { | |
40 | + memcpy(ns, orig, sizeof(struct nsproxy)); | |
41 | + atomic_set(&ns->count, 1); | |
42 | + } | |
43 | + return ns; | |
44 | +} | |
45 | + | |
46 | +/* | |
47 | + * copies the nsproxy, setting refcount to 1, and grabbing a | |
48 | + * reference to all contained namespaces. Called from | |
49 | + * sys_unshare() | |
50 | + */ | |
51 | +struct nsproxy *dup_namespaces(struct nsproxy *orig) | |
52 | +{ | |
53 | + struct nsproxy *ns = clone_namespaces(orig); | |
54 | + | |
55 | + return ns; | |
56 | +} | |
57 | + | |
58 | +/* | |
59 | + * called from clone. This now handles copy for nsproxy and all | |
60 | + * namespaces therein. | |
61 | + */ | |
62 | +int copy_namespaces(int flags, struct task_struct *tsk) | |
63 | +{ | |
64 | + struct nsproxy *old_ns = tsk->nsproxy; | |
65 | + | |
66 | + if (!old_ns) | |
67 | + return 0; | |
68 | + | |
69 | + get_nsproxy(old_ns); | |
70 | + | |
71 | + return 0; | |
72 | +} | |
73 | + | |
74 | +void free_nsproxy(struct nsproxy *ns) | |
75 | +{ | |
76 | + kfree(ns); | |
77 | +} |