diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2011-06-15 10:21:48 -0700 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2012-11-20 04:19:49 -0800 |
commit | 98f842e675f96ffac96e6c50315790912b2812be (patch) | |
tree | ed4dee9a6e54e3443e9f3f1614c8a2fcf9b31e0a /ipc/namespace.c | |
parent | bf056bfa80596a5d14b26b17276a56a0dcb080e5 (diff) | |
download | linux-98f842e675f96ffac96e6c50315790912b2812be.tar.gz |
proc: Usable inode numbers for the namespace file descriptors.
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>
Diffstat (limited to 'ipc/namespace.c')
-rw-r--r-- | ipc/namespace.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/ipc/namespace.c b/ipc/namespace.c index 72c868277793..cf3386a51de2 100644 --- a/ipc/namespace.c +++ b/ipc/namespace.c @@ -26,9 +26,16 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns, if (ns == NULL) return ERR_PTR(-ENOMEM); + err = proc_alloc_inum(&ns->proc_inum); + if (err) { + kfree(ns); + return ERR_PTR(err); + } + atomic_set(&ns->count, 1); err = mq_init_ns(ns); if (err) { + proc_free_inum(ns->proc_inum); kfree(ns); return ERR_PTR(err); } @@ -111,6 +118,7 @@ static void free_ipc_ns(struct ipc_namespace *ns) */ ipcns_notify(IPCNS_REMOVED); put_user_ns(ns->user_ns); + proc_free_inum(ns->proc_inum); kfree(ns); } @@ -172,10 +180,18 @@ static int ipcns_install(struct nsproxy *nsproxy, void *new) return 0; } +static unsigned int ipcns_inum(void *vp) +{ + struct ipc_namespace *ns = vp; + + return ns->proc_inum; +} + const struct proc_ns_operations ipcns_operations = { .name = "ipc", .type = CLONE_NEWIPC, .get = ipcns_get, .put = ipcns_put, .install = ipcns_install, + .inum = ipcns_inum, }; |