Playing with namespaces and bloat-o-meeter
Hi, guys!
I've noticed that compiling out all the core related to cloning and cleaning the new namespace saves us more than a Kbyte (!) from the vmlinux.
add/remove: 19/0 grow/shrink: 6/6 up/down: 1532/-336 (1196)
function old new delta copy_user_ns - 181 +181 copy_ipcs - 149 +149 copy_utsname - 120 +120 shm_exit_ns - 106 +106 sem_exit_ns - 106 +106 msg_exit_ns - 106 +106 freeary - 100 +100 release_uids - 95 +95 freeque - 92 +92 free_nsproxy 48 99 +51 __sem_init_ns - 45 +45 shm_init_ns - 42 +42 sem_init_ns - 42 +42 msg_init_ns - 42 +42 __shm_init_ns - 38 +38 create_new_namespaces 300 335 +35 __msg_init_ns - 31 +31 sysvipc_proc_release 5 35 +30 free_ipc_ns - 30 +30 do_shm_rmid - 29 +29 shm_release 18 39 +21 free_user_ns - 16 +16 sysvipc_proc_open 100 111 +11 do_shmat 778 787 +9 free_uts_ns - 5 +5 sys_shmctl 1934 1907 -27 msg_init 82 47 -35 shm_init 92 47 -45 sem_init 99 44 -55 sys_msgctl 1394 1311 -83 sys_semctl 2123 2032 -91
Since there already were some questions like "do I need it on my cellphone?" in reply to pid namespaces patches and so on, why don't we make ALL the namespaces cloning code under the config option to make those people happy?
Here's the proposed patch.
---
include/linux/ipc.h +0 -50
@@ -100,56 +100,6 @@ struct kern_ipc_permvoid *security; }; -struct ipc_ids ; -struct ipc_namespace { -struct kref kref; -struct ipc_ids *ids[3 ]; - -int sem_ctls[4 ]; -int used_sems; - -int msg_ctlmax; -int msg_ctlmnb; -int msg_ctlmni; - -size_t shm_ctlmax; -size_t shm_ctlall; -int shm_ctlmni; -int shm_tot; -}; - -extern struct ipc_namespace init_ipc_ns; - -#ifdef CONFIG_SYSVIPC -#define INIT_IPC_NS (ns) .ns = &init_ipc_ns, -extern void free_ipc_ns (struct kref *kref); -extern struct ipc_namespace *copy_ipcs (unsigned long flags, -struct ipc_namespace *ns); -#else -#define INIT_IPC_NS (ns) -static inline struct ipc_namespace *copy_ipcs (unsigned long flags, -struct ipc_namespace *ns) -{ -return ns; -} -#endif - -static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) -{ -#ifdef CONFIG_SYSVIPC -if (ns) -kref_get (&ns->kref); -#endif -return ns; -} - -static inline void put_ipc_ns (struct ipc_namespace *ns) -{ -#ifdef CONFIG_SYSVIPC -kref_put (&ns->kref, free_ipc_ns); -#endif -} -#endif /* __KERNEL__ */ #endif /* _LINUX_IPC_H */
include/linux/ipc_namespace.h new file +67 -0
67 lines not on this page · raw message
include/linux/nsproxy.h +0 -0
include/linux/pid.h +0 -1
@@ -122,7 +122,6 @@ extern struct pid *find_ge_pid(int nr, sextern struct pid *alloc_pid (struct pid_namespace *ns);extern void FASTCALL (free_pid (struct pid *pid)); -extern void zap_pid_ns_processes (struct pid_namespace *pid_ns);/* * the helpers to get the pid's id seen from different namespaces
include/linux/pid_namespace.h +27 -0
@@ -6,6 +6,7 @@#include <linux/threads.h> #include <linux/nsproxy.h> #include <linux/kref.h> +#include <linux/err.h> struct pidmap {atomic_t nr_free;
@@ -29,6 +30,7 @@ struct pid_namespace {extern struct pid_namespace init_pid_ns; +#ifdef CONFIG_NS_PID static inline struct pid_namespace *get_pid_ns (struct pid_namespace *ns) {if (ns != &init_pid_ns)
@@ -38,12 +40,37 @@ static inline struct pid_namespace *get_extern struct pid_namespace *copy_pid_ns (unsigned long flags,struct pid_namespace *ns);extern void free_pid_ns (struct kref *kref); +extern void zap_pid_ns_processes (struct pid_namespace *pid_ns);static inline void put_pid_ns (struct pid_namespace *ns) {if (ns != &init_pid_ns)kref_put (&ns->kref, free_pid_ns); } +#else +static inline struct pid_namespace *get_pid_ns (struct pid_namespace *ns) +{ +return ns; +} + +static inline void put_pid_ns (struct pid_namespace *ns) +{ +} + +static inline struct pid_namespace *copy_pid_ns (unsigned long flags, +struct pid_namespace *ns) +{ +if (flags &CLONE_NEWPID ) +return ERR_PTR (-EINVAL ); + +return ns; +} + +static inline void zap_pid_ns_processes (struct pid_namespace *ns) +{ +BUG (); +} +#endif static inline struct pid_namespace *task_active_pid_ns (struct task_struct *tsk) {
include/linux/sched.h +0 -0
include/linux/sem.h +0 -0
include/linux/user_namespace.h +1 -1
@@ -17,7 +17,7 @@ struct user_namespace {extern struct user_namespace init_user_ns; -#ifdef CONFIG_USER_NS +#ifdef CONFIG_NS_UID static inline struct user_namespace *get_user_ns (struct user_namespace *ns) {
include/linux/utsname.h +21 -0
@@ -35,6 +35,7 @@ struct new_utsname {#include <linux/sched.h> #include <linux/kref.h> #include <linux/nsproxy.h> +#include <linux/err.h> #include <asm/atomic.h> struct uts_namespace {
@@ -43,6 +44,7 @@ struct uts_namespace { };extern struct uts_namespace init_uts_ns; +#ifdef CONFIG_NS_UTS static inline void get_uts_ns (struct uts_namespace *ns) {kref_get (&ns->kref);
@@ -56,6 +58,25 @@ static inline void put_uts_ns(struct uts {kref_put (&ns->kref, free_uts_ns); } +#else +static inline void get_uts_ns (struct uts_namespace *ns) +{ +} + +static inline void put_uts_ns (struct uts_namespace *ns) +{ +} + +static inline struct uts_namespace *copy_utsname (unsigned long flags, +struct uts_namespace *ns) +{ +if (flags &CLONE_NEWUTS ) +return ERR_PTR (-EINVAL ); + +return ns; +} +#endif +static inline struct new_utsname *utsname (void ) {return ¤t->nsproxy->uts_ns->name;
init/Kconfig +33 -9
54 lines not on this page · raw message
init/main.c +0 -0
ipc/Makefile +1 -0
@@ -7,4 +7,5 @@ obj-$(CONFIG_SYSVIPC) += util.o msgutil. obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o obj_mq-$(CONFIG_COMPAT) += compat_mq.o obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y) +obj-$(CONFIG_NS_IPC) += namespace.o
ipc/ipc_sysctl.c +1 -0
@@ -14,6 +14,7 @@#include <linux/nsproxy.h> #include <linux/sysctl.h> #include <linux/uaccess.h> +#include <linux/ipc_namespace.h> static void *get_ipc (ctl_table *table) {
ipc/msg.c +3 -0
@@ -36,6 +36,7 @@#include <linux/seq_file.h> #include <linux/mutex.h> #include <linux/nsproxy.h> +#include <linux/ipc_namespace.h> #include <asm/current.h> #include <asm/uaccess.h>
@@ -92,6 +93,7 @@ static void __msg_init_ns(struct ipc_namipc_init_ids (ids); } +#ifdef CONFIG_NS_IPC int msg_init_ns (struct ipc_namespace *ns) {struct ipc_ids *ids;
@@ -127,6 +129,7 @@ void msg_exit_ns(struct ipc_namespace *nkfree (ns->ids[IPC_MSG_IDS ]); ns->ids[IPC_MSG_IDS] = NULL; } +#endif void __init msg_init (void ) {
ipc/namespace.c new file +73 -0
73 lines not on this page · raw message
ipc/sem.c +3 -0
@@ -82,6 +82,7 @@#include <linux/seq_file.h> #include <linux/mutex.h> #include <linux/nsproxy.h> +#include <linux/ipc_namespace.h> #include <asm/uaccess.h> #include "util.h"
@@ -130,6 +131,7 @@ static void __sem_init_ns(struct ipc_namipc_init_ids (ids); } +#ifdef CONFIG_NS_IPC int sem_init_ns (struct ipc_namespace *ns) {struct ipc_ids *ids;
@@ -165,6 +167,7 @@ void sem_exit_ns(struct ipc_namespace *nkfree (ns->ids[IPC_SEM_IDS ]); ns->ids[IPC_SEM_IDS] = NULL; } +#endif void __init sem_init (void ) {
ipc/shm.c +3 -0
@@ -38,6 +38,7 @@#include <linux/mutex.h> #include <linux/nsproxy.h> #include <linux/mount.h> +#include <linux/ipc_namespace.h> #include <asm/uaccess.h>
@@ -97,6 +98,7 @@ static void do_shm_rmid(struct ipc_namesshm_destroy (ns, shp); } +#ifdef CONFIG_NS_IPC int shm_init_ns (struct ipc_namespace *ns) {struct ipc_ids *ids;
@@ -132,6 +134,7 @@ void shm_exit_ns(struct ipc_namespace *nkfree (ns->ids[IPC_SHM_IDS ]); ns->ids[IPC_SHM_IDS] = NULL; } +#endif void __init shm_init (void ) {
ipc/util.c +1 -60
73 lines not on this page · raw message
ipc/util.h +2 -0
@@ -20,6 +20,8 @@ void sem_init (void);void msg_init (void );void shm_init (void ); +struct ipc_namespace ; +int sem_init_ns (struct ipc_namespace *ns);int msg_init_ns (struct ipc_namespace *ns);int shm_init_ns (struct ipc_namespace *ns);
kernel/Makefile +4 -3
@@ -4,12 +4,11 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ exit.o itimer.o time.o softirq.o resource.o \ - sysctl.o capability.o ptrace.o timer.o user.o user_namespace.o \ + sysctl.o capability.o ptrace.o timer.o user.o \ signal.o sys.o kmod.o workqueue.o pid.o \ rcupdate.o extable.o params.o posix-timers.o \ kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ - hrtimer.o rwsem.o latency.o nsproxy.o srcu.o \ - utsname.o notifier.o sysctl.o + hrtimer.o rwsem.o latency.o nsproxy.o srcu.o notifier.o sysctl.o obj-$(CONFIG_SYSCTL) += sysctl_check.o obj-$(CONFIG_STACKTRACE) += stacktrace.o
@@ -50,6 +49,8 @@ obj-$(CONFIG_AUDITSYSCALL) += auditsc.o obj-$(CONFIG_AUDIT_TREE) += audit_tree.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KGDB) += kgdb.o +obj-$(CONFIG_NS_UTS) += utsname.o +obj-$(CONFIG_NS_UID) += user_namespace.o obj-$(CONFIG_SYSFS) += ksysfs.o obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
kernel/nsproxy.c +1 -0
@@ -20,6 +20,7 @@#include <linux/mnt_namespace.h> #include <linux/utsname.h> #include <linux/pid_namespace.h> +#include <linux/ipc_namespace.h> static struct kmem_cache *nsproxy_cachep;
kernel/pid.c +14 -1
@@ -432,6 +432,7 @@ struct pid *find_ge_pid(int nr, struct p }EXPORT_SYMBOL_GPL (find_get_pid); +#ifdef CONFIG_NS_PID struct pid_cache { int nr_ids; char name[16];
@@ -482,6 +483,11 @@ err_alloc:return NULL ; } +static __init struct kmem_cache *create_init_pid_cachep (void ) +{ +return create_pid_cachep (1 ); +} +static struct pid_namespace *create_pid_namespace (int level) {struct pid_namespace *ns;
@@ -603,6 +609,13 @@ void zap_pid_ns_processes(struct pid_nam pid_ns->child_reaper =NULL ; return; } +#else +static __init struct kmem_cache *create_init_pid_cachep (void ) +{ +return kmem_cache_create ("pid" ,sizeof (struct pid ),0 , +SLAB_HWCACHE_ALIGN ,NULL ); +} +#endif /* * The pid hash table is scaled according to the amount of memory in the
@@ -636,7 +649,7 @@ void __init pidmap_init(void)set_bit (0 , init_pid_ns.pidmap[0 ].page);atomic_dec (&init_pid_ns.pidmap[0 ].nr_free); - init_pid_ns.pid_cachep =create_pid_cachep (1 ); + init_pid_ns.pid_cachep =create_init_pid_cachep ();if (init_pid_ns.pid_cachep ==NULL )panic ("Can't create pid_1 cachep\n" );
kernel/user.c +11 -0
@@ -17,6 +17,15 @@#include <linux/module.h> #include <linux/user_namespace.h> +struct user_namespace init_user_ns = { + .kref = { + .refcount =ATOMIC_INIT (2 ), + }, + .root_user = &root_user, +}; + +EXPORT_SYMBOL_GPL (init_user_ns); +/* * UID task count cache, to get fast user lookup in "alloc_uid" * when changing user ID's (ie setuid() and friends).
@@ -199,6 +208,7 @@ void switch_uid(struct user_struct *new_suid_keys (current); } +#ifdef CONFIG_NS_UID void release_uids (struct user_namespace *ns) {int i;
@@ -223,6 +233,7 @@ void release_uids(struct user_namespace free_uid(ns->root_user); } +#endif static int __init uid_cache_init (void ) {
kernel/user_namespace.c +0 -13
@@ -10,17 +10,6 @@#include <linux/nsproxy.h> #include <linux/user_namespace.h> -struct user_namespace init_user_ns = { - .kref = { - .refcount =ATOMIC_INIT (2 ), - }, - .root_user = &root_user, -}; - -EXPORT_SYMBOL_GPL (init_user_ns); - -#ifdef CONFIG_USER_NS -/* * Clone a new ns copying an original user ns, setting refcount to 1 * @old_ns: namespace to clone
@@ -84,5 +73,3 @@ void free_user_ns(struct kref *kref)release_uids (ns);kfree (ns); } - -#endif /* CONFIG_USER_NS */
kernel/utsname.c +0 -0
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 40 lines · Pavel Emelyanov
Hi, guys!
I've noticed that compiling out all the core related to cloning and cleaning the new namespace saves us more than a Kbyte (!) from the vmlinux.
add/remove: 19/0 grow/shrink: 6/6 up/down: 1532/-336 (1196)
function old new delta copy_user_ns - 181 +181 copy_ipcs - 149 +149 copy_utsname - 120 +120 shm_exit_ns - 106 +106 sem_exit_ns - 106 +106 msg_exit_ns - 106 +106 freeary - 100 +100 release_uids - 95 +95 freeque - 92 +92 free_nsproxy 48 99 +51 __sem_init_ns - 45 +45 shm_init_ns - 42 +42 sem_init_ns - 42 +42 msg_init_ns - 42 +42 __shm_init_ns - 38 +38 create_new_namespaces 300 335 +35 __msg_init_ns - 31 +31 sysvipc_proc_release 5 35 +30 free_ipc_ns - 30 +30 do_shm_rmid - 29 +29 shm_release 18 39 +21 free_user_ns - 16 +16 sysvipc_proc_open 100 111 +11 do_shmat 778 787 +9 free_uts_ns - 5 +5 sys_shmctl 1934 1907 -27 msg_init 82 47 -35 shm_init 92 47 -45 sem_init 99 44 -55 sys_msgctl 1394 1311 -83 sys_semctl 2123 2032 -91
Quoted 6 lines
Since there already were some questions like "do I need it on my cellphone?" in reply to pid namespaces patches and so on, why don't we make ALL the namespaces cloning code under the config option to make those people happy?
Here's the proposed patch.
How about a single config variable for all namespaces?
-serge
Quoted 760 lines
Signed-off-by Pavel Emelyanov <[email protected]>---
include/linux/ipc.h +0
-50@@ -100,56 +100,6 @@ struct kern_ipc_permvoid *security; }; -struct ipc_ids ; -struct ipc_namespace { -struct kref kref; -struct ipc_ids *ids[3 ]; - -int sem_ctls[4 ]; -int used_sems; - -int msg_ctlmax; -int msg_ctlmnb; -int msg_ctlmni; - -size_t shm_ctlmax; -size_t shm_ctlall; -int shm_ctlmni; -int shm_tot; -}; - -extern struct ipc_namespace init_ipc_ns; - -#ifdef CONFIG_SYSVIPC -#define INIT_IPC_NS (ns) .ns = &init_ipc_ns, -extern void free_ipc_ns (struct kref *kref); -extern struct ipc_namespace *copy_ipcs (unsigned long flags, -struct ipc_namespace *ns); -#else -#define INIT_IPC_NS (ns) -static inline struct ipc_namespace *copy_ipcs (unsigned long flags, -struct ipc_namespace *ns) -{ -return ns; -} -#endif - -static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) -{ -#ifdef CONFIG_SYSVIPC -if (ns) -kref_get (&ns->kref); -#endif -return ns; -} - -static inline void put_ipc_ns (struct ipc_namespace *ns) -{ -#ifdef CONFIG_SYSVIPC -kref_put (&ns->kref, free_ipc_ns); -#endif -} -#endif /* __KERNEL__ */ #endif /* _LINUX_IPC_H */ include/linux/ipc_namespace.h new file +67
-0@@ -0,0 +1,67 @@ +#ifndef __IPC_NAMESPACE_H__ +#define __IPC_NAMESPACE_H__ + +#include <linux/err.h> + +struct ipc_ids ; +struct ipc_namespace { +struct kref kref; +struct ipc_ids *ids[3 ]; + +int sem_ctls[4 ]; +int used_sems; + +int msg_ctlmax; +int msg_ctlmnb; +int msg_ctlmni; + +size_t shm_ctlmax; +size_t shm_ctlall; +int shm_ctlmni; +int shm_tot; +}; + +extern struct ipc_namespace init_ipc_ns; + +#ifdef CONFIG_SYSVIPC +#define INIT_IPC_NS (ns) .ns = &init_ipc_ns, +#else +#define INIT_IPC_NS (ns) +#endif + +#ifdef CONFIG_NS_IPC +extern void free_ipc_ns (struct kref *kref); +extern struct ipc_namespace *copy_ipcs (unsigned long flags, +struct ipc_namespace *ns); + +static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) +{ +if (ns) +kref_get (&ns->kref); +return ns; +} + +static inline void put_ipc_ns (struct ipc_namespace *ns) +{ +kref_put (&ns->kref, free_ipc_ns); +} +#else +static inline struct ipc_namespace *copy_ipcs (unsigned long flags, +struct ipc_namespace *ns) +{ +if (flags &CLONE_NEWIPC ) +return ERR_PTR (-EINVAL ); + +return ns; +} + +static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) +{ +return ns; +} + +static inline void put_ipc_ns (struct ipc_namespace *ns) +{ +} +#endif +#endif include/linux/nsproxy.h +0
-0include/linux/pid.h +0
-1@@ -122,7 +122,6 @@ extern struct pid *find_ge_pid(int nr, sextern struct pid *alloc_pid (struct pid_namespace *ns);extern void FASTCALL (free_pid (struct pid *pid)); -extern void zap_pid_ns_processes (struct pid_namespace *pid_ns);/* * the helpers to get the pid's id seen from different namespaces include/linux/pid_namespace.h +27
-0@@ -6,6 +6,7 @@#include <linux/threads.h> #include <linux/nsproxy.h> #include <linux/kref.h> +#include <linux/err.h> struct pidmap {atomic_t nr_free;@@ -29,6 +30,7 @@ struct pid_namespace {extern struct pid_namespace init_pid_ns; +#ifdef CONFIG_NS_PID static inline struct pid_namespace *get_pid_ns (struct pid_namespace *ns) {if (ns != &init_pid_ns)@@ -38,12 +40,37 @@ static inline struct pid_namespace *get_extern struct pid_namespace *copy_pid_ns (unsigned long flags,struct pid_namespace *ns);extern void free_pid_ns (struct kref *kref); +extern void zap_pid_ns_processes (struct pid_namespace *pid_ns);static inline void put_pid_ns (struct pid_namespace *ns) {if (ns != &init_pid_ns)kref_put (&ns->kref, free_pid_ns); } +#else +static inline struct pid_namespace *get_pid_ns (struct pid_namespace *ns) +{ +return ns; +} + +static inline void put_pid_ns (struct pid_namespace *ns) +{ +} + +static inline struct pid_namespace *copy_pid_ns (unsigned long flags, +struct pid_namespace *ns) +{ +if (flags &CLONE_NEWPID ) +return ERR_PTR (-EINVAL ); + +return ns; +} + +static inline void zap_pid_ns_processes (struct pid_namespace *ns) +{ +BUG (); +} +#endif static inline struct pid_namespace *task_active_pid_ns (struct task_struct *tsk) {include/linux/sched.h +0
-0include/linux/sem.h +0
-0include/linux/user_namespace.h +1
-1@@ -17,7 +17,7 @@ struct user_namespace {extern struct user_namespace init_user_ns; -#ifdef CONFIG_USER_NS +#ifdef CONFIG_NS_UID static inline struct user_namespace *get_user_ns (struct user_namespace *ns) {include/linux/utsname.h +21
-0@@ -35,6 +35,7 @@ struct new_utsname {#include <linux/sched.h> #include <linux/kref.h> #include <linux/nsproxy.h> +#include <linux/err.h> #include <asm/atomic.h> struct uts_namespace {@@ -43,6 +44,7 @@ struct uts_namespace { };extern struct uts_namespace init_uts_ns; +#ifdef CONFIG_NS_UTS static inline void get_uts_ns (struct uts_namespace *ns) {kref_get (&ns->kref);@@ -56,6 +58,25 @@ static inline void put_uts_ns(struct uts {kref_put (&ns->kref, free_uts_ns); } +#else +static inline void get_uts_ns (struct uts_namespace *ns) +{ +} + +static inline void put_uts_ns (struct uts_namespace *ns) +{ +} + +static inline struct uts_namespace *copy_utsname (unsigned long flags, +struct uts_namespace *ns) +{ +if (flags &CLONE_NEWUTS ) +return ERR_PTR (-EINVAL ); + +return ns; +} +#endif +static inline struct new_utsname *utsname (void ) {return ¤t->nsproxy->uts_ns->name;init/Kconfig +33
-9@@ -206,15 +206,6 @@ config TASK_IO_ACCOUNTING Say N if unsure. -config USER_NS - bool "User Namespaces (EXPERIMENTAL)" - default n - depends on EXPERIMENTAL - help - Support user namespaces. This allows containers, i.e. - vservers, to use user namespaces to provide different - user info for different servers. If unsure, say N. - config AUDIT bool "Auditing support" depends on NET@@ -369,6 +360,39 @@ config RELAY If unsure, say N. +config NAMESPACES + bool "The namespaces support" + help + Provides the way to make tasks work with different objects using + the same id + +config NS_UTS + bool "Uname namespace" + depends on NAMESPACES + help + The utsname namespace + +config NS_IPC + bool "IPC namespace" + depends on NAMESPACES && SYSVIPC + help + The SYSVIPC ids namespaces + +config NS_PIDS + bool "PID namespace" + depends on NAMESPACES + help + Tasks see only the pids living in the same namespace and in the + child namespaces + +config NS_UID + bool "UID namespace" + depends on NAMESPACES && EXPERIMENTAL + help + Support user namespaces. This allows containers, i.e. + vservers, to use user namespaces to provide different + user info for different servers. If unsure, say N. + config BLK_DEV_INITRD bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" depends on BROKEN || !FRVinit/main.c +0
-0ipc/Makefile +1
-0@@ -7,4 +7,5 @@ obj-$(CONFIG_SYSVIPC) += util.o msgutil. obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o obj_mq-$(CONFIG_COMPAT) += compat_mq.o obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y) +obj-$(CONFIG_NS_IPC) += namespace.oipc/ipc_sysctl.c +1
-0@@ -14,6 +14,7 @@#include <linux/nsproxy.h> #include <linux/sysctl.h> #include <linux/uaccess.h> +#include <linux/ipc_namespace.h> static void *get_ipc (ctl_table *table) {ipc/msg.c +3
-0@@ -36,6 +36,7 @@#include <linux/seq_file.h> #include <linux/mutex.h> #include <linux/nsproxy.h> +#include <linux/ipc_namespace.h> #include <asm/current.h> #include <asm/uaccess.h> @@ -92,6 +93,7 @@ static void __msg_init_ns(struct ipc_namipc_init_ids (ids); } +#ifdef CONFIG_NS_IPC int msg_init_ns (struct ipc_namespace *ns) {struct ipc_ids *ids;@@ -127,6 +129,7 @@ void msg_exit_ns(struct ipc_namespace *nkfree (ns->ids[IPC_MSG_IDS ]); ns->ids[IPC_MSG_IDS] = NULL; } +#endif void __init msg_init (void ) {ipc/namespace.c new file +73
-0@@ -0,0 +1,73 @@ +/* +* linux/ipc/namespace.c +* Copyright (C) 2006 Pavel Emelyanov <[email protected]> OpenVZ, SWsoft Inc. +*/ + +#include <linux/ipc.h> +#include <linux/msg.h> +#include <linux/ipc_namespace.h> +#include <linux/rcupdate.h> +#include <linux/nsproxy.h> +#include <linux/slab.h> + +#include "util.h" + +static struct ipc_namespace *clone_ipc_ns (struct ipc_namespace *old_ns) +{ +int err; +struct ipc_namespace *ns; + + err = -ENOMEM ; + ns =kmalloc (sizeof (struct ipc_namespace ),GFP_KERNEL ); +if (ns ==NULL ) + goto err_mem; + + err =sem_init_ns (ns); +if (err) + goto err_sem; + err =msg_init_ns (ns); +if (err) + goto err_msg; + err =shm_init_ns (ns); +if (err) + goto err_shm; + +kref_init (&ns->kref); +return ns; + +err_shm: +msg_exit_ns (ns); +err_msg: +sem_exit_ns (ns); +err_sem: +kfree (ns); +err_mem: +return ERR_PTR (err); +} + +struct ipc_namespace *copy_ipcs (unsigned long flags,struct ipc_namespace *ns) +{ +struct ipc_namespace *new_ns; + +BUG_ON (!ns); +get_ipc_ns (ns); + +if (!(flags &CLONE_NEWIPC )) +return ns; + + new_ns =clone_ipc_ns (ns); + +put_ipc_ns (ns); +return new_ns; +} + +void free_ipc_ns (struct kref *kref) +{ +struct ipc_namespace *ns; + + ns = container_of(kref, struct ipc_namespace, kref); +sem_exit_ns (ns); +msg_exit_ns (ns); +shm_exit_ns (ns); +kfree (ns); +}ipc/sem.c +3
-0@@ -82,6 +82,7 @@#include <linux/seq_file.h> #include <linux/mutex.h> #include <linux/nsproxy.h> +#include <linux/ipc_namespace.h> #include <asm/uaccess.h> #include "util.h" @@ -130,6 +131,7 @@ static void __sem_init_ns(struct ipc_namipc_init_ids (ids); } +#ifdef CONFIG_NS_IPC int sem_init_ns (struct ipc_namespace *ns) {struct ipc_ids *ids;@@ -165,6 +167,7 @@ void sem_exit_ns(struct ipc_namespace *nkfree (ns->ids[IPC_SEM_IDS ]); ns->ids[IPC_SEM_IDS] = NULL; } +#endif void __init sem_init (void ) {ipc/shm.c +3
-0@@ -38,6 +38,7 @@#include <linux/mutex.h> #include <linux/nsproxy.h> #include <linux/mount.h> +#include <linux/ipc_namespace.h> #include <asm/uaccess.h> @@ -97,6 +98,7 @@ static void do_shm_rmid(struct ipc_namesshm_destroy (ns, shp); } +#ifdef CONFIG_NS_IPC int shm_init_ns (struct ipc_namespace *ns) {struct ipc_ids *ids;@@ -132,6 +134,7 @@ void shm_exit_ns(struct ipc_namespace *nkfree (ns->ids[IPC_SHM_IDS ]); ns->ids[IPC_SHM_IDS] = NULL; } +#endif void __init shm_init (void ) {ipc/util.c +1
-60@@ -32,6 +32,7 @@#include <linux/proc_fs.h> #include <linux/audit.h> #include <linux/nsproxy.h> +#include <linux/ipc_namespace.h> #include <asm/unistd.h> @@ -50,66 +51,6 @@ struct ipc_namespace init_ipc_ns = { }, }; -static struct ipc_namespace *clone_ipc_ns (struct ipc_namespace *old_ns) -{ -int err; -struct ipc_namespace *ns; - - err = -ENOMEM ; - ns =kmalloc (sizeof (struct ipc_namespace ),GFP_KERNEL ); -if (ns ==NULL ) - goto err_mem; - - err =sem_init_ns (ns); -if (err) - goto err_sem; - err =msg_init_ns (ns); -if (err) - goto err_msg; - err =shm_init_ns (ns); -if (err) - goto err_shm; - -kref_init (&ns->kref); -return ns; - -err_shm: -msg_exit_ns (ns); -err_msg: -sem_exit_ns (ns); -err_sem: -kfree (ns); -err_mem: -return ERR_PTR (err); -} - -struct ipc_namespace *copy_ipcs (unsigned long flags,struct ipc_namespace *ns) -{ -struct ipc_namespace *new_ns; - -BUG_ON (!ns); -get_ipc_ns (ns); - -if (!(flags &CLONE_NEWIPC )) -return ns; - - new_ns =clone_ipc_ns (ns); - -put_ipc_ns (ns); -return new_ns; -} - -void free_ipc_ns (struct kref *kref) -{ -struct ipc_namespace *ns; - - ns = container_of(kref, struct ipc_namespace, kref); -sem_exit_ns (ns); -msg_exit_ns (ns); -shm_exit_ns (ns); -kfree (ns); -} -/** * ipc_init - initialise IPC subsystem * ipc/util.h +2
-0@@ -20,6 +20,8 @@ void sem_init (void);void msg_init (void );void shm_init (void ); +struct ipc_namespace ; +int sem_init_ns (struct ipc_namespace *ns);int msg_init_ns (struct ipc_namespace *ns);int shm_init_ns (struct ipc_namespace *ns);kernel/Makefile +4
-3@@ -4,12 +4,11 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ exit.o itimer.o time.o softirq.o resource.o \ - sysctl.o capability.o ptrace.o timer.o user.o user_namespace.o \ + sysctl.o capability.o ptrace.o timer.o user.o \ signal.o sys.o kmod.o workqueue.o pid.o \ rcupdate.o extable.o params.o posix-timers.o \ kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ - hrtimer.o rwsem.o latency.o nsproxy.o srcu.o \ - utsname.o notifier.o sysctl.o + hrtimer.o rwsem.o latency.o nsproxy.o srcu.o notifier.o sysctl.o obj-$(CONFIG_SYSCTL) += sysctl_check.o obj-$(CONFIG_STACKTRACE) += stacktrace.o@@ -50,6 +49,8 @@ obj-$(CONFIG_AUDITSYSCALL) += auditsc.o obj-$(CONFIG_AUDIT_TREE) += audit_tree.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KGDB) += kgdb.o +obj-$(CONFIG_NS_UTS) += utsname.o +obj-$(CONFIG_NS_UID) += user_namespace.o obj-$(CONFIG_SYSFS) += ksysfs.o obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o obj-$(CONFIG_GENERIC_HARDIRQS) += irq/kernel/nsproxy.c +1
-0@@ -20,6 +20,7 @@#include <linux/mnt_namespace.h> #include <linux/utsname.h> #include <linux/pid_namespace.h> +#include <linux/ipc_namespace.h> static struct kmem_cache *nsproxy_cachep;kernel/pid.c +14
-1@@ -432,6 +432,7 @@ struct pid *find_ge_pid(int nr, struct p }EXPORT_SYMBOL_GPL (find_get_pid); +#ifdef CONFIG_NS_PID struct pid_cache { int nr_ids; char name[16];@@ -482,6 +483,11 @@ err_alloc:return NULL ; } +static __init struct kmem_cache *create_init_pid_cachep (void ) +{ +return create_pid_cachep (1 ); +} +static struct pid_namespace *create_pid_namespace (int level) {struct pid_namespace *ns;@@ -603,6 +609,13 @@ void zap_pid_ns_processes(struct pid_nam pid_ns->child_reaper =NULL ; return; } +#else +static __init struct kmem_cache *create_init_pid_cachep (void ) +{ +return kmem_cache_create ("pid" ,sizeof (struct pid ),0 , +SLAB_HWCACHE_ALIGN ,NULL ); +} +#endif /* * The pid hash table is scaled according to the amount of memory in the @@ -636,7 +649,7 @@ void __init pidmap_init(void)set_bit (0 , init_pid_ns.pidmap[0 ].page);atomic_dec (&init_pid_ns.pidmap[0 ].nr_free); - init_pid_ns.pid_cachep =create_pid_cachep (1 ); + init_pid_ns.pid_cachep =create_init_pid_cachep ();if (init_pid_ns.pid_cachep ==NULL )panic ("Can't create pid_1 cachep\n" );kernel/user.c +11
-0@@ -17,6 +17,15 @@#include <linux/module.h> #include <linux/user_namespace.h> +struct user_namespace init_user_ns = { + .kref = { + .refcount =ATOMIC_INIT (2 ), + }, + .root_user = &root_user, +}; + +EXPORT_SYMBOL_GPL (init_user_ns); +/* * UID task count cache, to get fast user lookup in "alloc_uid" * when changing user ID's (ie setuid() and friends). @@ -199,6 +208,7 @@ void switch_uid(struct user_struct *new_suid_keys (current); } +#ifdef CONFIG_NS_UID void release_uids (struct user_namespace *ns) {int i;@@ -223,6 +233,7 @@ void release_uids(struct user_namespace free_uid(ns->root_user); } +#endif static int __init uid_cache_init (void ) {kernel/user_namespace.c +0
-13@@ -10,17 +10,6 @@#include <linux/nsproxy.h> #include <linux/user_namespace.h> -struct user_namespace init_user_ns = { - .kref = { - .refcount =ATOMIC_INIT (2 ), - }, - .root_user = &root_user, -}; - -EXPORT_SYMBOL_GPL (init_user_ns); - -#ifdef CONFIG_USER_NS -/* * Clone a new ns copying an original user ns, setting refcount to 1 * @old_ns: namespace to clone @@ -84,5 +73,3 @@ void free_user_ns(struct kref *kref)release_uids (ns);kfree (ns); } - -#endif /* CONFIG_USER_NS */ kernel/utsname.c +0
-0
A message that is not in the archive (sent off-list or not yet received): 20070926131349.GA20637-6s5zFf/[email protected]
Quoted 41 lines · Serge E. Hallyn
Quoted 40 lines · Pavel Emelyanov
Hi, guys!
I've noticed that compiling out all the core related to cloning and cleaning the new namespace saves us more than a Kbyte (!) from the vmlinux.
add/remove: 19/0 grow/shrink: 6/6 up/down: 1532/-336 (1196)
function old new delta copy_user_ns - 181 +181 copy_ipcs - 149 +149 copy_utsname - 120 +120 shm_exit_ns - 106 +106 sem_exit_ns - 106 +106 msg_exit_ns - 106 +106 freeary - 100 +100 release_uids - 95 +95 freeque - 92 +92 free_nsproxy 48 99 +51 __sem_init_ns - 45 +45 shm_init_ns - 42 +42 sem_init_ns - 42 +42 msg_init_ns - 42 +42 __shm_init_ns - 38 +38 create_new_namespaces 300 335 +35 __msg_init_ns - 31 +31 sysvipc_proc_release 5 35 +30 free_ipc_ns - 30 +30 do_shm_rmid - 29 +29 shm_release 18 39 +21 free_user_ns - 16 +16 sysvipc_proc_open 100 111 +11 do_shmat 778 787 +9 free_uts_ns - 5 +5 sys_shmctl 1934 1907 -27 msg_init 82 47 -35 shm_init 92 47 -45 sem_init 99 44 -55 sys_msgctl 1394 1311 -83 sys_semctl 2123 2032 -91
Quoted 8 lines
Quoted 6 lines
Since there already were some questions like "do I need it on my cellphone?" in reply to pid namespaces patches and so on, why don't we make ALL the namespaces cloning code under the config option to make those people happy?
Here's the proposed patch.
How about a single config variable for all namespaces?
yes good idea.
C.
A message that is not in the archive (sent off-list or not yet received): 46FA5BF3.4030505-NmTC/[email protected]
Quoted 47 lines · Cedric Le Goater
Quoted 46 lines · Serge E. Hallyn
Quoted 45 lines · Pavel Emelyanov
Hi, guys!
I've noticed that compiling out all the core related to cloning and cleaning the new namespace saves us more than a Kbyte (!) from the vmlinux.
add/remove: 19/0 grow/shrink: 6/6 up/down: 1532/-336 (1196)
function old new delta copy_user_ns - 181 +181 copy_ipcs - 149 +149 copy_utsname - 120 +120 shm_exit_ns - 106 +106 sem_exit_ns - 106 +106 msg_exit_ns - 106 +106 freeary - 100 +100 release_uids - 95 +95 freeque - 92 +92 free_nsproxy 48 99 +51 __sem_init_ns - 45 +45 shm_init_ns - 42 +42 sem_init_ns - 42 +42 msg_init_ns - 42 +42 __shm_init_ns - 38 +38 create_new_namespaces 300 335 +35 __msg_init_ns - 31 +31 sysvipc_proc_release 5 35 +30 free_ipc_ns - 30 +30 do_shm_rmid - 29 +29 shm_release 18 39 +21 free_user_ns - 16 +16 sysvipc_proc_open 100 111 +11 do_shmat 778 787 +9 free_uts_ns - 5 +5 sys_shmctl 1934 1907 -27 msg_init 82 47 -35 shm_init 92 47 -45 sem_init 99 44 -55 sys_msgctl 1394 1311 -83 sys_semctl 2123 2032 -91Since there already were some questions like "do I need it on my cellphone?" in reply to pid namespaces patches and so on, why don't we make ALL the namespaces cloning code under the config option to make those people happy?
Quoted 4 lines
Quoted 2 lines
Quoted 1 line
Here's the proposed patch.
How about a single config variable for all namespaces?
yes good idea.
oops, that done already in the patch : CONFIG_NAMESPACES
thanks :)
C.
A message that is not in the archive (sent off-list or not yet received): 46FA5C5C.2070906-NmTC/[email protected]
Quoted 48 lines · Cedric Le Goater
Quoted 47 lines · Cedric Le Goater
Quoted 46 lines · Serge E. Hallyn
Quoted 45 lines · Pavel Emelyanov
Hi, guys!
I've noticed that compiling out all the core related to cloning and cleaning the new namespace saves us more than a Kbyte (!) from the vmlinux.
add/remove: 19/0 grow/shrink: 6/6 up/down: 1532/-336 (1196)
function old new delta copy_user_ns - 181 +181 copy_ipcs - 149 +149 copy_utsname - 120 +120 shm_exit_ns - 106 +106 sem_exit_ns - 106 +106 msg_exit_ns - 106 +106 freeary - 100 +100 release_uids - 95 +95 freeque - 92 +92 free_nsproxy 48 99 +51 __sem_init_ns - 45 +45 shm_init_ns - 42 +42 sem_init_ns - 42 +42 msg_init_ns - 42 +42 __shm_init_ns - 38 +38 create_new_namespaces 300 335 +35 __msg_init_ns - 31 +31 sysvipc_proc_release 5 35 +30 free_ipc_ns - 30 +30 do_shm_rmid - 29 +29 shm_release 18 39 +21 free_user_ns - 16 +16 sysvipc_proc_open 100 111 +11 do_shmat 778 787 +9 free_uts_ns - 5 +5 sys_shmctl 1934 1907 -27 msg_init 82 47 -35 shm_init 92 47 -45 sem_init 99 44 -55 sys_msgctl 1394 1311 -83 sys_semctl 2123 2032 -91Since there already were some questions like "do I need it on my cellphone?" in reply to pid namespaces patches and so on, why don't we make ALL the namespaces cloning code under the config option to make those people happy?
Quoted 6 lines
Quoted 3 lines
Quoted 2 lines
Quoted 1 line
Here's the proposed patch.
How about a single config variable for all namespaces?
yes good idea.
oops, that done already in the patch :
CONFIG_NAMESPACES
So... Acked-by: Serge E. Hallyn and Cedric Le Goater ? :)
Quoted 5 lines
thanks :)
C.
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 47 lines · Pavel Emelyanov
Quoted 46 lines · Cedric Le Goater
Quoted 45 lines · Cedric Le Goater
Quoted 44 lines · Serge E. Hallyn
Quoted 43 lines · Pavel Emelyanov
Hi, guys!
I've noticed that compiling out all the core related to cloning and cleaning the new namespace saves us more than a Kbyte (!) from the vmlinux.
add/remove: 19/0 grow/shrink: 6/6 up/down: 1532/-336 (1196)
function old new delta copy_user_ns - 181 +181 copy_ipcs - 149 +149 copy_utsname - 120 +120 shm_exit_ns - 106 +106 sem_exit_ns - 106 +106 msg_exit_ns - 106 +106 freeary - 100 +100 release_uids - 95 +95 freeque - 92 +92 free_nsproxy 48 99 +51 __sem_init_ns - 45 +45 shm_init_ns - 42 +42 sem_init_ns - 42 +42 msg_init_ns - 42 +42 __shm_init_ns - 38 +38 create_new_namespaces 300 335 +35 __msg_init_ns - 31 +31 sysvipc_proc_release 5 35 +30 free_ipc_ns - 30 +30 do_shm_rmid - 29 +29 shm_release 18 39 +21 free_user_ns - 16 +16 sysvipc_proc_open 100 111 +11 do_shmat 778 787 +9 free_uts_ns - 5 +5 sys_shmctl 1934 1907 -27 msg_init 82 47 -35 shm_init 92 47 -45 sem_init 99 44 -55 sys_msgctl 1394 1311 -83 sys_semctl 2123 2032 -91Since there already were some questions like "do I need it
on my cellphone?" in reply to pid namespaces patches and so on, why don't we make ALL the namespaces cloning code under the config option to make those people happy?
Quoted 7 lines
Quoted 5 lines
Quoted 3 lines
Quoted 2 lines
Quoted 1 line
Here's the proposed patch.
How about a single config variable for all namespaces?
yes good idea.
oops, that done already in the patch :
CONFIG_NAMESPACESSo... Acked-by: Serge E. Hallyn and Cedric Le Goater ? :)
That is a good idea, that will avoid to have the namespaces config all around the menuconfig too.
Quoted 49 lines · Cedric Le Goater
Quoted 48 lines · Cedric Le Goater
Quoted 47 lines · Serge E. Hallyn
Quoted 46 lines · Pavel Emelyanov
Hi, guys!
I've noticed that compiling out all the core related to cloning and cleaning the new namespace saves us more than a Kbyte (!) from the vmlinux.
add/remove: 19/0 grow/shrink: 6/6 up/down: 1532/-336 (1196)
function old new delta copy_user_ns - 181 +181 copy_ipcs - 149 +149 copy_utsname - 120 +120 shm_exit_ns - 106 +106 sem_exit_ns - 106 +106 msg_exit_ns - 106 +106 freeary - 100 +100 release_uids - 95 +95 freeque - 92 +92 free_nsproxy 48 99 +51 __sem_init_ns - 45 +45 shm_init_ns - 42 +42 sem_init_ns - 42 +42 msg_init_ns - 42 +42 __shm_init_ns - 38 +38 create_new_namespaces 300 335 +35 __msg_init_ns - 31 +31 sysvipc_proc_release 5 35 +30 free_ipc_ns - 30 +30 do_shm_rmid - 29 +29 shm_release 18 39 +21 free_user_ns - 16 +16 sysvipc_proc_open 100 111 +11 do_shmat 778 787 +9 free_uts_ns - 5 +5 sys_shmctl 1934 1907 -27 msg_init 82 47 -35 shm_init 92 47 -45 sem_init 99 44 -55 sys_msgctl 1394 1311 -83 sys_semctl 2123 2032 -91Since there already were some questions like "do I need it on my cellphone?" in reply to pid namespaces patches and so on, why don't we make ALL the namespaces cloning code under the config option to make those people happy?
Here's the proposed patch.
Quoted 8 lines
Quoted 3 lines
Quoted 1 line
How about a single config variable for all namespaces?
yes good idea.
oops, that done already in the patch :
CONFIG_NAMESPACESthanks :)
That at least organizes them all in Kconfig. I meant one config variable, period.
Then instead of adding CONFIG_USER_NS and such whlie they are experimental, put all experimental namespaces (i.e. maybe soon user and network) under CONFIG_NAMESPACES_EXPERIMENTAL.
-serge
Quoted 5 lines · Pavel Emelyanov
Hi, guys!
I've noticed that compiling out all the core related to cloning and cleaning the new namespace saves us more than a Kbyte (!) from the vmlinux.
cool.
but compared to the 5KB pid ns is adding, it's not much. I guess anything that can be saved is good to save when you run on a cell.
Quoted 34 lines
add/remove: 19/0 grow/shrink: 6/6 up/down: 1532/-336 (1196)
function old new delta copy_user_ns - 181 +181 copy_ipcs - 149 +149 copy_utsname - 120 +120 shm_exit_ns - 106 +106 sem_exit_ns - 106 +106 msg_exit_ns - 106 +106 freeary - 100 +100 release_uids - 95 +95 freeque - 92 +92 free_nsproxy 48 99 +51 __sem_init_ns - 45 +45 shm_init_ns - 42 +42 sem_init_ns - 42 +42 msg_init_ns - 42 +42 __shm_init_ns - 38 +38 create_new_namespaces 300 335 +35 __msg_init_ns - 31 +31 sysvipc_proc_release 5 35 +30 free_ipc_ns - 30 +30 do_shm_rmid - 29 +29 shm_release 18 39 +21 free_user_ns - 16 +16 sysvipc_proc_open 100 111 +11 do_shmat 778 787 +9 free_uts_ns - 5 +5 sys_shmctl 1934 1907 -27 msg_init 82 47 -35 shm_init 92 47 -45 sem_init 99 44 -55 sys_msgctl 1394 1311 -83 sys_semctl 2123 2032 -91
Quoted 6 lines
Since there already were some questions like "do I need it on my cellphone?" in reply to pid namespaces patches and so on, why don't we make ALL the namespaces cloning code under the config option to make those people happy?
Here's the proposed patch.
I think I'm ok with it but it would be easier to review if you could split it in little patchlets, at least one for each namespace. diffstats are welcome also :)
include/linux/ipc_namespace.h
Quoted 70 lines
Signed-off-by Pavel Emelyanov <[email protected]>---
include/linux/ipc.h +0
-50@@ -100,56 +100,6 @@ struct kern_ipc_permvoid *security; }; -struct ipc_ids ; -struct ipc_namespace { -struct kref kref; -struct ipc_ids *ids[3 ]; - -int sem_ctls[4 ]; -int used_sems; - -int msg_ctlmax; -int msg_ctlmnb; -int msg_ctlmni; - -size_t shm_ctlmax; -size_t shm_ctlall; -int shm_ctlmni; -int shm_tot; -}; - -extern struct ipc_namespace init_ipc_ns; - -#ifdef CONFIG_SYSVIPC -#define INIT_IPC_NS (ns) .ns = &init_ipc_ns, -extern void free_ipc_ns (struct kref *kref); -extern struct ipc_namespace *copy_ipcs (unsigned long flags, -struct ipc_namespace *ns); -#else -#define INIT_IPC_NS (ns) -static inline struct ipc_namespace *copy_ipcs (unsigned long flags, -struct ipc_namespace *ns) -{ -return ns; -} -#endif - -static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) -{ -#ifdef CONFIG_SYSVIPC -if (ns) -kref_get (&ns->kref); -#endif -return ns; -} - -static inline void put_ipc_ns (struct ipc_namespace *ns) -{ -#ifdef CONFIG_SYSVIPC -kref_put (&ns->kref, free_ipc_ns); -#endif -} -#endif /* __KERNEL__ */ #endif /* _LINUX_IPC_H */ include/linux/ipc_namespace.h new file +0
-0
that's something i wanted to do. thanks.
Quoted 23 lines
include/linux/ipc_namespace.h new file +22
-0@@ -0,0 +1,67 @@ +#ifndef __IPC_NAMESPACE_H__ +#define __IPC_NAMESPACE_H__ + +#include <linux/err.h> + +struct ipc_ids ; +struct ipc_namespace { +struct kref kref; +struct ipc_ids *ids[3 ]; + +int sem_ctls[4 ]; +int used_sems; + +int msg_ctlmax; +int msg_ctlmnb; +int msg_ctlmni; + +size_t shm_ctlmax; +size_t shm_ctlall; +int shm_ctlmni; +int shm_tot; +};
include/linux/ipc_namespace.h line 32
Quoted 10 lines
include/linux/ipc_namespace.h new file +10
-0+ +extern struct ipc_namespace init_ipc_ns; + +#ifdef CONFIG_SYSVIPC +#define INIT_IPC_NS (ns) .ns = &init_ipc_ns, +#else +#define INIT_IPC_NS (ns) +#endif + +#ifdef CONFIG_NS_IPC
ok so you're readding that flag. please check ipc/ipc_sysctl.c there might be some surprises.
check the compile with CONFIG_SYSCTL=n
Quoted 202 lines
include/linux/ipc_namespace.h new file +35
-0+extern void free_ipc_ns (struct kref *kref); +extern struct ipc_namespace *copy_ipcs (unsigned long flags, +struct ipc_namespace *ns); + +static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) +{ +if (ns) +kref_get (&ns->kref); +return ns; +} + +static inline void put_ipc_ns (struct ipc_namespace *ns) +{ +kref_put (&ns->kref, free_ipc_ns); +} +#else +static inline struct ipc_namespace *copy_ipcs (unsigned long flags, +struct ipc_namespace *ns) +{ +if (flags &CLONE_NEWIPC ) +return ERR_PTR (-EINVAL ); + +return ns; +} + +static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) +{ +return ns; +} + +static inline void put_ipc_ns (struct ipc_namespace *ns) +{ +} +#endif +#endif include/linux/nsproxy.h +0
-0include/linux/pid.h +0
-1@@ -122,7 +122,6 @@ extern struct pid *find_ge_pid(int nr, sextern struct pid *alloc_pid (struct pid_namespace *ns);extern void FASTCALL (free_pid (struct pid *pid)); -extern void zap_pid_ns_processes (struct pid_namespace *pid_ns);/* * the helpers to get the pid's id seen from different namespaces include/linux/pid_namespace.h +27
-0@@ -6,6 +6,7 @@#include <linux/threads.h> #include <linux/nsproxy.h> #include <linux/kref.h> +#include <linux/err.h> struct pidmap {atomic_t nr_free;@@ -29,6 +30,7 @@ struct pid_namespace {extern struct pid_namespace init_pid_ns; +#ifdef CONFIG_NS_PID static inline struct pid_namespace *get_pid_ns (struct pid_namespace *ns) {if (ns != &init_pid_ns)@@ -38,12 +40,37 @@ static inline struct pid_namespace *get_extern struct pid_namespace *copy_pid_ns (unsigned long flags,struct pid_namespace *ns);extern void free_pid_ns (struct kref *kref); +extern void zap_pid_ns_processes (struct pid_namespace *pid_ns);static inline void put_pid_ns (struct pid_namespace *ns) {if (ns != &init_pid_ns)kref_put (&ns->kref, free_pid_ns); } +#else +static inline struct pid_namespace *get_pid_ns (struct pid_namespace *ns) +{ +return ns; +} + +static inline void put_pid_ns (struct pid_namespace *ns) +{ +} + +static inline struct pid_namespace *copy_pid_ns (unsigned long flags, +struct pid_namespace *ns) +{ +if (flags &CLONE_NEWPID ) +return ERR_PTR (-EINVAL ); + +return ns; +} + +static inline void zap_pid_ns_processes (struct pid_namespace *ns) +{ +BUG (); +} +#endif static inline struct pid_namespace *task_active_pid_ns (struct task_struct *tsk) {include/linux/sched.h +0
-0include/linux/sem.h +0
-0include/linux/user_namespace.h +1
-1@@ -17,7 +17,7 @@ struct user_namespace {extern struct user_namespace init_user_ns; -#ifdef CONFIG_USER_NS +#ifdef CONFIG_NS_UID static inline struct user_namespace *get_user_ns (struct user_namespace *ns) {include/linux/utsname.h +21
-0@@ -35,6 +35,7 @@ struct new_utsname {#include <linux/sched.h> #include <linux/kref.h> #include <linux/nsproxy.h> +#include <linux/err.h> #include <asm/atomic.h> struct uts_namespace {@@ -43,6 +44,7 @@ struct uts_namespace { };extern struct uts_namespace init_uts_ns; +#ifdef CONFIG_NS_UTS static inline void get_uts_ns (struct uts_namespace *ns) {kref_get (&ns->kref);@@ -56,6 +58,25 @@ static inline void put_uts_ns(struct uts {kref_put (&ns->kref, free_uts_ns); } +#else +static inline void get_uts_ns (struct uts_namespace *ns) +{ +} + +static inline void put_uts_ns (struct uts_namespace *ns) +{ +} + +static inline struct uts_namespace *copy_utsname (unsigned long flags, +struct uts_namespace *ns) +{ +if (flags &CLONE_NEWUTS ) +return ERR_PTR (-EINVAL ); + +return ns; +} +#endif +static inline struct new_utsname *utsname (void ) {return ¤t->nsproxy->uts_ns->name;init/Kconfig +11
-9@@ -206,15 +206,6 @@ config TASK_IO_ACCOUNTING Say N if unsure. -config USER_NS - bool "User Namespaces (EXPERIMENTAL)" - default n - depends on EXPERIMENTAL - help - Support user namespaces. This allows containers, i.e. - vservers, to use user namespaces to provide different - user info for different servers. If unsure, say N. - config AUDIT bool "Auditing support" depends on NET@@ -369,6 +360,39 @@ config RELAY If unsure, say N. +config NAMESPACES + bool "The namespaces support" + help + Provides the way to make tasks work with different objects using + the same id + +config NS_UTS + bool "Uname namespace" + depends on NAMESPACES + help + The utsname namespace
init/Kconfig config RELAY · line 383
Quoted 10 lines
init/Kconfig +10
-0+ +config NS_IPC + bool "IPC namespace" + depends on NAMESPACES && SYSVIPC + help + The SYSVIPC ids namespaces + +config NS_PIDS + bool "PID namespace" + depends on NAMESPACES
I'd put experimental on this one also
Quoted 21 lines
init/Kconfig +12
-0+ help + Tasks see only the pids living in the same namespace and in the + child namespaces + +config NS_UID + bool "UID namespace" + depends on NAMESPACES && EXPERIMENTAL + help + Support user namespaces. This allows containers, i.e. + vservers, to use user namespaces to provide different + user info for different servers. If unsure, say N. + config BLK_DEV_INITRD bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" depends on BROKEN || !FRVinit/main.c +0
-0ipc/Makefile +0
-0
ipc/Makefile obj-$(CONFIG_SYSVIPC) += util.o msgutil. · line 10
Quoted 4 lines
ipc/Makefile +1
-0@@ -7,4 +7,5 @@ obj-$(CONFIG_SYSVIPC) += util.o msgutil. obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o obj_mq-$(CONFIG_COMPAT) += compat_mq.o obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y) +obj-$(CONFIG_NS_IPC) += namespace.o
ipc_namespace.c is a better name.
Quoted 34 lines
ipc/ipc_sysctl.c +1
-0@@ -14,6 +14,7 @@#include <linux/nsproxy.h> #include <linux/sysctl.h> #include <linux/uaccess.h> +#include <linux/ipc_namespace.h> static void *get_ipc (ctl_table *table) {ipc/msg.c +2
-0@@ -36,6 +36,7 @@#include <linux/seq_file.h> #include <linux/mutex.h> #include <linux/nsproxy.h> +#include <linux/ipc_namespace.h> #include <asm/current.h> #include <asm/uaccess.h> @@ -92,6 +93,7 @@ static void __msg_init_ns(struct ipc_namipc_init_ids (ids); } +#ifdef CONFIG_NS_IPC int msg_init_ns (struct ipc_namespace *ns) {struct ipc_ids *ids;
ipc/msg.c void msg_exit_ns(struct ipc_namespace *n · line 132
Quoted 4 lines
ipc/msg.c +1
-0@@ -127,6 +129,7 @@ void msg_exit_ns(struct ipc_namespace *nkfree (ns->ids[IPC_MSG_IDS ]); ns->ids[IPC_MSG_IDS] = NULL; } +#endif
can't this routine be in ipc_namespace.c to remove the #ifdef CONFIG_NS_IPC ? the same apply to the other init routine.
ipc/namespace.c
Quoted 3 lines
ipc/msg.c +0
-0void __init msg_init (void ) {ipc/namespace.c +0
-0
i'd call it ipc_namespace.c
Quoted 379 lines
new file mode 100644
index 0000000..cef1139ipc/namespace.c new file +73
-0@@ -0,0 +1,73 @@ +/* +* linux/ipc/namespace.c +* Copyright (C) 2006 Pavel Emelyanov <[email protected]> OpenVZ, SWsoft Inc. +*/ + +#include <linux/ipc.h> +#include <linux/msg.h> +#include <linux/ipc_namespace.h> +#include <linux/rcupdate.h> +#include <linux/nsproxy.h> +#include <linux/slab.h> + +#include "util.h" + +static struct ipc_namespace *clone_ipc_ns (struct ipc_namespace *old_ns) +{ +int err; +struct ipc_namespace *ns; + + err = -ENOMEM ; + ns =kmalloc (sizeof (struct ipc_namespace ),GFP_KERNEL ); +if (ns ==NULL ) + goto err_mem; + + err =sem_init_ns (ns); +if (err) + goto err_sem; + err =msg_init_ns (ns); +if (err) + goto err_msg; + err =shm_init_ns (ns); +if (err) + goto err_shm; + +kref_init (&ns->kref); +return ns; + +err_shm: +msg_exit_ns (ns); +err_msg: +sem_exit_ns (ns); +err_sem: +kfree (ns); +err_mem: +return ERR_PTR (err); +} + +struct ipc_namespace *copy_ipcs (unsigned long flags,struct ipc_namespace *ns) +{ +struct ipc_namespace *new_ns; + +BUG_ON (!ns); +get_ipc_ns (ns); + +if (!(flags &CLONE_NEWIPC )) +return ns; + + new_ns =clone_ipc_ns (ns); + +put_ipc_ns (ns); +return new_ns; +} + +void free_ipc_ns (struct kref *kref) +{ +struct ipc_namespace *ns; + + ns = container_of(kref, struct ipc_namespace, kref); +sem_exit_ns (ns); +msg_exit_ns (ns); +shm_exit_ns (ns); +kfree (ns); +}ipc/sem.c +3
-0@@ -82,6 +82,7 @@#include <linux/seq_file.h> #include <linux/mutex.h> #include <linux/nsproxy.h> +#include <linux/ipc_namespace.h> #include <asm/uaccess.h> #include "util.h" @@ -130,6 +131,7 @@ static void __sem_init_ns(struct ipc_namipc_init_ids (ids); } +#ifdef CONFIG_NS_IPC int sem_init_ns (struct ipc_namespace *ns) {struct ipc_ids *ids;@@ -165,6 +167,7 @@ void sem_exit_ns(struct ipc_namespace *nkfree (ns->ids[IPC_SEM_IDS ]); ns->ids[IPC_SEM_IDS] = NULL; } +#endif void __init sem_init (void ) {ipc/shm.c +3
-0@@ -38,6 +38,7 @@#include <linux/mutex.h> #include <linux/nsproxy.h> #include <linux/mount.h> +#include <linux/ipc_namespace.h> #include <asm/uaccess.h> @@ -97,6 +98,7 @@ static void do_shm_rmid(struct ipc_namesshm_destroy (ns, shp); } +#ifdef CONFIG_NS_IPC int shm_init_ns (struct ipc_namespace *ns) {struct ipc_ids *ids;@@ -132,6 +134,7 @@ void shm_exit_ns(struct ipc_namespace *nkfree (ns->ids[IPC_SHM_IDS ]); ns->ids[IPC_SHM_IDS] = NULL; } +#endif void __init shm_init (void ) {ipc/util.c +1
-60@@ -32,6 +32,7 @@#include <linux/proc_fs.h> #include <linux/audit.h> #include <linux/nsproxy.h> +#include <linux/ipc_namespace.h> #include <asm/unistd.h> @@ -50,66 +51,6 @@ struct ipc_namespace init_ipc_ns = { }, }; -static struct ipc_namespace *clone_ipc_ns (struct ipc_namespace *old_ns) -{ -int err; -struct ipc_namespace *ns; - - err = -ENOMEM ; - ns =kmalloc (sizeof (struct ipc_namespace ),GFP_KERNEL ); -if (ns ==NULL ) - goto err_mem; - - err =sem_init_ns (ns); -if (err) - goto err_sem; - err =msg_init_ns (ns); -if (err) - goto err_msg; - err =shm_init_ns (ns); -if (err) - goto err_shm; - -kref_init (&ns->kref); -return ns; - -err_shm: -msg_exit_ns (ns); -err_msg: -sem_exit_ns (ns); -err_sem: -kfree (ns); -err_mem: -return ERR_PTR (err); -} - -struct ipc_namespace *copy_ipcs (unsigned long flags,struct ipc_namespace *ns) -{ -struct ipc_namespace *new_ns; - -BUG_ON (!ns); -get_ipc_ns (ns); - -if (!(flags &CLONE_NEWIPC )) -return ns; - - new_ns =clone_ipc_ns (ns); - -put_ipc_ns (ns); -return new_ns; -} - -void free_ipc_ns (struct kref *kref) -{ -struct ipc_namespace *ns; - - ns = container_of(kref, struct ipc_namespace, kref); -sem_exit_ns (ns); -msg_exit_ns (ns); -shm_exit_ns (ns); -kfree (ns); -} -/** * ipc_init - initialise IPC subsystem * ipc/util.h +2
-0@@ -20,6 +20,8 @@ void sem_init (void);void msg_init (void );void shm_init (void ); +struct ipc_namespace ; +int sem_init_ns (struct ipc_namespace *ns);int msg_init_ns (struct ipc_namespace *ns);int shm_init_ns (struct ipc_namespace *ns);kernel/Makefile +4
-3@@ -4,12 +4,11 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ exit.o itimer.o time.o softirq.o resource.o \ - sysctl.o capability.o ptrace.o timer.o user.o user_namespace.o \ + sysctl.o capability.o ptrace.o timer.o user.o \ signal.o sys.o kmod.o workqueue.o pid.o \ rcupdate.o extable.o params.o posix-timers.o \ kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ - hrtimer.o rwsem.o latency.o nsproxy.o srcu.o \ - utsname.o notifier.o sysctl.o + hrtimer.o rwsem.o latency.o nsproxy.o srcu.o notifier.o sysctl.o obj-$(CONFIG_SYSCTL) += sysctl_check.o obj-$(CONFIG_STACKTRACE) += stacktrace.o@@ -50,6 +49,8 @@ obj-$(CONFIG_AUDITSYSCALL) += auditsc.o obj-$(CONFIG_AUDIT_TREE) += audit_tree.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KGDB) += kgdb.o +obj-$(CONFIG_NS_UTS) += utsname.o +obj-$(CONFIG_NS_UID) += user_namespace.o obj-$(CONFIG_SYSFS) += ksysfs.o obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o obj-$(CONFIG_GENERIC_HARDIRQS) += irq/kernel/nsproxy.c +1
-0@@ -20,6 +20,7 @@#include <linux/mnt_namespace.h> #include <linux/utsname.h> #include <linux/pid_namespace.h> +#include <linux/ipc_namespace.h> static struct kmem_cache *nsproxy_cachep;kernel/pid.c +14
-1@@ -432,6 +432,7 @@ struct pid *find_ge_pid(int nr, struct p }EXPORT_SYMBOL_GPL (find_get_pid); +#ifdef CONFIG_NS_PID struct pid_cache { int nr_ids; char name[16];@@ -482,6 +483,11 @@ err_alloc:return NULL ; } +static __init struct kmem_cache *create_init_pid_cachep (void ) +{ +return create_pid_cachep (1 ); +} +static struct pid_namespace *create_pid_namespace (int level) {struct pid_namespace *ns;@@ -603,6 +609,13 @@ void zap_pid_ns_processes(struct pid_nam pid_ns->child_reaper =NULL ; return; } +#else +static __init struct kmem_cache *create_init_pid_cachep (void ) +{ +return kmem_cache_create ("pid" ,sizeof (struct pid ),0 , +SLAB_HWCACHE_ALIGN ,NULL ); +} +#endif /* * The pid hash table is scaled according to the amount of memory in the @@ -636,7 +649,7 @@ void __init pidmap_init(void)set_bit (0 , init_pid_ns.pidmap[0 ].page);atomic_dec (&init_pid_ns.pidmap[0 ].nr_free); - init_pid_ns.pid_cachep =create_pid_cachep (1 ); + init_pid_ns.pid_cachep =create_init_pid_cachep ();if (init_pid_ns.pid_cachep ==NULL )panic ("Can't create pid_1 cachep\n" );kernel/user.c +11
-0@@ -17,6 +17,15 @@#include <linux/module.h> #include <linux/user_namespace.h> +struct user_namespace init_user_ns = { + .kref = { + .refcount =ATOMIC_INIT (2 ), + }, + .root_user = &root_user, +}; + +EXPORT_SYMBOL_GPL (init_user_ns); +/* * UID task count cache, to get fast user lookup in "alloc_uid" * when changing user ID's (ie setuid() and friends). @@ -199,6 +208,7 @@ void switch_uid(struct user_struct *new_suid_keys (current); } +#ifdef CONFIG_NS_UID void release_uids (struct user_namespace *ns) {int i;@@ -223,6 +233,7 @@ void release_uids(struct user_namespace free_uid(ns->root_user); } +#endif static int __init uid_cache_init (void ) {kernel/user_namespace.c +0
-13@@ -10,17 +10,6 @@#include <linux/nsproxy.h> #include <linux/user_namespace.h> -struct user_namespace init_user_ns = { - .kref = { - .refcount =ATOMIC_INIT (2 ), - }, - .root_user = &root_user, -}; - -EXPORT_SYMBOL_GPL (init_user_ns); - -#ifdef CONFIG_USER_NS -/* * Clone a new ns copying an original user ns, setting refcount to 1 * @old_ns: namespace to clone @@ -84,5 +73,3 @@ void free_user_ns(struct kref *kref)release_uids (ns);kfree (ns); } - -#endif /* CONFIG_USER_NS */ kernel/utsname.c +0
-0
A message that is not in the archive (sent off-list or not yet received): 46FA5D83.2010308-NmTC/[email protected]
Quoted 11 lines · Cedric Le Goater
Quoted 5 lines · Pavel Emelyanov
Hi, guys!
I've noticed that compiling out all the core related to cloning and cleaning the new namespace saves us more than a Kbyte (!) from the vmlinux.
cool.
but compared to the 5KB pid ns is adding, it's not much. I guess anything that can be saved is good to save when you run on a cell.
Yup, but I've already sent 3 patches to Andrew that save 1.5 KB so we have already managed to get a half for cell users ;)
Quoted 828 lines
Quoted 34 lines
add/remove: 19/0 grow/shrink: 6/6 up/down: 1532/-336 (1196)
function old new delta copy_user_ns - 181 +181 copy_ipcs - 149 +149 copy_utsname - 120 +120 shm_exit_ns - 106 +106 sem_exit_ns - 106 +106 msg_exit_ns - 106 +106 freeary - 100 +100 release_uids - 95 +95 freeque - 92 +92 free_nsproxy 48 99 +51 __sem_init_ns - 45 +45 shm_init_ns - 42 +42 sem_init_ns - 42 +42 msg_init_ns - 42 +42 __shm_init_ns - 38 +38 create_new_namespaces 300 335 +35 __msg_init_ns - 31 +31 sysvipc_proc_release 5 35 +30 free_ipc_ns - 30 +30 do_shm_rmid - 29 +29 shm_release 18 39 +21 free_user_ns - 16 +16 sysvipc_proc_open 100 111 +11 do_shmat 778 787 +9 free_uts_ns - 5 +5 sys_shmctl 1934 1907 -27 msg_init 82 47 -35 shm_init 92 47 -45 sem_init 99 44 -55 sys_msgctl 1394 1311 -83 sys_semctl 2123 2032 -91Quoted 6 lines
Since there already were some questions like "do I need it on my cellphone?" in reply to pid namespaces patches and so on, why don't we make ALL the namespaces cloning code under the config option to make those people happy?
Here's the proposed patch.
I think I'm ok with it but it would be easier to review if you could split it in little patchlets, at least one for each namespace. diffstats are welcome also :)
include/linux/ipc_namespace.h
Quoted 70 lines
Signed-off-by Pavel Emelyanov <[email protected]>---
include/linux/ipc.h +0
-50@@ -100,56 +100,6 @@ struct kern_ipc_permvoid *security; }; -struct ipc_ids ; -struct ipc_namespace { -struct kref kref; -struct ipc_ids *ids[3 ]; - -int sem_ctls[4 ]; -int used_sems; - -int msg_ctlmax; -int msg_ctlmnb; -int msg_ctlmni; - -size_t shm_ctlmax; -size_t shm_ctlall; -int shm_ctlmni; -int shm_tot; -}; - -extern struct ipc_namespace init_ipc_ns; - -#ifdef CONFIG_SYSVIPC -#define INIT_IPC_NS (ns) .ns = &init_ipc_ns, -extern void free_ipc_ns (struct kref *kref); -extern struct ipc_namespace *copy_ipcs (unsigned long flags, -struct ipc_namespace *ns); -#else -#define INIT_IPC_NS (ns) -static inline struct ipc_namespace *copy_ipcs (unsigned long flags, -struct ipc_namespace *ns) -{ -return ns; -} -#endif - -static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) -{ -#ifdef CONFIG_SYSVIPC -if (ns) -kref_get (&ns->kref); -#endif -return ns; -} - -static inline void put_ipc_ns (struct ipc_namespace *ns) -{ -#ifdef CONFIG_SYSVIPC -kref_put (&ns->kref, free_ipc_ns); -#endif -} -#endif /* __KERNEL__ */ #endif /* _LINUX_IPC_H */ include/linux/ipc_namespace.h new file +0
-0that's something i wanted to do. thanks.
Quoted 23 lines
include/linux/ipc_namespace.h new file +22
-0@@ -0,0 +1,67 @@ +#ifndef __IPC_NAMESPACE_H__ +#define __IPC_NAMESPACE_H__ + +#include <linux/err.h> + +struct ipc_ids ; +struct ipc_namespace { +struct kref kref; +struct ipc_ids *ids[3 ]; + +int sem_ctls[4 ]; +int used_sems; + +int msg_ctlmax; +int msg_ctlmnb; +int msg_ctlmni; + +size_t shm_ctlmax; +size_t shm_ctlall; +int shm_ctlmni; +int shm_tot; +};include/linux/ipc_namespace.h line 32
Quoted 10 lines
include/linux/ipc_namespace.h new file +10
-0+ +extern struct ipc_namespace init_ipc_ns; + +#ifdef CONFIG_SYSVIPC +#define INIT_IPC_NS (ns) .ns = &init_ipc_ns, +#else +#define INIT_IPC_NS (ns) +#endif + +#ifdef CONFIG_NS_IPC ok so you're readding that flag. please check
ipc/ipc_sysctl.cthere might be some surprises.check the compile with
CONFIG_SYSCTL=nQuoted 202 lines
include/linux/ipc_namespace.h new file +35
-0+extern void free_ipc_ns (struct kref *kref); +extern struct ipc_namespace *copy_ipcs (unsigned long flags, +struct ipc_namespace *ns); + +static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) +{ +if (ns) +kref_get (&ns->kref); +return ns; +} + +static inline void put_ipc_ns (struct ipc_namespace *ns) +{ +kref_put (&ns->kref, free_ipc_ns); +} +#else +static inline struct ipc_namespace *copy_ipcs (unsigned long flags, +struct ipc_namespace *ns) +{ +if (flags &CLONE_NEWIPC ) +return ERR_PTR (-EINVAL ); + +return ns; +} + +static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) +{ +return ns; +} + +static inline void put_ipc_ns (struct ipc_namespace *ns) +{ +} +#endif +#endif include/linux/nsproxy.h +0
-0include/linux/pid.h +0
-1@@ -122,7 +122,6 @@ extern struct pid *find_ge_pid(int nr, sextern struct pid *alloc_pid (struct pid_namespace *ns);extern void FASTCALL (free_pid (struct pid *pid)); -extern void zap_pid_ns_processes (struct pid_namespace *pid_ns);/* * the helpers to get the pid's id seen from different namespaces include/linux/pid_namespace.h +27
-0@@ -6,6 +6,7 @@#include <linux/threads.h> #include <linux/nsproxy.h> #include <linux/kref.h> +#include <linux/err.h> struct pidmap {atomic_t nr_free;@@ -29,6 +30,7 @@ struct pid_namespace {extern struct pid_namespace init_pid_ns; +#ifdef CONFIG_NS_PID static inline struct pid_namespace *get_pid_ns (struct pid_namespace *ns) {if (ns != &init_pid_ns)@@ -38,12 +40,37 @@ static inline struct pid_namespace *get_extern struct pid_namespace *copy_pid_ns (unsigned long flags,struct pid_namespace *ns);extern void free_pid_ns (struct kref *kref); +extern void zap_pid_ns_processes (struct pid_namespace *pid_ns);static inline void put_pid_ns (struct pid_namespace *ns) {if (ns != &init_pid_ns)kref_put (&ns->kref, free_pid_ns); } +#else +static inline struct pid_namespace *get_pid_ns (struct pid_namespace *ns) +{ +return ns; +} + +static inline void put_pid_ns (struct pid_namespace *ns) +{ +} + +static inline struct pid_namespace *copy_pid_ns (unsigned long flags, +struct pid_namespace *ns) +{ +if (flags &CLONE_NEWPID ) +return ERR_PTR (-EINVAL ); + +return ns; +} + +static inline void zap_pid_ns_processes (struct pid_namespace *ns) +{ +BUG (); +} +#endif static inline struct pid_namespace *task_active_pid_ns (struct task_struct *tsk) {include/linux/sched.h +0
-0include/linux/sem.h +0
-0include/linux/user_namespace.h +1
-1@@ -17,7 +17,7 @@ struct user_namespace {extern struct user_namespace init_user_ns; -#ifdef CONFIG_USER_NS +#ifdef CONFIG_NS_UID static inline struct user_namespace *get_user_ns (struct user_namespace *ns) {include/linux/utsname.h +21
-0@@ -35,6 +35,7 @@ struct new_utsname {#include <linux/sched.h> #include <linux/kref.h> #include <linux/nsproxy.h> +#include <linux/err.h> #include <asm/atomic.h> struct uts_namespace {@@ -43,6 +44,7 @@ struct uts_namespace { };extern struct uts_namespace init_uts_ns; +#ifdef CONFIG_NS_UTS static inline void get_uts_ns (struct uts_namespace *ns) {kref_get (&ns->kref);@@ -56,6 +58,25 @@ static inline void put_uts_ns(struct uts {kref_put (&ns->kref, free_uts_ns); } +#else +static inline void get_uts_ns (struct uts_namespace *ns) +{ +} + +static inline void put_uts_ns (struct uts_namespace *ns) +{ +} + +static inline struct uts_namespace *copy_utsname (unsigned long flags, +struct uts_namespace *ns) +{ +if (flags &CLONE_NEWUTS ) +return ERR_PTR (-EINVAL ); + +return ns; +} +#endif +static inline struct new_utsname *utsname (void ) {return ¤t->nsproxy->uts_ns->name;init/Kconfig +11
-9@@ -206,15 +206,6 @@ config TASK_IO_ACCOUNTING Say N if unsure. -config USER_NS - bool "User Namespaces (EXPERIMENTAL)" - default n - depends on EXPERIMENTAL - help - Support user namespaces. This allows containers, i.e. - vservers, to use user namespaces to provide different - user info for different servers. If unsure, say N. - config AUDIT bool "Auditing support" depends on NET@@ -369,6 +360,39 @@ config RELAY If unsure, say N. +config NAMESPACES + bool "The namespaces support" + help + Provides the way to make tasks work with different objects using + the same id + +config NS_UTS + bool "Uname namespace" + depends on NAMESPACES + help + The utsname namespaceinit/Kconfig config RELAY · line 383
Quoted 10 lines
init/Kconfig +10
-0+ +config NS_IPC + bool "IPC namespace" + depends on NAMESPACES && SYSVIPC + help + The SYSVIPC ids namespaces + +config NS_PIDS + bool "PID namespace" + depends on NAMESPACESI'd put experimental on this one also
Quoted 21 lines
init/Kconfig +12
-0+ help + Tasks see only the pids living in the same namespace and in the + child namespaces + +config NS_UID + bool "UID namespace" + depends on NAMESPACES && EXPERIMENTAL + help + Support user namespaces. This allows containers, i.e. + vservers, to use user namespaces to provide different + user info for different servers. If unsure, say N. + config BLK_DEV_INITRD bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" depends on BROKEN || !FRVinit/main.c +0
-0ipc/Makefile +0
-0ipc/Makefile obj-$(CONFIG_SYSVIPC) += util.o msgutil. · line 10
Quoted 4 lines
ipc/Makefile +1
-0@@ -7,4 +7,5 @@ obj-$(CONFIG_SYSVIPC) += util.o msgutil. obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o obj_mq-$(CONFIG_COMPAT) += compat_mq.o obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y) +obj-$(CONFIG_NS_IPC) += namespace.o
ipc_namespace.cis a better name.Quoted 33 lines
ipc/ipc_sysctl.c +1
-0@@ -14,6 +14,7 @@#include <linux/nsproxy.h> #include <linux/sysctl.h> #include <linux/uaccess.h> +#include <linux/ipc_namespace.h> static void *get_ipc (ctl_table *table) {ipc/msg.c +2
-0@@ -36,6 +36,7 @@#include <linux/seq_file.h> #include <linux/mutex.h> #include <linux/nsproxy.h> +#include <linux/ipc_namespace.h> #include <asm/current.h> #include <asm/uaccess.h> @@ -92,6 +93,7 @@ static void __msg_init_ns(struct ipc_namipc_init_ids (ids); } +#ifdef CONFIG_NS_IPC int msg_init_ns (struct ipc_namespace *ns) {struct ipc_ids *ids;ipc/msg.c void msg_exit_ns(struct ipc_namespace *n · line 132
Quoted 4 lines
ipc/msg.c +1
-0@@ -127,6 +129,7 @@ void msg_exit_ns(struct ipc_namespace *nkfree (ns->ids[IPC_MSG_IDS ]); ns->ids[IPC_MSG_IDS] = NULL; } +#endif can't this routine be in
ipc_namespace.cto remove the #ifdefCONFIG_NS_IPC? the same apply to the other init routine.ipc/namespace.c
Quoted 3 lines
ipc/msg.c +0
-0void __init msg_init (void ) {ipc/namespace.c +0
-0i'd call it
ipc_namespace.cQuoted 379 lines
new file mode 100644
index 0000000..cef1139ipc/namespace.c new file +73
-0@@ -0,0 +1,73 @@ +/* +* linux/ipc/namespace.c +* Copyright (C) 2006 Pavel Emelyanov <[email protected]> OpenVZ, SWsoft Inc. +*/ + +#include <linux/ipc.h> +#include <linux/msg.h> +#include <linux/ipc_namespace.h> +#include <linux/rcupdate.h> +#include <linux/nsproxy.h> +#include <linux/slab.h> + +#include "util.h" + +static struct ipc_namespace *clone_ipc_ns (struct ipc_namespace *old_ns) +{ +int err; +struct ipc_namespace *ns; + + err = -ENOMEM ; + ns =kmalloc (sizeof (struct ipc_namespace ),GFP_KERNEL ); +if (ns ==NULL ) + goto err_mem; + + err =sem_init_ns (ns); +if (err) + goto err_sem; + err =msg_init_ns (ns); +if (err) + goto err_msg; + err =shm_init_ns (ns); +if (err) + goto err_shm; + +kref_init (&ns->kref); +return ns; + +err_shm: +msg_exit_ns (ns); +err_msg: +sem_exit_ns (ns); +err_sem: +kfree (ns); +err_mem: +return ERR_PTR (err); +} + +struct ipc_namespace *copy_ipcs (unsigned long flags,struct ipc_namespace *ns) +{ +struct ipc_namespace *new_ns; + +BUG_ON (!ns); +get_ipc_ns (ns); + +if (!(flags &CLONE_NEWIPC )) +return ns; + + new_ns =clone_ipc_ns (ns); + +put_ipc_ns (ns); +return new_ns; +} + +void free_ipc_ns (struct kref *kref) +{ +struct ipc_namespace *ns; + + ns = container_of(kref, struct ipc_namespace, kref); +sem_exit_ns (ns); +msg_exit_ns (ns); +shm_exit_ns (ns); +kfree (ns); +}ipc/sem.c +3
-0@@ -82,6 +82,7 @@#include <linux/seq_file.h> #include <linux/mutex.h> #include <linux/nsproxy.h> +#include <linux/ipc_namespace.h> #include <asm/uaccess.h> #include "util.h" @@ -130,6 +131,7 @@ static void __sem_init_ns(struct ipc_namipc_init_ids (ids); } +#ifdef CONFIG_NS_IPC int sem_init_ns (struct ipc_namespace *ns) {struct ipc_ids *ids;@@ -165,6 +167,7 @@ void sem_exit_ns(struct ipc_namespace *nkfree (ns->ids[IPC_SEM_IDS ]); ns->ids[IPC_SEM_IDS] = NULL; } +#endif void __init sem_init (void ) {ipc/shm.c +3
-0@@ -38,6 +38,7 @@#include <linux/mutex.h> #include <linux/nsproxy.h> #include <linux/mount.h> +#include <linux/ipc_namespace.h> #include <asm/uaccess.h> @@ -97,6 +98,7 @@ static void do_shm_rmid(struct ipc_namesshm_destroy (ns, shp); } +#ifdef CONFIG_NS_IPC int shm_init_ns (struct ipc_namespace *ns) {struct ipc_ids *ids;@@ -132,6 +134,7 @@ void shm_exit_ns(struct ipc_namespace *nkfree (ns->ids[IPC_SHM_IDS ]); ns->ids[IPC_SHM_IDS] = NULL; } +#endif void __init shm_init (void ) {ipc/util.c +1
-60@@ -32,6 +32,7 @@#include <linux/proc_fs.h> #include <linux/audit.h> #include <linux/nsproxy.h> +#include <linux/ipc_namespace.h> #include <asm/unistd.h> @@ -50,66 +51,6 @@ struct ipc_namespace init_ipc_ns = { }, }; -static struct ipc_namespace *clone_ipc_ns (struct ipc_namespace *old_ns) -{ -int err; -struct ipc_namespace *ns; - - err = -ENOMEM ; - ns =kmalloc (sizeof (struct ipc_namespace ),GFP_KERNEL ); -if (ns ==NULL ) - goto err_mem; - - err =sem_init_ns (ns); -if (err) - goto err_sem; - err =msg_init_ns (ns); -if (err) - goto err_msg; - err =shm_init_ns (ns); -if (err) - goto err_shm; - -kref_init (&ns->kref); -return ns; - -err_shm: -msg_exit_ns (ns); -err_msg: -sem_exit_ns (ns); -err_sem: -kfree (ns); -err_mem: -return ERR_PTR (err); -} - -struct ipc_namespace *copy_ipcs (unsigned long flags,struct ipc_namespace *ns) -{ -struct ipc_namespace *new_ns; - -BUG_ON (!ns); -get_ipc_ns (ns); - -if (!(flags &CLONE_NEWIPC )) -return ns; - - new_ns =clone_ipc_ns (ns); - -put_ipc_ns (ns); -return new_ns; -} - -void free_ipc_ns (struct kref *kref) -{ -struct ipc_namespace *ns; - - ns = container_of(kref, struct ipc_namespace, kref); -sem_exit_ns (ns); -msg_exit_ns (ns); -shm_exit_ns (ns); -kfree (ns); -} -/** * ipc_init - initialise IPC subsystem * ipc/util.h +2
-0@@ -20,6 +20,8 @@ void sem_init (void);void msg_init (void );void shm_init (void ); +struct ipc_namespace ; +int sem_init_ns (struct ipc_namespace *ns);int msg_init_ns (struct ipc_namespace *ns);int shm_init_ns (struct ipc_namespace *ns);kernel/Makefile +4
-3@@ -4,12 +4,11 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ exit.o itimer.o time.o softirq.o resource.o \ - sysctl.o capability.o ptrace.o timer.o user.o user_namespace.o \ + sysctl.o capability.o ptrace.o timer.o user.o \ signal.o sys.o kmod.o workqueue.o pid.o \ rcupdate.o extable.o params.o posix-timers.o \ kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ - hrtimer.o rwsem.o latency.o nsproxy.o srcu.o \ - utsname.o notifier.o sysctl.o + hrtimer.o rwsem.o latency.o nsproxy.o srcu.o notifier.o sysctl.o obj-$(CONFIG_SYSCTL) += sysctl_check.o obj-$(CONFIG_STACKTRACE) += stacktrace.o@@ -50,6 +49,8 @@ obj-$(CONFIG_AUDITSYSCALL) += auditsc.o obj-$(CONFIG_AUDIT_TREE) += audit_tree.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KGDB) += kgdb.o +obj-$(CONFIG_NS_UTS) += utsname.o +obj-$(CONFIG_NS_UID) += user_namespace.o obj-$(CONFIG_SYSFS) += ksysfs.o obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o obj-$(CONFIG_GENERIC_HARDIRQS) += irq/kernel/nsproxy.c +1
-0@@ -20,6 +20,7 @@#include <linux/mnt_namespace.h> #include <linux/utsname.h> #include <linux/pid_namespace.h> +#include <linux/ipc_namespace.h> static struct kmem_cache *nsproxy_cachep;kernel/pid.c +14
-1@@ -432,6 +432,7 @@ struct pid *find_ge_pid(int nr, struct p }EXPORT_SYMBOL_GPL (find_get_pid); +#ifdef CONFIG_NS_PID struct pid_cache { int nr_ids; char name[16];@@ -482,6 +483,11 @@ err_alloc:return NULL ; } +static __init struct kmem_cache *create_init_pid_cachep (void ) +{ +return create_pid_cachep (1 ); +} +static struct pid_namespace *create_pid_namespace (int level) {struct pid_namespace *ns;@@ -603,6 +609,13 @@ void zap_pid_ns_processes(struct pid_nam pid_ns->child_reaper =NULL ; return; } +#else +static __init struct kmem_cache *create_init_pid_cachep (void ) +{ +return kmem_cache_create ("pid" ,sizeof (struct pid ),0 , +SLAB_HWCACHE_ALIGN ,NULL ); +} +#endif /* * The pid hash table is scaled according to the amount of memory in the @@ -636,7 +649,7 @@ void __init pidmap_init(void)set_bit (0 , init_pid_ns.pidmap[0 ].page);atomic_dec (&init_pid_ns.pidmap[0 ].nr_free); - init_pid_ns.pid_cachep =create_pid_cachep (1 ); + init_pid_ns.pid_cachep =create_init_pid_cachep ();if (init_pid_ns.pid_cachep ==NULL )panic ("Can't create pid_1 cachep\n" );kernel/user.c +11
-0@@ -17,6 +17,15 @@#include <linux/module.h> #include <linux/user_namespace.h> +struct user_namespace init_user_ns = { + .kref = { + .refcount =ATOMIC_INIT (2 ), + }, + .root_user = &root_user, +}; + +EXPORT_SYMBOL_GPL (init_user_ns); +/* * UID task count cache, to get fast user lookup in "alloc_uid" * when changing user ID's (ie setuid() and friends). @@ -199,6 +208,7 @@ void switch_uid(struct user_struct *new_suid_keys (current); } +#ifdef CONFIG_NS_UID void release_uids (struct user_namespace *ns) {int i;@@ -223,6 +233,7 @@ void release_uids(struct user_namespace free_uid(ns->root_user); } +#endif static int __init uid_cache_init (void ) {kernel/user_namespace.c +0
-13@@ -10,17 +10,6 @@#include <linux/nsproxy.h> #include <linux/user_namespace.h> -struct user_namespace init_user_ns = { - .kref = { - .refcount =ATOMIC_INIT (2 ), - }, - .root_user = &root_user, -}; - -EXPORT_SYMBOL_GPL (init_user_ns); - -#ifdef CONFIG_USER_NS -/* * Clone a new ns copying an original user ns, setting refcount to 1 * @old_ns: namespace to clone @@ -84,5 +73,3 @@ void free_user_ns(struct kref *kref)release_uids (ns);kfree (ns); } - -#endif /* CONFIG_USER_NS */ kernel/utsname.c +0
-0
Quoted 5 lines · Pavel Emelyanov
Hi, guys!
I've noticed that compiling out all the core related to cloning and cleaning the new namespace saves us more than a Kbyte (!) from the vmlinux.
Sorry guys, this patch is a bit broken :P
CONFIG_NS_PID is used in kernel/pid.c while the real option is CONFIG_NS_PIDS :(
I've remade the patch and it actually saves 2KB :) I will send it to Andrew soon.
add/remove: 27/0 grow/shrink: 11/7 up/down: 2477/-340 (2137)
function old new delta copy_pid_ns - 537 +537 copy_user_ns - 181 +181 copy_ipcs - 149 +149 zap_pid_ns_processes - 130 +130 copy_utsname - 120 +120 shm_exit_ns - 106 +106 sem_exit_ns - 106 +106 msg_exit_ns - 106 +106 freeary - 100 +100 release_uids - 95 +95 freeque - 92 +92 free_nsproxy 48 123 +75 create_new_namespaces 300 358 +58 free_pid_ns - 56 +56 pid_namespaces_init - 48 +48 __sem_init_ns - 45 +45 shm_init_ns - 42 +42 sem_init_ns - 42 +42 msg_init_ns - 42 +42 __shm_init_ns - 38 +38 __msg_init_ns - 31 +31 sysvipc_proc_release 5 35 +30 proc_kill_sb 5 35 +30 free_ipc_ns - 30 +30 do_shm_rmid - 29 +29 proc_set_super 13 38 +25 shm_release 18 39 +21 put_pid 75 95 +20 alloc_pid 687 706 +19 pid_caches_mutex - 16 +16 free_user_ns - 16 +16 sysvipc_proc_open 100 111 +11 do_shmat 778 787 +9 pid_caches_lh - 8 +8 free_uts_ns - 5 +5 pid_ns_cachep - 4 +4 __initcall_pid_namespaces_init6 - 4 +4 do_exit 1855 1856 +1 show_stat 1665 1661 -4 sys_shmctl 1934 1907 -27 msg_init 82 47 -35 shm_init 92 47 -45 sem_init 99 44 -55 sys_msgctl 1394 1311 -83 sys_semctl 2123 2032 -91
Quoted 802 lines
add/remove: 19/0 grow/shrink: 6/6 up/down: 1532/-336 (1196)
function old new delta copy_user_ns - 181 +181 copy_ipcs - 149 +149 copy_utsname - 120 +120 shm_exit_ns - 106 +106 sem_exit_ns - 106 +106 msg_exit_ns - 106 +106 freeary - 100 +100 release_uids - 95 +95 freeque - 92 +92 free_nsproxy 48 99 +51 __sem_init_ns - 45 +45 shm_init_ns - 42 +42 sem_init_ns - 42 +42 msg_init_ns - 42 +42 __shm_init_ns - 38 +38 create_new_namespaces 300 335 +35 __msg_init_ns - 31 +31 sysvipc_proc_release 5 35 +30 free_ipc_ns - 30 +30 do_shm_rmid - 29 +29 shm_release 18 39 +21 free_user_ns - 16 +16 sysvipc_proc_open 100 111 +11 do_shmat 778 787 +9 free_uts_ns - 5 +5 sys_shmctl 1934 1907 -27 msg_init 82 47 -35 shm_init 92 47 -45 sem_init 99 44 -55 sys_msgctl 1394 1311 -83 sys_semctl 2123 2032 -91Since there already were some questions like "do I need it on my cellphone?" in reply to pid namespaces patches and so on, why don't we make ALL the namespaces cloning code under the config option to make those people happy?
Here's the proposed patch.
Signed-off-by Pavel Emelyanov <[email protected]>---
include/linux/ipc.h +0
-50@@ -100,56 +100,6 @@ struct kern_ipc_permvoid *security; }; -struct ipc_ids ; -struct ipc_namespace { -struct kref kref; -struct ipc_ids *ids[3 ]; - -int sem_ctls[4 ]; -int used_sems; - -int msg_ctlmax; -int msg_ctlmnb; -int msg_ctlmni; - -size_t shm_ctlmax; -size_t shm_ctlall; -int shm_ctlmni; -int shm_tot; -}; - -extern struct ipc_namespace init_ipc_ns; - -#ifdef CONFIG_SYSVIPC -#define INIT_IPC_NS (ns) .ns = &init_ipc_ns, -extern void free_ipc_ns (struct kref *kref); -extern struct ipc_namespace *copy_ipcs (unsigned long flags, -struct ipc_namespace *ns); -#else -#define INIT_IPC_NS (ns) -static inline struct ipc_namespace *copy_ipcs (unsigned long flags, -struct ipc_namespace *ns) -{ -return ns; -} -#endif - -static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) -{ -#ifdef CONFIG_SYSVIPC -if (ns) -kref_get (&ns->kref); -#endif -return ns; -} - -static inline void put_ipc_ns (struct ipc_namespace *ns) -{ -#ifdef CONFIG_SYSVIPC -kref_put (&ns->kref, free_ipc_ns); -#endif -} -#endif /* __KERNEL__ */ #endif /* _LINUX_IPC_H */ include/linux/ipc_namespace.h new file +67
-0@@ -0,0 +1,67 @@ +#ifndef __IPC_NAMESPACE_H__ +#define __IPC_NAMESPACE_H__ + +#include <linux/err.h> + +struct ipc_ids ; +struct ipc_namespace { +struct kref kref; +struct ipc_ids *ids[3 ]; + +int sem_ctls[4 ]; +int used_sems; + +int msg_ctlmax; +int msg_ctlmnb; +int msg_ctlmni; + +size_t shm_ctlmax; +size_t shm_ctlall; +int shm_ctlmni; +int shm_tot; +}; + +extern struct ipc_namespace init_ipc_ns; + +#ifdef CONFIG_SYSVIPC +#define INIT_IPC_NS (ns) .ns = &init_ipc_ns, +#else +#define INIT_IPC_NS (ns) +#endif + +#ifdef CONFIG_NS_IPC +extern void free_ipc_ns (struct kref *kref); +extern struct ipc_namespace *copy_ipcs (unsigned long flags, +struct ipc_namespace *ns); + +static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) +{ +if (ns) +kref_get (&ns->kref); +return ns; +} + +static inline void put_ipc_ns (struct ipc_namespace *ns) +{ +kref_put (&ns->kref, free_ipc_ns); +} +#else +static inline struct ipc_namespace *copy_ipcs (unsigned long flags, +struct ipc_namespace *ns) +{ +if (flags &CLONE_NEWIPC ) +return ERR_PTR (-EINVAL ); + +return ns; +} + +static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) +{ +return ns; +} + +static inline void put_ipc_ns (struct ipc_namespace *ns) +{ +} +#endif +#endif include/linux/nsproxy.h +0
-0include/linux/pid.h +0
-1@@ -122,7 +122,6 @@ extern struct pid *find_ge_pid(int nr, sextern struct pid *alloc_pid (struct pid_namespace *ns);extern void FASTCALL (free_pid (struct pid *pid)); -extern void zap_pid_ns_processes (struct pid_namespace *pid_ns);/* * the helpers to get the pid's id seen from different namespaces include/linux/pid_namespace.h +27
-0@@ -6,6 +6,7 @@#include <linux/threads.h> #include <linux/nsproxy.h> #include <linux/kref.h> +#include <linux/err.h> struct pidmap {atomic_t nr_free;@@ -29,6 +30,7 @@ struct pid_namespace {extern struct pid_namespace init_pid_ns; +#ifdef CONFIG_NS_PID static inline struct pid_namespace *get_pid_ns (struct pid_namespace *ns) {if (ns != &init_pid_ns)@@ -38,12 +40,37 @@ static inline struct pid_namespace *get_extern struct pid_namespace *copy_pid_ns (unsigned long flags,struct pid_namespace *ns);extern void free_pid_ns (struct kref *kref); +extern void zap_pid_ns_processes (struct pid_namespace *pid_ns);static inline void put_pid_ns (struct pid_namespace *ns) {if (ns != &init_pid_ns)kref_put (&ns->kref, free_pid_ns); } +#else +static inline struct pid_namespace *get_pid_ns (struct pid_namespace *ns) +{ +return ns; +} + +static inline void put_pid_ns (struct pid_namespace *ns) +{ +} + +static inline struct pid_namespace *copy_pid_ns (unsigned long flags, +struct pid_namespace *ns) +{ +if (flags &CLONE_NEWPID ) +return ERR_PTR (-EINVAL ); + +return ns; +} + +static inline void zap_pid_ns_processes (struct pid_namespace *ns) +{ +BUG (); +} +#endif static inline struct pid_namespace *task_active_pid_ns (struct task_struct *tsk) {include/linux/sched.h +0
-0include/linux/sem.h +0
-0include/linux/user_namespace.h +1
-1@@ -17,7 +17,7 @@ struct user_namespace {extern struct user_namespace init_user_ns; -#ifdef CONFIG_USER_NS +#ifdef CONFIG_NS_UID static inline struct user_namespace *get_user_ns (struct user_namespace *ns) {include/linux/utsname.h +21
-0@@ -35,6 +35,7 @@ struct new_utsname {#include <linux/sched.h> #include <linux/kref.h> #include <linux/nsproxy.h> +#include <linux/err.h> #include <asm/atomic.h> struct uts_namespace {@@ -43,6 +44,7 @@ struct uts_namespace { };extern struct uts_namespace init_uts_ns; +#ifdef CONFIG_NS_UTS static inline void get_uts_ns (struct uts_namespace *ns) {kref_get (&ns->kref);@@ -56,6 +58,25 @@ static inline void put_uts_ns(struct uts {kref_put (&ns->kref, free_uts_ns); } +#else +static inline void get_uts_ns (struct uts_namespace *ns) +{ +} + +static inline void put_uts_ns (struct uts_namespace *ns) +{ +} + +static inline struct uts_namespace *copy_utsname (unsigned long flags, +struct uts_namespace *ns) +{ +if (flags &CLONE_NEWUTS ) +return ERR_PTR (-EINVAL ); + +return ns; +} +#endif +static inline struct new_utsname *utsname (void ) {return ¤t->nsproxy->uts_ns->name;init/Kconfig +33
-9@@ -206,15 +206,6 @@ config TASK_IO_ACCOUNTING Say N if unsure. -config USER_NS - bool "User Namespaces (EXPERIMENTAL)" - default n - depends on EXPERIMENTAL - help - Support user namespaces. This allows containers, i.e. - vservers, to use user namespaces to provide different - user info for different servers. If unsure, say N. - config AUDIT bool "Auditing support" depends on NET@@ -369,6 +360,39 @@ config RELAY If unsure, say N. +config NAMESPACES + bool "The namespaces support" + help + Provides the way to make tasks work with different objects using + the same id + +config NS_UTS + bool "Uname namespace" + depends on NAMESPACES + help + The utsname namespace + +config NS_IPC + bool "IPC namespace" + depends on NAMESPACES && SYSVIPC + help + The SYSVIPC ids namespaces + +config NS_PIDS + bool "PID namespace" + depends on NAMESPACES + help + Tasks see only the pids living in the same namespace and in the + child namespaces + +config NS_UID + bool "UID namespace" + depends on NAMESPACES && EXPERIMENTAL + help + Support user namespaces. This allows containers, i.e. + vservers, to use user namespaces to provide different + user info for different servers. If unsure, say N. + config BLK_DEV_INITRD bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" depends on BROKEN || !FRVinit/main.c +0
-0ipc/Makefile +1
-0@@ -7,4 +7,5 @@ obj-$(CONFIG_SYSVIPC) += util.o msgutil. obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o obj_mq-$(CONFIG_COMPAT) += compat_mq.o obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y) +obj-$(CONFIG_NS_IPC) += namespace.oipc/ipc_sysctl.c +1
-0@@ -14,6 +14,7 @@#include <linux/nsproxy.h> #include <linux/sysctl.h> #include <linux/uaccess.h> +#include <linux/ipc_namespace.h> static void *get_ipc (ctl_table *table) {ipc/msg.c +3
-0@@ -36,6 +36,7 @@#include <linux/seq_file.h> #include <linux/mutex.h> #include <linux/nsproxy.h> +#include <linux/ipc_namespace.h> #include <asm/current.h> #include <asm/uaccess.h> @@ -92,6 +93,7 @@ static void __msg_init_ns(struct ipc_namipc_init_ids (ids); } +#ifdef CONFIG_NS_IPC int msg_init_ns (struct ipc_namespace *ns) {struct ipc_ids *ids;@@ -127,6 +129,7 @@ void msg_exit_ns(struct ipc_namespace *nkfree (ns->ids[IPC_MSG_IDS ]); ns->ids[IPC_MSG_IDS] = NULL; } +#endif void __init msg_init (void ) {ipc/namespace.c new file +73
-0@@ -0,0 +1,73 @@ +/* +* linux/ipc/namespace.c +* Copyright (C) 2006 Pavel Emelyanov <[email protected]> OpenVZ, SWsoft Inc. +*/ + +#include <linux/ipc.h> +#include <linux/msg.h> +#include <linux/ipc_namespace.h> +#include <linux/rcupdate.h> +#include <linux/nsproxy.h> +#include <linux/slab.h> + +#include "util.h" + +static struct ipc_namespace *clone_ipc_ns (struct ipc_namespace *old_ns) +{ +int err; +struct ipc_namespace *ns; + + err = -ENOMEM ; + ns =kmalloc (sizeof (struct ipc_namespace ),GFP_KERNEL ); +if (ns ==NULL ) + goto err_mem; + + err =sem_init_ns (ns); +if (err) + goto err_sem; + err =msg_init_ns (ns); +if (err) + goto err_msg; + err =shm_init_ns (ns); +if (err) + goto err_shm; + +kref_init (&ns->kref); +return ns; + +err_shm: +msg_exit_ns (ns); +err_msg: +sem_exit_ns (ns); +err_sem: +kfree (ns); +err_mem: +return ERR_PTR (err); +} + +struct ipc_namespace *copy_ipcs (unsigned long flags,struct ipc_namespace *ns) +{ +struct ipc_namespace *new_ns; + +BUG_ON (!ns); +get_ipc_ns (ns); + +if (!(flags &CLONE_NEWIPC )) +return ns; + + new_ns =clone_ipc_ns (ns); + +put_ipc_ns (ns); +return new_ns; +} + +void free_ipc_ns (struct kref *kref) +{ +struct ipc_namespace *ns; + + ns = container_of(kref, struct ipc_namespace, kref); +sem_exit_ns (ns); +msg_exit_ns (ns); +shm_exit_ns (ns); +kfree (ns); +}ipc/sem.c +3
-0@@ -82,6 +82,7 @@#include <linux/seq_file.h> #include <linux/mutex.h> #include <linux/nsproxy.h> +#include <linux/ipc_namespace.h> #include <asm/uaccess.h> #include "util.h" @@ -130,6 +131,7 @@ static void __sem_init_ns(struct ipc_namipc_init_ids (ids); } +#ifdef CONFIG_NS_IPC int sem_init_ns (struct ipc_namespace *ns) {struct ipc_ids *ids;@@ -165,6 +167,7 @@ void sem_exit_ns(struct ipc_namespace *nkfree (ns->ids[IPC_SEM_IDS ]); ns->ids[IPC_SEM_IDS] = NULL; } +#endif void __init sem_init (void ) {ipc/shm.c +3
-0@@ -38,6 +38,7 @@#include <linux/mutex.h> #include <linux/nsproxy.h> #include <linux/mount.h> +#include <linux/ipc_namespace.h> #include <asm/uaccess.h> @@ -97,6 +98,7 @@ static void do_shm_rmid(struct ipc_namesshm_destroy (ns, shp); } +#ifdef CONFIG_NS_IPC int shm_init_ns (struct ipc_namespace *ns) {struct ipc_ids *ids;@@ -132,6 +134,7 @@ void shm_exit_ns(struct ipc_namespace *nkfree (ns->ids[IPC_SHM_IDS ]); ns->ids[IPC_SHM_IDS] = NULL; } +#endif void __init shm_init (void ) {ipc/util.c +1
-60@@ -32,6 +32,7 @@#include <linux/proc_fs.h> #include <linux/audit.h> #include <linux/nsproxy.h> +#include <linux/ipc_namespace.h> #include <asm/unistd.h> @@ -50,66 +51,6 @@ struct ipc_namespace init_ipc_ns = { }, }; -static struct ipc_namespace *clone_ipc_ns (struct ipc_namespace *old_ns) -{ -int err; -struct ipc_namespace *ns; - - err = -ENOMEM ; - ns =kmalloc (sizeof (struct ipc_namespace ),GFP_KERNEL ); -if (ns ==NULL ) - goto err_mem; - - err =sem_init_ns (ns); -if (err) - goto err_sem; - err =msg_init_ns (ns); -if (err) - goto err_msg; - err =shm_init_ns (ns); -if (err) - goto err_shm; - -kref_init (&ns->kref); -return ns; - -err_shm: -msg_exit_ns (ns); -err_msg: -sem_exit_ns (ns); -err_sem: -kfree (ns); -err_mem: -return ERR_PTR (err); -} - -struct ipc_namespace *copy_ipcs (unsigned long flags,struct ipc_namespace *ns) -{ -struct ipc_namespace *new_ns; - -BUG_ON (!ns); -get_ipc_ns (ns); - -if (!(flags &CLONE_NEWIPC )) -return ns; - - new_ns =clone_ipc_ns (ns); - -put_ipc_ns (ns); -return new_ns; -} - -void free_ipc_ns (struct kref *kref) -{ -struct ipc_namespace *ns; - - ns = container_of(kref, struct ipc_namespace, kref); -sem_exit_ns (ns); -msg_exit_ns (ns); -shm_exit_ns (ns); -kfree (ns); -} -/** * ipc_init - initialise IPC subsystem * ipc/util.h +2
-0@@ -20,6 +20,8 @@ void sem_init (void);void msg_init (void );void shm_init (void ); +struct ipc_namespace ; +int sem_init_ns (struct ipc_namespace *ns);int msg_init_ns (struct ipc_namespace *ns);int shm_init_ns (struct ipc_namespace *ns);kernel/Makefile +4
-3@@ -4,12 +4,11 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ exit.o itimer.o time.o softirq.o resource.o \ - sysctl.o capability.o ptrace.o timer.o user.o user_namespace.o \ + sysctl.o capability.o ptrace.o timer.o user.o \ signal.o sys.o kmod.o workqueue.o pid.o \ rcupdate.o extable.o params.o posix-timers.o \ kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ - hrtimer.o rwsem.o latency.o nsproxy.o srcu.o \ - utsname.o notifier.o sysctl.o + hrtimer.o rwsem.o latency.o nsproxy.o srcu.o notifier.o sysctl.o obj-$(CONFIG_SYSCTL) += sysctl_check.o obj-$(CONFIG_STACKTRACE) += stacktrace.o@@ -50,6 +49,8 @@ obj-$(CONFIG_AUDITSYSCALL) += auditsc.o obj-$(CONFIG_AUDIT_TREE) += audit_tree.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KGDB) += kgdb.o +obj-$(CONFIG_NS_UTS) += utsname.o +obj-$(CONFIG_NS_UID) += user_namespace.o obj-$(CONFIG_SYSFS) += ksysfs.o obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o obj-$(CONFIG_GENERIC_HARDIRQS) += irq/kernel/nsproxy.c +1
-0@@ -20,6 +20,7 @@#include <linux/mnt_namespace.h> #include <linux/utsname.h> #include <linux/pid_namespace.h> +#include <linux/ipc_namespace.h> static struct kmem_cache *nsproxy_cachep;kernel/pid.c +14
-1@@ -432,6 +432,7 @@ struct pid *find_ge_pid(int nr, struct p }EXPORT_SYMBOL_GPL (find_get_pid); +#ifdef CONFIG_NS_PID struct pid_cache { int nr_ids; char name[16];@@ -482,6 +483,11 @@ err_alloc:return NULL ; } +static __init struct kmem_cache *create_init_pid_cachep (void ) +{ +return create_pid_cachep (1 ); +} +static struct pid_namespace *create_pid_namespace (int level) {struct pid_namespace *ns;@@ -603,6 +609,13 @@ void zap_pid_ns_processes(struct pid_nam pid_ns->child_reaper =NULL ; return; } +#else +static __init struct kmem_cache *create_init_pid_cachep (void ) +{ +return kmem_cache_create ("pid" ,sizeof (struct pid ),0 , +SLAB_HWCACHE_ALIGN ,NULL ); +} +#endif /* * The pid hash table is scaled according to the amount of memory in the @@ -636,7 +649,7 @@ void __init pidmap_init(void)set_bit (0 , init_pid_ns.pidmap[0 ].page);atomic_dec (&init_pid_ns.pidmap[0 ].nr_free); - init_pid_ns.pid_cachep =create_pid_cachep (1 ); + init_pid_ns.pid_cachep =create_init_pid_cachep ();if (init_pid_ns.pid_cachep ==NULL )panic ("Can't create pid_1 cachep\n" );kernel/user.c +11
-0@@ -17,6 +17,15 @@#include <linux/module.h> #include <linux/user_namespace.h> +struct user_namespace init_user_ns = { + .kref = { + .refcount =ATOMIC_INIT (2 ), + }, + .root_user = &root_user, +}; + +EXPORT_SYMBOL_GPL (init_user_ns); +/* * UID task count cache, to get fast user lookup in "alloc_uid" * when changing user ID's (ie setuid() and friends). @@ -199,6 +208,7 @@ void switch_uid(struct user_struct *new_suid_keys (current); } +#ifdef CONFIG_NS_UID void release_uids (struct user_namespace *ns) {int i;@@ -223,6 +233,7 @@ void release_uids(struct user_namespace free_uid(ns->root_user); } +#endif static int __init uid_cache_init (void ) {kernel/user_namespace.c +0
-13@@ -10,17 +10,6 @@#include <linux/nsproxy.h> #include <linux/user_namespace.h> -struct user_namespace init_user_ns = { - .kref = { - .refcount =ATOMIC_INIT (2 ), - }, - .root_user = &root_user, -}; - -EXPORT_SYMBOL_GPL (init_user_ns); - -#ifdef CONFIG_USER_NS -/* * Clone a new ns copying an original user ns, setting refcount to 1 * @old_ns: namespace to clone @@ -84,5 +73,3 @@ void free_user_ns(struct kref *kref)release_uids (ns);kfree (ns); } - -#endif /* CONFIG_USER_NS */ kernel/utsname.c +0
-0
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 29 lines · Pavel Emelyanov
Quoted 29 lines
init/Kconfig +28
-0+config NAMESPACES + bool "The namespaces support" + help + Provides the way to make tasks work with different objects using + the same id + +config NS_UTS + bool "Uname namespace" + depends on NAMESPACES + help + The utsname namespace + +config NS_IPC + bool "IPC namespace" + depends on NAMESPACES && SYSVIPC + help + The SYSVIPC ids namespaces + +config NS_PIDS + bool "PID namespace" + depends on NAMESPACES + help + Tasks see only the pids living in the same namespace and in the + child namespaces + +config NS_UID + bool "UID namespace" + depends on NAMESPACES && EXPERIMENTAL
Quoted 8 lines
init/Kconfig config RELAY · line 398
Quoted 8 lines
init/Kconfig +5
-0+ help + Support user namespaces. This allows containers, i.e. + vservers, to use user namespaces to provide different + user info for different servers. If unsure, say N. + config BLK_DEV_INITRD bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" depends on BROKEN || !FRV
The reason we removed these options earlier was a maintenance issue and the fact we could not actually compile out the namespaces.
If we don't cause maintenance complications I think the general idea is fine. But please. This all should show up under CONFIG_EMBEDDED since the only purpose is to save space.
While things are experimental there is an additional purpose of not exposing people to broken or partially working code, so it does make sense to have an option there.
Eric
A message that is not in the archive (sent off-list or not yet received): m1y7etv634.fsf-T1Yj925okcoyDheHMi7gv2pdwda3JcWeAL8bYrjMMd8@public.gmane.org
Quoted 34 lines · Eric W. Biederman
Quoted 32 lines · Pavel Emelyanov
Quoted 32 lines
init/Kconfig +31
-0+config NAMESPACES + bool "The namespaces support" + help + Provides the way to make tasks work with different objects using + the same id + +config NS_UTS + bool "Uname namespace" + depends on NAMESPACES + help + The utsname namespace + +config NS_IPC + bool "IPC namespace" + depends on NAMESPACES && SYSVIPC + help + The SYSVIPC ids namespaces + +config NS_PIDS + bool "PID namespace" + depends on NAMESPACES + help + Tasks see only the pids living in the same namespace and in the + child namespaces + +config NS_UID + bool "UID namespace" + depends on NAMESPACES && EXPERIMENTAL + help + Support user namespaces. This allows containers, i.e. + vservers, to use user namespaces to provide different
Quoted 8 lines
Quoted 5 lines
init/Kconfig config RELAY · line 398
Quoted 5 lines
init/Kconfig +2
-0+ user info for different servers. If unsure, say N. + config BLK_DEV_INITRD bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" depends on BROKEN || !FRVThe reason we removed these options earlier was a maintenance issue and the fact we could not actually compile out the namespaces.
I do not propose to compile out the namespaces, I just propose to compile out the code that does the clone and release of new namespaces. This is absolutely painless.
Quoted 3 lines
If we don't cause maintenance complications I think the general idea is fine. But please. This all should show up under
CONFIG_EMBEDDEDsince the only purpose is to save space.
Hm... Ok, but I also try to save the vmlinux size on my home PC, so I'd be happy if I could just throw these things out.
Anyway - I will move the CONFIG_NAMESPACES to be selectable with the EMBEDDED only.
Quoted 3 lines
While things are experimental there is an additional purpose of not exposing people to broken or partially working code, so it does make sense to have an option there.
Ok, thanks.
So your accolades, can they be transformed into Acked-by-s or just mentioned in the patch like "reviewed and approved by ..."?
Quoted 2 lines
Eric
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 58 lines · Pavel Emelyanov
Quoted 34 lines · Eric W. Biederman
Quoted 32 lines · Pavel Emelyanov
Quoted 32 lines
(quoted diff) +31
-0+config NAMESPACES + bool "The namespaces support" + help + Provides the way to make tasks work with different objects using + the same id + +config NS_UTS + bool "Uname namespace" + depends on NAMESPACES + help + The utsname namespace + +config NS_IPC + bool "IPC namespace" + depends on NAMESPACES && SYSVIPC + help + The SYSVIPC ids namespaces + +config NS_PIDS + bool "PID namespace" + depends on NAMESPACES + help + Tasks see only the pids living in the same namespace and in the + child namespaces + +config NS_UID + bool "UID namespace" + depends on NAMESPACES && EXPERIMENTAL + help + Support user namespaces. This allows containers, i.e. + vservers, to use user namespaces to provide differentQuoted 8 lines
Quoted 5 lines
Review
Quoted 5 lines
(quoted diff) +2
-0+ user info for different servers. If unsure, say N. + config BLK_DEV_INITRD bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" depends on BROKEN || !FRVThe reason we removed these options earlier was a maintenance issue and the fact we could not actually compile out the namespaces.
I do not propose to compile out the namespaces, I just propose to compile out the code that does the clone and release of new namespaces. This is absolutely painless.
Quoted 3 lines
If we don't cause maintenance complications I think the general idea is fine. But please. This all should show up under
CONFIG_EMBEDDEDsince the only purpose is to save space.Hm... Ok, but I also try to save the vmlinux size on my home PC, so I'd be happy if I could just throw these things out.
Anyway - I will move the
CONFIG_NAMESPACESto be selectable with the EMBEDDED only.
Quoted 8 lines
Quoted 3 lines
While things are experimental there is an additional purpose of not exposing people to broken or partially working code, so it does make sense to have an option there.
Ok, thanks.
So your accolades, can they be transformed into Acked-by-s or just mentioned in the patch like "reviewed and approved by ..."?
I for one have no objection to the idea itself. There have been several good suggestions though so I would like to see one more round here to which I can add an Acked-by.
thanks,
-serge