aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2011-06-15 10:21:48 -0700
committerZiyan <jaraidaniel@gmail.com>2016-03-11 16:08:59 +0100
commite1405a6b24b7f9b84aee7aff6db09e5ca5c17cec (patch)
tree3480b8e0e625b0036af678e672a6491225e71ab6 /ipc
parenta6bf34a158d63bc888bb8c89b86cbc95e5d986c3 (diff)
downloadkernel_samsung_espresso10-e1405a6b24b7f9b84aee7aff6db09e5ca5c17cec.zip
kernel_samsung_espresso10-e1405a6b24b7f9b84aee7aff6db09e5ca5c17cec.tar.gz
kernel_samsung_espresso10-e1405a6b24b7f9b84aee7aff6db09e5ca5c17cec.tar.bz2
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> (cherry picked from commit 98f842e675f96ffac96e6c50315790912b2812be)
Diffstat (limited to 'ipc')
-rw-r--r--ipc/msgutil.c2
-rw-r--r--ipc/namespace.c16
2 files changed, 18 insertions, 0 deletions
diff --git a/ipc/msgutil.c b/ipc/msgutil.c
index 8b5ce5d..3123735 100644
--- a/ipc/msgutil.c
+++ b/ipc/msgutil.c
@@ -16,6 +16,7 @@
#include <linux/ipc_namespace.h>
#include <asm/uaccess.h>
+#include <linux/proc_fs.h>
#include "util.h"
DEFINE_SPINLOCK(mq_lock);
@@ -33,6 +34,7 @@ struct ipc_namespace init_ipc_ns = {
.mq_msgsize_max = DFLT_MSGSIZEMAX,
#endif
.user_ns = &init_user_ns,
+ .proc_inum = PROC_IPC_INIT_INO,
};
atomic_t nr_ipc_ns = ATOMIC_INIT(1);
diff --git a/ipc/namespace.c b/ipc/namespace.c
index ce0a647..cd7f733 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -26,9 +26,16 @@ static struct ipc_namespace *create_ipc_ns(struct task_struct *tsk,
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);
}
@@ -113,6 +120,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);
}
@@ -170,10 +178,18 @@ static int ipcns_install(struct nsproxy *nsproxy, void *ns)
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,
};