LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: "Yordan Karadzhov (VMware)" <y.karadz@gmail.com>
To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org
Cc: viro@zeniv.linux.org.uk, ebiederm@xmission.com,
	rostedt@goodmis.org, mingo@redhat.com, hagen@jauu.net,
	rppt@kernel.org, James.Bottomley@HansenPartnership.com,
	akpm@linux-foundation.org, vvs@virtuozzo.com,
	shakeelb@google.com, christian.brauner@ubuntu.com,
	mkoutny@suse.com,
	"Yordan Karadzhov (VMware)" <y.karadz@gmail.com>
Subject: [RFC PATCH 2/4] namespacefs: Add methods to create/remove PID namespace directories
Date: Thu, 18 Nov 2021 20:12:08 +0200	[thread overview]
Message-ID: <20211118181210.281359-3-y.karadz@gmail.com> (raw)
In-Reply-To: <20211118181210.281359-1-y.karadz@gmail.com>

Each existing namespace on the system will be represented by a
corresponding directory in namespacesfs. When a namespace is created
a new directory will be added. When a namespace is destroyed, its
corresponding directory will be removed. When fully functional,
'namespacesfs' will provide a direct (1 to 1) mapping between the
hierarchy of all namespaces that are currently active on the system
and the hierarchy of directories in 'namespacesfs'.

As a first step towards this, here we add methods for creating and
removing PID namespace directories. For the moment the PID namespace
directory contains only one file called 'tasks'. This is a read only
pseudo file that provides a list of PIDs of all tasks enclosed inside
the namespace.

We modify 'struct ns_common' so that each namespaces will be able to
own a pointer to the 'dentry' of its corresponding directory in
'namespacesfs'. This pointer will be used to couple the creation and
destruction of a namespace with the creation and removal of its
corresponding directory.

In the patch we also add generic helper methods for printing the content
of an 'idr' ('id to pointer' translation service) into synthetic files
from sequences of records (seq_file). These new definitions are used by
'namespacefs' when printing the PIDs of the tasks in each PID namespace.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 fs/namespacefs/inode.c      | 119 ++++++++++++++++++++++++++++++++++++
 include/linux/idr-seq.h     |   0
 include/linux/namespacefs.h |  13 ++++
 include/linux/ns_common.h   |   4 ++
 4 files changed, 136 insertions(+)
 delete mode 100644 include/linux/idr-seq.h

diff --git a/fs/namespacefs/inode.c b/fs/namespacefs/inode.c
index 0f6293b0877d..012c1c43b44d 100644
--- a/fs/namespacefs/inode.c
+++ b/fs/namespacefs/inode.c
@@ -10,6 +10,8 @@
 #include <linux/namei.h>
 #include <linux/fsnotify.h>
 #include <linux/magic.h>
+#include <linux/idr.h>
+#include <linux/seq_file.h>
 
 static struct vfsmount *namespacefs_mount;
 static int namespacefs_mount_count;
@@ -188,6 +190,123 @@ void namespacefs_remove_dir(struct dentry *dentry)
 	release_namespacefs();
 }
 
+struct idr_seq_context {
+	struct idr	*idr;
+	int		index;
+};
+
+static void *idr_seq_get_next(struct idr_seq_context *idr_ctx, loff_t *pos)
+{
+	void *next = idr_get_next(idr_ctx->idr, &idr_ctx->index);
+
+	*pos = ++idr_ctx->index;
+	return next;
+}
+
+static void *idr_seq_start(struct seq_file *m, loff_t *pos)
+{
+	struct idr_seq_context *idr_ctx = m->private;
+
+	idr_lock(idr_ctx->idr);
+	idr_ctx->index = *pos;
+	return idr_seq_get_next(idr_ctx, pos);
+}
+
+static void *idr_seq_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	return idr_seq_get_next(m->private, pos);
+}
+
+static void idr_seq_stop(struct seq_file *m, void *p)
+{
+	struct idr_seq_context *idr_ctx = m->private;
+
+	idr_unlock(idr_ctx->idr);
+}
+
+static int idr_seq_open(struct file *file, struct idr *idr,
+			const struct seq_operations *ops)
+{
+	struct idr_seq_context *idr_ctx;
+
+	idr_ctx = __seq_open_private(file, ops, sizeof(*idr_ctx));
+	if (!idr_ctx)
+		return -ENOMEM;
+
+	idr_ctx->idr = idr;
+
+	return 0;
+}
+
+static inline int pid_seq_show(struct seq_file *m, void *v)
+{
+	struct pid *pid = v;
+
+	seq_printf(m, "%d\n", pid_nr(pid));
+	return 0;
+}
+
+static const struct seq_operations pid_seq_ops = {
+	.start		= idr_seq_start,
+	.next		= idr_seq_next,
+	.stop		= idr_seq_stop,
+	.show		= pid_seq_show,
+};
+
+static int pid_seq_open(struct inode *inode, struct file *file)
+{
+	struct idr *idr = inode->i_private;
+
+	return idr_seq_open(file, idr, &pid_seq_ops);
+}
+
+static const struct file_operations tasks_fops = {
+	.open		= pid_seq_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release_private,
+};
+
+static int create_inode_dir(struct ns_common *ns, struct dentry *parent_dentry,
+			    const struct user_namespace *user_ns)
+{
+	char *dir = kasprintf(GFP_KERNEL, "%u", ns->inum);
+
+	if (!dir)
+		return -ENOMEM;
+
+	ns->dentry = namespacefs_create_dir(dir, parent_dentry, user_ns);
+	kfree(dir);
+	if (IS_ERR(ns->dentry))
+		return PTR_ERR(ns->dentry);
+
+	return 0;
+}
+
+int namespacefs_create_pid_ns_dir(struct pid_namespace *ns)
+{
+	struct dentry *dentry;
+	int err;
+
+	err = create_inode_dir(&ns->ns, ns->parent->ns.dentry, ns->user_ns);
+	if (err)
+		return err;
+
+	dentry = namespacefs_create_file("tasks", ns->ns.dentry, ns->user_ns,
+					 &tasks_fops, &ns->idr);
+	if (IS_ERR(dentry)) {
+		dput(ns->ns.dentry);
+		return PTR_ERR(dentry);
+	}
+
+	return 0;
+}
+
+void namespacefs_remove_pid_ns_dir(struct pid_namespace *ns)
+{
+	namespacefs_remove_dir(ns->ns.dentry);
+}
+
 #define _NS_MOUNT_DIR	"namespaces"
 
 static int __init namespacefs_init(void)
