diff options
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/init_task.h | 7 | ||||
-rw-r--r-- | include/linux/nsproxy.h | 45 | ||||
-rw-r--r-- | include/linux/sched.h | 2 |
3 files changed, 54 insertions, 0 deletions
diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 60aac2cea0c..8f8bb422a5c 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -68,6 +68,12 @@ .session = 1, \ } +extern struct nsproxy init_nsproxy; +#define INIT_NSPROXY(nsproxy) { \ + .count = ATOMIC_INIT(1), \ + .nslock = SPIN_LOCK_UNLOCKED, \ +} + #define INIT_SIGHAND(sighand) { \ .count = ATOMIC_INIT(1), \ .action = { { { .sa_handler = NULL, } }, }, \ @@ -117,6 +123,7 @@ extern struct group_info init_groups; .files = &init_files, \ .signal = &init_signals, \ .sighand = &init_sighand, \ + .nsproxy = &init_nsproxy, \ .pending = { \ .list = LIST_HEAD_INIT(tsk.pending.list), \ .signal = {{0}}}, \ diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h new file mode 100644 index 00000000000..7bdebfaab6a --- /dev/null +++ b/include/linux/nsproxy.h @@ -0,0 +1,45 @@ +#ifndef _LINUX_NSPROXY_H +#define _LINUX_NSPROXY_H + +#include <linux/spinlock.h> +#include <linux/sched.h> + +/* + * A structure to contain pointers to all per-process + * namespaces - fs (mount), uts, network, sysvipc, etc. + * + * 'count' is the number of tasks holding a reference. + * The count for each namespace, then, will be the number + * of nsproxies pointing to it, not the number of tasks. + * + * The nsproxy is shared by tasks which share all namespaces. + * As soon as a single namespace is cloned or unshared, the + * nsproxy is copied. + */ +struct nsproxy { + atomic_t count; + spinlock_t nslock; +}; +extern struct nsproxy init_nsproxy; + +struct nsproxy *dup_namespaces(struct nsproxy *orig); +int copy_namespaces(int flags, struct task_struct *tsk); +void get_task_namespaces(struct task_struct *tsk); +void free_nsproxy(struct nsproxy *ns); + +static inline void put_nsproxy(struct nsproxy *ns) +{ + if (atomic_dec_and_test(&ns->count)) { + free_nsproxy(ns); + } +} + +static inline void exit_task_namespaces(struct task_struct *p) +{ + struct nsproxy *ns = p->nsproxy; + if (ns) { + put_nsproxy(ns); + p->nsproxy = NULL; + } +} +#endif diff --git a/include/linux/sched.h b/include/linux/sched.h index a7fff3304bd..4fa631fa55e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -239,6 +239,7 @@ extern signed long schedule_timeout_uninterruptible(signed long timeout); asmlinkage void schedule(void); struct namespace; +struct nsproxy; /* Maximum number of active map areas.. This is a random (large) number */ #define DEFAULT_MAX_MAP_COUNT 65536 @@ -898,6 +899,7 @@ struct task_struct { struct files_struct *files; /* namespace */ struct namespace *namespace; + struct nsproxy *nsproxy; /* signal handlers */ struct signal_struct *signal; struct sighand_struct *sighand; |