[PATCH] namespaces: utsname: implement utsname namespaces

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.

[akpm@osdl.org: build fix, cleanup]
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>
This commit is contained in:
Serge E. Hallyn 2006-10-02 02:18:14 -07:00 коммит произвёл Linus Torvalds
Родитель 96b644bdec
Коммит 4865ecf131
9 изменённых файлов: 121 добавлений и 12 удалений

Просмотреть файл

@ -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 \
@ -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, \
}

Просмотреть файл

@ -5,6 +5,7 @@
#include <linux/sched.h>
struct namespace;
struct uts_namespace;
/*
* A structure to contain pointers to all per-process
@ -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;

Просмотреть файл

@ -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,

Просмотреть файл

@ -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 {
@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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 "@"

Просмотреть файл

@ -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

Просмотреть файл

@ -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);
@ -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;
@ -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;
@ -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
kernel/utsname.c Normal file
Просмотреть файл

@ -0,0 +1,42 @@
/*
* Copyright (C) 2004 IBM Corporation
*
* Author: Serge Hallyn <serue@us.ibm.com>
*
* 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);
}