All of lore.kernel.org
 help / color / mirror / Atom feed
From: Beau Belgrave <beaub@linux.microsoft.com>
To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com
Cc: linux-trace-devel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [RFC PATCH v2 2/7] tracing: Add namespace instance directory to tracefs
Date: Thu, 28 Jul 2022 16:52:36 -0700	[thread overview]
Message-ID: <20220728235241.2249-3-beaub@linux.microsoft.com> (raw)
In-Reply-To: <20220728235241.2249-1-beaub@linux.microsoft.com>

Some tracing systems require a group or namespace isolation, such as
user_events. The namespace directory in tracefs is a singleton like the
instances directory. It also acts like the instances directory in that
user-mode processes can create a directory within the namespace if they
have appropriate permissions.

This change only covers adding the ability for a tracing system to
create the namespace directory. A system for adding and managing
namespaces will reside within another tracing API.

Link: https://lore.kernel.org/all/20220312010140.1880-1-beaub@linux.microsoft.com/

Signed-off-by: Beau Belgrave <beaub@linux.microsoft.com>
---
 fs/tracefs/inode.c      | 119 ++++++++++++++++++++++++++++++++++++++--
 include/linux/tracefs.h |   5 ++
 2 files changed, 118 insertions(+), 6 deletions(-)

diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index 81d26abf486f..7bf95cc65d78 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -24,6 +24,11 @@
 
 #define TRACEFS_DEFAULT_MODE	0700
 
+enum tracefs_dir_type {
+	TRACEFS_DIR_INSTANCES,
+	TRACEFS_DIR_NAMESPACES,
+};
+
 static struct vfsmount *tracefs_mount;
 static int tracefs_mount_count;
 static bool tracefs_registered;
@@ -50,6 +55,8 @@ static const struct file_operations tracefs_file_operations = {
 static struct tracefs_dir_ops {
 	int (*mkdir)(const char *name);
 	int (*rmdir)(const char *name);
+	int (*ns_mkdir)(const char *name);
+	int (*ns_rmdir)(const char *name);
 } tracefs_ops __ro_after_init;
 
 static char *get_dname(struct dentry *dentry)
@@ -67,9 +74,8 @@ static char *get_dname(struct dentry *dentry)
 	return name;
 }
 
