aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/init_task.h2
-rw-r--r--include/linux/nsproxy.h2
-rw-r--r--include/linux/sched.h1
-rw-r--r--include/linux/utsname.h40
-rw-r--r--init/Kconfig8
-rw-r--r--init/version.c23
-rw-r--r--kernel/Makefile1
-rw-r--r--kernel/nsproxy.c14
-rw-r--r--kernel/utsname.c42
9 files changed, 121 insertions, 12 deletions
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 4865348ca8bd..e08531ec32f0 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -4,6 +4,7 @@
4#include <linux/file.h> 4#include <linux/file.h>
5#include <linux/rcupdate.h> 5#include <linux/rcupdate.h>
6#include <linux/irqflags.h> 6#include <linux/irqflags.h>
7#include <linux/utsname.h>
7#include <linux/lockdep.h> 8#include <linux/lockdep.h>
8 9
9#define INIT_FDTABLE \ 10#define INIT_FDTABLE \
@@ -72,6 +73,7 @@ extern struct nsproxy init_nsproxy;
72#define INIT_NSPROXY(nsproxy) { \ 73#define INIT_NSPROXY(nsproxy) { \
73 .count = ATOMIC_INIT(1), \ 74 .count = ATOMIC_INIT(1), \
74 .nslock = SPIN_LOCK_UNLOCKED, \ 75 .nslock = SPIN_LOCK_UNLOCKED, \
76 .uts_ns = &init_uts_ns, \
75 .namespace = NULL, \ 77 .namespace = NULL, \
76} 78}
77 79
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
index 7ebe66670c59..9c2e0ad508db 100644
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -5,6 +5,7 @@
5#include <linux/sched.h> 5#include <linux/sched.h>
6 6
7struct namespace; 7struct namespace;
8struct uts_namespace;
8 9
9/* 10/*
10 * A structure to contain pointers to all per-process 11 * A structure to contain pointers to all per-process
@@ -21,6 +22,7 @@ struct namespace;
21struct nsproxy { 22struct nsproxy {
22 atomic_t count; 23 atomic_t count;
23 spinlock_t nslock; 24 spinlock_t nslock;
25 struct uts_namespace *uts_ns;
24 struct namespace *namespace; 26 struct namespace *namespace;
25}; 27};
26extern struct nsproxy init_nsproxy; 28extern struct nsproxy init_nsproxy;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 670b89a20070..46d6f5be72f2 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -753,6 +753,7 @@ static inline void prefetch_stack(struct task_struct *t) { }
753struct audit_context; /* See audit.c */ 753struct audit_context; /* See audit.c */
754struct mempolicy; 754struct mempolicy;
755struct pipe_inode_info; 755struct pipe_inode_info;
756struct uts_namespace;
756 757
757enum sleep_type { 758enum sleep_type {
758 SLEEP_NORMAL, 759 SLEEP_NORMAL,
diff --git a/include/linux/utsname.h b/include/linux/utsname.h
index 77e97a5755d9..afa54e1542b3 100644
--- a/include/linux/utsname.h
+++ b/include/linux/utsname.h
@@ -1,6 +1,11 @@
1#ifndef _LINUX_UTSNAME_H 1#ifndef _LINUX_UTSNAME_H
2#define _LINUX_UTSNAME_H 2#define _LINUX_UTSNAME_H
3 3
4#include <linux/sched.h>
5#include <linux/kref.h>
6#include <linux/nsproxy.h>
7#include <asm/atomic.h>
8
4#define __OLD_UTS_LEN 8 9#define __OLD_UTS_LEN 8
5 10
6struct oldold_utsname { 11struct oldold_utsname {
@@ -30,17 +35,46 @@ struct new_utsname {
30 char domainname[65]; 35 char domainname[65];
31}; 36};
32 37
33extern struct new_utsname system_utsname; 38struct uts_namespace {
39 struct kref kref;
40 struct new_utsname name;
41};
42extern struct uts_namespace init_uts_ns;
43
44static inline void get_uts_ns(struct uts_namespace *ns)
45{
46 kref_get(&ns->kref);
47}
48
49#ifdef CONFIG_UTS_NS
50extern int copy_utsname(int flags, struct task_struct *tsk);
51extern void free_uts_ns(struct kref *kref);
52
53static inline void put_uts_ns(struct uts_namespace *ns)
54{
55 kref_put(&ns->kref, free_uts_ns);
56}
57#else
58static inline int copy_utsname(int flags, struct task_struct *tsk)
59{
60 return 0;
61}
62static inline void put_uts_ns(struct uts_namespace *ns)
63{
64}
65#endif
34 66
35static inline struct new_utsname *utsname(void) 67static inline struct new_utsname *utsname(void)
36{ 68{
37 return &system_utsname; 69 return &current->nsproxy->uts_ns->name;
38} 70}
39 71
40static inline struct new_utsname *init_utsname(void) 72static inline struct new_utsname *init_utsname(void)
41{ 73{
42 return &system_utsname; 74 return &init_uts_ns.name;
43} 75}
44 76
77#define system_utsname init_uts_ns.name
78
45extern struct rw_semaphore uts_sem; 79extern struct rw_semaphore uts_sem;
46#endif 80#endif
diff --git a/init/Kconfig b/init/Kconfig
index f7a04d0daf07..b0ea97554473 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -182,6 +182,14 @@ config TASK_DELAY_ACCT
182 182
183 Say N if unsure. 183 Say N if unsure.
184 184
185config UTS_NS
186 bool "UTS Namespaces"
187 default n
188 help
189 Support uts namespaces. This allows containers, i.e.
190 vservers, to use uts namespaces to provide different
191 uts info for different servers. If unsure, say N.
192
185config AUDIT 193config AUDIT
186 bool "Auditing support" 194 bool "Auditing support"
187 depends on NET 195 depends on NET
diff --git a/init/version.c b/init/version.c
index e290802c6bd2..8f28344d9c70 100644
--- a/init/version.c
+++ b/init/version.c
@@ -12,22 +12,27 @@
12#include <linux/utsname.h> 12#include <linux/utsname.h>
13#include <linux/utsrelease.h> 13#include <linux/utsrelease.h>
14#include <linux/version.h> 14#include <linux/version.h>
15#include <linux/sched.h>
15 16
16#define version(a) Version_ ## a 17#define version(a) Version_ ## a
17#define version_string(a) version(a) 18#define version_string(a) version(a)
18 19
19int version_string(LINUX_VERSION_CODE); 20int version_string(LINUX_VERSION_CODE);
20 21
21struct new_utsname system_utsname = { 22struct uts_namespace init_uts_ns = {
22 .sysname = UTS_SYSNAME, 23 .kref = {
23 .nodename = UTS_NODENAME, 24 .refcount = ATOMIC_INIT(2),
24 .release = UTS_RELEASE, 25 },
25 .version = UTS_VERSION, 26 .name = {
26 .machine = UTS_MACHINE, 27 .sysname = UTS_SYSNAME,
27 .domainname = UTS_DOMAINNAME, 28 .nodename = UTS_NODENAME,
29 .release = UTS_RELEASE,
30 .version = UTS_VERSION,
31 .machine = UTS_MACHINE,
32 .domainname = UTS_DOMAINNAME,
33 },
28}; 34};
29 35EXPORT_SYMBOL_GPL(init_uts_ns);
30EXPORT_SYMBOL(system_utsname);
31 36
32const char linux_banner[] = 37const char linux_banner[] =
33 "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@" 38 "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
diff --git a/kernel/Makefile b/kernel/Makefile
index 6ec53009b866..d948ca12acf0 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
48obj-$(CONFIG_SECCOMP) += seccomp.o 48obj-$(CONFIG_SECCOMP) += seccomp.o
49obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o 49obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
50obj-$(CONFIG_RELAY) += relay.o 50obj-$(CONFIG_RELAY) += relay.o
51obj-$(CONFIG_UTS_NS) += utsname.o
51obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o 52obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
52obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o 53obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
53 54
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index e10385c17f73..47c19280c55b 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -14,6 +14,7 @@
14#include <linux/nsproxy.h> 14#include <linux/nsproxy.h>
15#include <linux/init_task.h> 15#include <linux/init_task.h>
16#include <linux/namespace.h> 16#include <linux/namespace.h>
17#include <linux/utsname.h>
17 18
18struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); 19struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
19 20
@@ -59,6 +60,8 @@ struct nsproxy *dup_namespaces(struct nsproxy *orig)
59 if (ns) { 60 if (ns) {
60 if (ns->namespace) 61 if (ns->namespace)
61 get_namespace(ns->namespace); 62 get_namespace(ns->namespace);
63 if (ns->uts_ns)
64 get_uts_ns(ns->uts_ns);
62 } 65 }
63 66
64 return ns; 67 return ns;
@@ -97,6 +100,15 @@ int copy_namespaces(int flags, struct task_struct *tsk)
97 goto out; 100 goto out;
98 } 101 }
99 102
103 err = copy_utsname(flags, tsk);
104 if (err) {
105 if (new_ns->namespace)
106 put_namespace(new_ns->namespace);
107 tsk->nsproxy = old_ns;
108 put_nsproxy(new_ns);
109 goto out;
110 }
111
100out: 112out:
101 put_nsproxy(old_ns); 113 put_nsproxy(old_ns);
102 return err; 114 return err;
@@ -106,5 +118,7 @@ void free_nsproxy(struct nsproxy *ns)
106{ 118{
107 if (ns->namespace) 119 if (ns->namespace)
108 put_namespace(ns->namespace); 120 put_namespace(ns->namespace);
121 if (ns->uts_ns)
122 put_uts_ns(ns->uts_ns);
109 kfree(ns); 123 kfree(ns);
110} 124}
diff --git a/kernel/utsname.c b/kernel/utsname.c
new file mode 100644
index 000000000000..1824384ecfa3
--- /dev/null
+++ b/kernel/utsname.c
@@ -0,0 +1,42 @@
1/*
2 * Copyright (C) 2004 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/uts.h>
14#include <linux/utsname.h>
15#include <linux/version.h>
16
17/*
18 * Copy task tsk's utsname namespace, or clone it if flags
19 * specifies CLONE_NEWUTS. In latter case, changes to the
20 * utsname of this process won't be seen by parent, and vice
21 * versa.
22 */
23int copy_utsname(int flags, struct task_struct *tsk)
24{
25 struct uts_namespace *old_ns = tsk->nsproxy->uts_ns;
26 int err = 0;
27
28 if (!old_ns)
29 return 0;
30
31 get_uts_ns(old_ns);
32
33 return err;
34}
35
36void free_uts_ns(struct kref *kref)
37{
38 struct uts_namespace *ns;
39
40 ns = container_of(kref, struct uts_namespace, kref);
41 kfree(ns);
42}