diff --git a/include/linux/idr-seq.h b/include/linux/idr-seq.h
deleted file mode 100644
index e69de29bb2d1..000000000000
diff --git a/include/linux/namespacefs.h b/include/linux/namespacefs.h
index 44a760080df7..f41499a7635a 100644
--- a/include/linux/namespacefs.h
+++ b/include/linux/namespacefs.h
@@ -19,6 +19,8 @@ struct dentry *
 namespacefs_create_dir(const char *name, struct dentry *parent,
 		       const struct user_namespace *user_ns);
 void namespacefs_remove_dir(struct dentry *dentry);
+int namespacefs_create_pid_ns_dir(struct pid_namespace *ns);
+void namespacefs_remove_pid_ns_dir(struct pid_namespace *ns);
 
 #else
 
@@ -42,6 +44,17 @@ static inline void namespacefs_remove_dir(struct dentry *dentry)
 {
 }
 
+static inline int
+namespacefs_create_pid_ns_dir(struct pid_namespace *ns)
+{
+	return 0;
+}
+
+static inline void
+namespacefs_remove_pid_ns_dir(struct pid_namespace *ns)
+{
+}
+
 #endif /* CONFIG_NAMESPACE_FS */
 
 #endif
diff --git a/include/linux/ns_common.h b/include/linux/ns_common.h
index 0f1d024bd958..1dec75c51b2c 100644
--- a/include/linux/ns_common.h
+++ b/include/linux/ns_common.h
@@ -11,6 +11,10 @@ struct ns_common {
 	const struct proc_ns_operations *ops;
 	unsigned int inum;
 	refcount_t count;
+
+#ifdef CONFIG_NAMESPACE_FS
+	struct dentry *dentry;
+#endif /* CONFIG_NAMESPACE_FS */
 };
 
 #endif
-- 
2.33.1


  parent reply	other threads:[~2021-11-18 18:13 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-18 18:12 [RFC PATCH 0/4] namespacefs: Proof-of-Concept Yordan Karadzhov (VMware)
2021-11-18 18:12 ` [RFC PATCH 1/4] namespacefs: Introduce 'namespacefs' Yordan Karadzhov (VMware)
2021-11-18 18:12 ` Yordan Karadzhov (VMware) [this message]
2021-11-18 18:12 ` [RFC PATCH 3/4] namespacefs: Couple namespacefs to the PID namespace Yordan Karadzhov (VMware)
2021-11-18 18:12 ` [RFC PATCH 4/4] namespacefs: Couple namespacefs to the UTS namespace Yordan Karadzhov (VMware)
2021-11-18 18:55 ` [RFC PATCH 0/4] namespacefs: Proof-of-Concept Eric W. Biederman
2021-11-18 19:02   ` Steven Rostedt
2021-11-18 19:22     ` Eric W. Biederman
2021-11-18 19:36       ` Steven Rostedt
2021-11-18 19:24   ` Steven Rostedt
2021-11-19  9:50     ` Kirill Tkhai
2021-11-19 12:45     ` James Bottomley
     [not found]       ` <20211119092758.1012073e@gandalf.local.home>
2021-11-19 16:42         ` James Bottomley
2021-11-19 17:14           ` Yordan Karadzhov
2021-11-19 17:22             ` Steven Rostedt
2021-11-19 23:22             ` James Bottomley
2021-11-20  0:07               ` Steven Rostedt
2021-11-20  0:14                 ` James Bottomley
     [not found]         ` <f6ca1f5bdb3b516688f291d9685a6a59f49f1393.camel@HansenPartnership.com>
2021-11-19 16:47           ` Steven Rostedt
2021-11-19 16:49             ` Steven Rostedt
2021-11-19 23:08               ` James Bottomley
2021-11-22 13:02                 ` Yordan Karadzhov
2021-11-22 13:44                   ` James Bottomley
2021-11-22 15:00                     ` Yordan Karadzhov
2021-11-22 15:47                       ` James Bottomley
2021-11-22 16:15                         ` Yordan Karadzhov
2021-11-19 14:26   ` Yordan Karadzhov
2021-11-18 21:24 ` Mike Rapoport

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211118181210.281359-3-y.karadz@gmail.com \
    --to=y.karadz@gmail.com \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=akpm@linux-foundation.org \
    --cc=christian.brauner@ubuntu.com \
    --cc=ebiederm@xmission.com \
    --cc=hagen@jauu.net \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=mkoutny@suse.com \
    --cc=rostedt@goodmis.org \
    --cc=rppt@kernel.org \
    --cc=shakeelb@google.com \
    --cc=viro@zeniv.linux.org.uk \
    --cc=vvs@virtuozzo.com \
    --subject='Re: [RFC PATCH 2/4] namespacefs: Add methods to create/remove PID namespace directories' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).