-static int tracefs_syscall_mkdir(struct user_namespace *mnt_userns,
-				 struct inode *inode, struct dentry *dentry,
-				 umode_t mode)
+static int tracefs_syscall_mkdir_core(int type, struct inode *inode,
+				      struct dentry *dentry)
 {
 	char *name;
 	int ret;
@@ -84,7 +90,22 @@ static int tracefs_syscall_mkdir(struct user_namespace *mnt_userns,
 	 * mkdir routine to handle races.
 	 */
 	inode_unlock(inode);
-	ret = tracefs_ops.mkdir(name);
+
+	switch (type) {
+	case TRACEFS_DIR_INSTANCES:
+		ret = tracefs_ops.mkdir(name);
+		break;
+
+	case TRACEFS_DIR_NAMESPACES:
+		ret = tracefs_ops.ns_mkdir(name);
+		break;
+
+	default:
+		pr_debug("tracefs: unknown mkdir type '%d'\n", type);
+		ret = -ENOENT;
+		break;
+	}
+
 	inode_lock(inode);
 
 	kfree(name);
@@ -92,7 +113,24 @@ static int tracefs_syscall_mkdir(struct user_namespace *mnt_userns,
 	return ret;
 }
 
-static int tracefs_syscall_rmdir(struct inode *inode, struct dentry *dentry)
+static int tracefs_syscall_mkdir(struct user_namespace *mnt_userns,
+				 struct inode *inode, struct dentry *dentry,
+				 umode_t mode)
+{
+	return tracefs_syscall_mkdir_core(TRACEFS_DIR_INSTANCES,
+					  inode, dentry);
+}
+
+static int tracefs_syscall_ns_mkdir(struct user_namespace *mnt_userns,
+				    struct inode *inode, struct dentry *dentry,
+				    umode_t mode)
+{
+	return tracefs_syscall_mkdir_core(TRACEFS_DIR_NAMESPACES,
+					  inode, dentry);
+}
+
+static int tracefs_syscall_rmdir_core(int type, struct inode *inode,
+				      struct dentry *dentry)
 {
 	char *name;
 	int ret;
@@ -111,7 +149,20 @@ static int tracefs_syscall_rmdir(struct inode *inode, struct dentry *dentry)
 	inode_unlock(inode);
 	inode_unlock(d_inode(dentry));
 
-	ret = tracefs_ops.rmdir(name);
+	switch (type) {
+	case TRACEFS_DIR_INSTANCES:
+		ret = tracefs_ops.rmdir(name);
+		break;
+
+	case TRACEFS_DIR_NAMESPACES:
+		ret = tracefs_ops.ns_rmdir(name);
+		break;
+
+	default:
+		pr_debug("tracefs: unknown rmdir type '%d'\n", type);
+		ret = -ENOENT;
+		break;
+	}
 
 	inode_lock_nested(inode, I_MUTEX_PARENT);
 	inode_lock(d_inode(dentry));
@@ -121,12 +172,30 @@ static int tracefs_syscall_rmdir(struct inode *inode, struct dentry *dentry)
 	return ret;
 }
 
+static int tracefs_syscall_rmdir(struct inode *inode, struct dentry *dentry)
+{
+	return tracefs_syscall_rmdir_core(TRACEFS_DIR_INSTANCES,
+					  inode, dentry);
+}
+
+static int tracefs_syscall_ns_rmdir(struct inode *inode, struct dentry *dentry)
+{
+	return tracefs_syscall_rmdir_core(TRACEFS_DIR_NAMESPACES,
+					  inode, dentry);
+}
+
 static const struct inode_operations tracefs_dir_inode_operations = {
 	.lookup		= simple_lookup,
 	.mkdir		= tracefs_syscall_mkdir,
 	.rmdir		= tracefs_syscall_rmdir,
 };
 
+static const struct inode_operations tracefs_dir_inode_ns_operations = {
+	.lookup		= simple_lookup,
+	.mkdir		= tracefs_syscall_ns_mkdir,
+	.rmdir		= tracefs_syscall_ns_rmdir,
+};
+
 static struct inode *tracefs_get_inode(struct super_block *sb)
 {
 	struct inode *inode = new_inode(sb);
@@ -582,6 +651,44 @@ __init struct dentry *tracefs_create_instance_dir(const char *name,
 	return dentry;
 }
 
+/**
+ * tracefs_create_namespace_dir - create the tracing namespaces directory
+ * @name: The name of the namespaces directory to create
+ * @parent: The parent directory that the namespaces directory will exist
+ * @mkdir: The function to call when a mkdir is performed.
+ * @rmdir: The function to call when a rmdir is performed.
+ *
+ * Only one namespaces directory is allowed.
+ *
+ * The namespaces directory is special as it allows for mkdir and rmdir
+ * to be done by userspace. When a mkdir or rmdir is performed, the inode
+ * locks are released and the methods passed in (@mkdir and @rmdir) are
+ * called without locks and with the name of the directory being created
+ * within the namespaces directory.
+ *
+ * Returns the dentry of the namespaces directory.
+ */
+__init struct dentry *tracefs_create_namespace_dir(const char *name,
+					  struct dentry *parent,
+					  int (*mkdir)(const char *name),
+					  int (*rmdir)(const char *name))
+{
+	struct dentry *dentry;
+
+	/* Only allow one instance of the namespaces directory. */
+	if (WARN_ON(tracefs_ops.ns_mkdir || tracefs_ops.ns_rmdir))
+		return NULL;
+
+	dentry = __create_dir(name, parent, &tracefs_dir_inode_ns_operations);
+	if (!dentry)
+		return NULL;
+
+	tracefs_ops.ns_mkdir = mkdir;
+	tracefs_ops.ns_rmdir = rmdir;
+
+	return dentry;
+}
+
 static void remove_one(struct dentry *victim)
 {
 	simple_release_fs(&tracefs_mount, &tracefs_mount_count);
diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h
index 99912445974c..04870dee6c87 100644
--- a/include/linux/tracefs.h
+++ b/include/linux/tracefs.h
@@ -33,6 +33,11 @@ struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *pare
 					   int (*mkdir)(const char *name),
 					   int (*rmdir)(const char *name));
 
+struct dentry *tracefs_create_namespace_dir(const char *name,
+					    struct dentry *parent,
+					    int (*mkdir)(const char *name),
+					    int (*rmdir)(const char *name));
+
 bool tracefs_initialized(void);
 
 #endif /* CONFIG_TRACING */
-- 
2.25.1


  parent reply	other threads:[~2022-07-28 23:53 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-28 23:52 [RFC PATCH v2 0/7] tracing: Add tracing namespace API for user Beau Belgrave
2022-07-28 23:52 ` [RFC PATCH v2 1/7] tracing/user_events: Remove BROKEN and restore user_events.h location Beau Belgrave
2022-07-28 23:52 ` Beau Belgrave [this message]
2022-07-28 23:52 ` [RFC PATCH v2 3/7] tracing: Add tracing namespace API for systems to register with Beau Belgrave
2022-07-28 23:52 ` [RFC PATCH v2 4/7] tracing/user_events: Move pages/locks into groups to prepare for namespaces Beau Belgrave
2022-07-28 23:52 ` [RFC PATCH v2 5/7] tracing/user_events: Register with trace namespace API Beau Belgrave
2022-07-28 23:52 ` [RFC PATCH v2 6/7] tracing/user_events: Enable setting event limit within namespace Beau Belgrave
2022-07-28 23:52 ` [RFC PATCH v2 7/7] tracing/user_events: Add self-test for namespace integration Beau Belgrave

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=20220728235241.2249-3-beaub@linux.microsoft.com \
    --to=beaub@linux.microsoft.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-trace-devel@vger.kernel.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=mhiramat@kernel.org \
    --cc=rostedt@goodmis.org \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.