Skip to content

Commit

Permalink
[PATCH] namespaces: utsname: implement utsname namespaces
Browse files Browse the repository at this point in the history
This patch defines the uts namespace and some manipulators.
Adds the uts namespace to task_struct, and initializes a
system-wide init namespace.

It leaves a #define for system_utsname so sysctl will compile.
This define will be removed in a separate patch.

[[email protected]: build fix, cleanup]
Signed-off-by: Serge Hallyn <[email protected]>
Cc: Kirill Korotaev <[email protected]>
Cc: "Eric W. Biederman" <[email protected]>
Cc: Herbert Poetzl <[email protected]>
Cc: Andrey Savochkin <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Serge E. Hallyn authored and Linus Torvalds committed Oct 2, 2006
1 parent 96b644b commit 4865ecf
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 12 deletions.
2 changes: 2 additions & 0 deletions include/linux/init_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <linux/file.h>
#include <linux/rcupdate.h>
#include <linux/irqflags.h>
#include <linux/utsname.h>
#include <linux/lockdep.h>

#define INIT_FDTABLE \
Expand Down Expand Up @@ -72,6 +73,7 @@ extern struct nsproxy init_nsproxy;
#define INIT_NSPROXY(nsproxy) { \
.count = ATOMIC_INIT(1), \
.nslock = SPIN_LOCK_UNLOCKED, \
.uts_ns = &init_uts_ns, \
.namespace = NULL, \
}

Expand Down
2 changes: 2 additions & 0 deletions include/linux/nsproxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <linux/sched.h>

struct namespace;
struct uts_namespace;

/*
* A structure to contain pointers to all per-process
Expand All @@ -21,6 +22,7 @@ struct namespace;
struct nsproxy {
atomic_t count;
spinlock_t nslock;
struct uts_namespace *uts_ns;
struct namespace *namespace;
};
extern struct nsproxy init_nsproxy;
Expand Down
1 change: 1 addition & 0 deletions include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,7 @@ static inline void prefetch_stack(struct task_struct *t) { }
struct audit_context; /* See audit.c */
struct mempolicy;
struct pipe_inode_info;
struct uts_namespace;

enum sleep_type {
SLEEP_NORMAL,
Expand Down
40 changes: 37 additions & 3 deletions include/linux/utsname.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#ifndef _LINUX_UTSNAME_H
#define _LINUX_UTSNAME_H

#include <linux/sched.h>
#include <linux/kref.h>
#include <linux/nsproxy.h>
#include <asm/atomic.h>

#define __OLD_UTS_LEN 8

struct oldold_utsname {
Expand Down Expand Up @@ -30,17 +35,46 @@ struct new_utsname {
char domainname[65];
};

extern struct new_utsname system_utsname;
struct uts_namespace {
struct kref kref;
struct new_utsname name;
};
extern struct uts_namespace init_uts_ns;

static inline void get_uts_ns(struct uts_namespace *ns)
{
kref_get(&ns->kref);
}

#ifdef CONFIG_UTS_NS
extern int copy_utsname(int flags, struct task_struct *tsk);
extern void free_uts_ns(struct kref *kref);

static inline void put_uts_ns(struct uts_namespace *ns)
{
kref_put(&ns->kref, free_uts_ns);
}
#else
static inline int copy_utsname(int flags, struct task_struct *tsk)
{
return 0;
}
static inline void put_uts_ns(struct uts_namespace *ns)
{
}
#endif

static inline struct new_utsname *utsname(void)
{
return &system_utsname;
return &current->nsproxy->uts_ns->name;
}

static inline struct new_utsname *init_utsname(void)
{
return &system_utsname;
return &init_uts_ns.name;
}

#define system_utsname init_uts_ns.name

extern struct rw_semaphore uts_sem;
#endif
8 changes: 8 additions & 0 deletions init/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,14 @@ config TASK_DELAY_ACCT

Say N if unsure.

config UTS_NS
bool "UTS Namespaces"
default n
help
Support uts namespaces. This allows containers, i.e.
vservers, to use uts namespaces to provide different
uts info for different servers. If unsure, say N.

config AUDIT
bool "Auditing support"
depends on NET
Expand Down
23 changes: 14 additions & 9 deletions init/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,27 @@
#include <linux/utsname.h>
#include <linux/utsrelease.h>
#include <linux/version.h>
#include <linux/sched.h>

#define version(a) Version_ ## a
#define version_string(a) version(a)

int version_string(LINUX_VERSION_CODE);

struct new_utsname system_utsname = {
.sysname = UTS_SYSNAME,
.nodename = UTS_NODENAME,
.release = UTS_RELEASE,
.version = UTS_VERSION,
.machine = UTS_MACHINE,
.domainname = UTS_DOMAINNAME,
struct uts_namespace init_uts_ns = {
.kref = {
.refcount = ATOMIC_INIT(2),
},
.name = {
.sysname = UTS_SYSNAME,
.nodename = UTS_NODENAME,
.release = UTS_RELEASE,
.version = UTS_VERSION,
.machine = UTS_MACHINE,
.domainname = UTS_DOMAINNAME,
},
};

EXPORT_SYMBOL(system_utsname);
EXPORT_SYMBOL_GPL(init_uts_ns);

const char linux_banner[] =
"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
Expand Down
1 change: 1 addition & 0 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
obj-$(CONFIG_SECCOMP) += seccomp.o
obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
obj-$(CONFIG_RELAY) += relay.o
obj-$(CONFIG_UTS_NS) += utsname.o
obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o

Expand Down
14 changes: 14 additions & 0 deletions kernel/nsproxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/nsproxy.h>
#include <linux/init_task.h>
#include <linux/namespace.h>
#include <linux/utsname.h>

struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);

Expand Down Expand Up @@ -59,6 +60,8 @@ struct nsproxy *dup_namespaces(struct nsproxy *orig)
if (ns) {
if (ns->namespace)
get_namespace(ns->namespace);
if (ns->uts_ns)
get_uts_ns(ns->uts_ns);
}

return ns;
Expand Down Expand Up @@ -97,6 +100,15 @@ int copy_namespaces(int flags, struct task_struct *tsk)
goto out;
}

err = copy_utsname(flags, tsk);
if (err) {
if (new_ns->namespace)
put_namespace(new_ns->namespace);
tsk->nsproxy = old_ns;
put_nsproxy(new_ns);
goto out;
}

out:
put_nsproxy(old_ns);
return err;
Expand All @@ -106,5 +118,7 @@ void free_nsproxy(struct nsproxy *ns)
{
if (ns->namespace)
put_namespace(ns->namespace);
if (ns->uts_ns)
put_uts_ns(ns->uts_ns);
kfree(ns);
}
42 changes: 42 additions & 0 deletions kernel/utsname.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (C) 2004 IBM Corporation
*
* Author: Serge Hallyn <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/

#include <linux/module.h>
#include <linux/uts.h>
#include <linux/utsname.h>
#include <linux/version.h>

/*
* Copy task tsk's utsname namespace, or clone it if flags
* specifies CLONE_NEWUTS. In latter case, changes to the
* utsname of this process won't be seen by parent, and vice
* versa.
*/
int copy_utsname(int flags, struct task_struct *tsk)
{
struct uts_namespace *old_ns = tsk->nsproxy->uts_ns;
int err = 0;

if (!old_ns)
return 0;

get_uts_ns(old_ns);

return err;
}

void free_uts_ns(struct kref *kref)
{
struct uts_namespace *ns;

ns = container_of(kref, struct uts_namespace, kref);
kfree(ns);
}

0 comments on commit 4865ecf

Please sign in to comment.