mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
60e6a983e5
Assign a unique proc inode to each namespace, and use that
inode number to ensure we only allocate at most one proc
inode for every namespace in proc.
A single proc inode per namespace allows userspace to test
to see if two processes are in the same namespace.
This has been a long requested feature and only blocked because
a naive implementation would put the id in a global space and
would ultimately require having a namespace for the names of
namespaces, making migration and certain virtualization tricks
impossible.
We still don't have per superblock inode numbers for proc, which
appears necessary for application unaware checkpoint/restart and
migrations (if the application is using namespace file descriptors)
but that is now allowd by the design if it becomes important.
I have preallocated the ipc and uts initial proc inode numbers so
their structures can be statically initialized.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
(cherry picked from commit 98f842e675
)
96 lines
2.1 KiB
C
96 lines
2.1 KiB
C
#ifndef _LINUX_PID_NS_H
|
|
#define _LINUX_PID_NS_H
|
|
|
|
#include <linux/sched.h>
|
|
#include <linux/bug.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/threads.h>
|
|
#include <linux/nsproxy.h>
|
|
#include <linux/kref.h>
|
|
|
|
struct pidmap {
|
|
atomic_t nr_free;
|
|
void *page;
|
|
};
|
|
|
|
#define PIDMAP_ENTRIES ((PID_MAX_LIMIT + 8*PAGE_SIZE - 1)/PAGE_SIZE/8)
|
|
|
|
struct bsd_acct_struct;
|
|
|
|
struct pid_namespace {
|
|
struct kref kref;
|
|
struct pidmap pidmap[PIDMAP_ENTRIES];
|
|
int last_pid;
|
|
struct task_struct *child_reaper;
|
|
struct kmem_cache *pid_cachep;
|
|
unsigned int level;
|
|
struct pid_namespace *parent;
|
|
#ifdef CONFIG_PROC_FS
|
|
struct vfsmount *proc_mnt;
|
|
#endif
|
|
#ifdef CONFIG_BSD_PROCESS_ACCT
|
|
struct bsd_acct_struct *bacct;
|
|
#endif
|
|
gid_t pid_gid;
|
|
int hide_pid;
|
|
int reboot; /* group exit code if this pidns was rebooted */
|
|
unsigned int proc_inum;
|
|
};
|
|
|
|
extern struct pid_namespace init_pid_ns;
|
|
|
|
#ifdef CONFIG_PID_NS
|
|
static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns)
|
|
{
|
|
if (ns != &init_pid_ns)
|
|
kref_get(&ns->kref);
|
|
return ns;
|
|
}
|
|
|
|
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);
|
|
extern int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd);
|
|
|
|
static inline void put_pid_ns(struct pid_namespace *ns)
|
|
{
|
|
if (ns != &init_pid_ns)
|
|
kref_put(&ns->kref, free_pid_ns);
|
|
}
|
|
|
|
#else /* !CONFIG_PID_NS */
|
|
#include <linux/err.h>
|
|
|
|
static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns)
|
|
{
|
|
return ns;
|
|
}
|
|
|
|
static inline struct pid_namespace *
|
|
copy_pid_ns(unsigned long flags, struct pid_namespace *ns)
|
|
{
|
|
if (flags & CLONE_NEWPID)
|
|
ns = ERR_PTR(-EINVAL);
|
|
return ns;
|
|
}
|
|
|
|
static inline void put_pid_ns(struct pid_namespace *ns)
|
|
{
|
|
}
|
|
|
|
static inline void zap_pid_ns_processes(struct pid_namespace *ns)
|
|
{
|
|
BUG();
|
|
}
|
|
|
|
static inline int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif /* CONFIG_PID_NS */
|
|
|
|
extern struct pid_namespace *task_active_pid_ns(struct task_struct *tsk);
|
|
void pidhash_init(void);
|
|
void pidmap_init(void);
|
|
|
|
#endif /* _LINUX_PID_NS_H */
|