@@ -169,6 +169,10 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
switch (ioctl) {
case NS_GET_USERNS:
return open_related_ns(ns, ns_get_owner);
+ case NS_GET_PARENT:
+ if (!ns->ops->get_parent)
+ return -EINVAL;
+ return open_related_ns(ns, ns->ops->get_parent);
default:
return -ENOTTY;
}
@@ -18,6 +18,7 @@ struct proc_ns_operations {
struct ns_common *(*get)(struct task_struct *task);
void (*put)(struct ns_common *ns);
int (*install)(struct nsproxy *nsproxy, struct ns_common *ns);
+ struct ns_common *(*get_parent)(struct ns_common *ns);
};
extern const struct proc_ns_operations netns_operations;
@@ -5,5 +5,6 @@
#define NSIO 0xb7
#define NS_GET_USERNS _IO(NSIO, 0x1)
+#define NS_GET_PARENT _IO(NSIO, 0x2)
#endif /* __LINUX_NSFS_H */
@@ -388,12 +388,38 @@ static int pidns_install(struct nsproxy *nsproxy, struct ns_common *ns)
return 0;
}
+static struct ns_common *pidns_get_parent(struct ns_common *ns)
+{
+ struct pid_namespace *active = task_active_pid_ns(current);
+ struct pid_namespace *pid_ns, *p;
+
+ pid_ns = to_pid_ns(ns);
+ if (pid_ns == &init_pid_ns) {
+ if (capable(CAP_SYS_ADMIN))
+ return ERR_PTR(-ENOENT);
+ return ERR_PTR(-EPERM);
+ }
+
+ pid_ns = p = pid_ns->parent;
+
+ for (;;) {
+ if (p == active)
+ break;
+ if (p == &init_pid_ns)
+ return ERR_PTR(-EPERM);
+ p = p->parent;
+ }
+
+ return &get_pid_ns(pid_ns)->ns;
+}
+
const struct proc_ns_operations pidns_operations = {
.name = "pid",
.type = CLONE_NEWPID,
.get = pidns_get,
.put = pidns_put,
.install = pidns_install,
+ .get_parent = pidns_get_parent,
};
static __init int pid_namespaces_init(void)
@@ -1024,6 +1024,7 @@ const struct proc_ns_operations userns_operations = {
.get = userns_get,
.put = userns_put,
.install = userns_install,
+ .get_parent = ns_get_owner,
};
static __init int user_namespaces_init(void)
Pid and user namepaces are hierarchical. There is no way to discover parent-child relationships. In a future we will use this interface to dump and restore nested namespaces. Signed-off-by: Andrey Vagin <avagin@openvz.org> --- fs/nsfs.c | 4 ++++ include/linux/proc_ns.h | 1 + include/uapi/linux/nsfs.h | 1 + kernel/pid_namespace.c | 26 ++++++++++++++++++++++++++ kernel/user_namespace.c | 1 + 5 files changed, 33 insertions(+)