[Devel] [PATCH RH7] kernfs/sysfs: add ioctl to get fd network namespace tag

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Fri Jul 17 17:21:04 MSK 2020


Sysfs mounts save current netns when mounting and show different set of
network devices in /sys/class/net based on it. But there is currently no
simple way to find out to that netns the sysfs mount is tagged to.

Lets add an ioctl so that we can get open file descriptor to this
namespace on nsfs. Next we would be able to readlink this fd to get
network namespace id.

We add an ability to get ns fd on both directories and files, as we may
need to determine netns for cut root bind mounts and file bind mount.

This is needed for CRIU to be able to dump CT with docker inside, which
mounts sysfs from non-root netns.

https://jira.sw.ru/browse/PSBM-105161

Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
 fs/kernfs/dir.c             |  1 +
 fs/kernfs/file.c            | 23 +++++++++++++++++++++++
 fs/kernfs/kernfs-internal.h |  1 +
 include/linux/kernfs.h      |  5 +++++
 4 files changed, 30 insertions(+)

diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 522947230f65..01d2e53acef2 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -1469,4 +1469,5 @@ const struct file_operations kernfs_dir_fops = {
 	.iterate	= kernfs_fop_readdir,
 	.release	= kernfs_dir_fop_release,
 	.llseek		= kernfs_dir_fop_llseek,
+	.unlocked_ioctl = kernfs_ioctl,
 };
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 3886845a2678..f8c482e1a6da 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -15,6 +15,10 @@
 #include <linux/pagemap.h>
 #include <linux/sched.h>
 #include <linux/fsnotify.h>
+#include <linux/proc_ns.h>
+#include <linux/magic.h>
+#include <linux/socket.h>
+#include <net/net_namespace.h>
 
 #include "kernfs-internal.h"
 
@@ -891,6 +895,24 @@ void kernfs_notify(struct kernfs_node *kn)
 }
 EXPORT_SYMBOL_GPL(kernfs_notify);
 
+long kernfs_ioctl(struct file *file, unsigned int ioctl,
+		  unsigned long arg)
+{
+	struct dentry *dentry = file->f_path.dentry;
+	const void *ns = kernfs_info(dentry->d_sb)->ns;
+	struct net *net;
+
+	switch (ioctl) {
+	case KERNFS_GET_NS:
+		if (dentry->d_sb->s_magic != SYSFS_MAGIC || !ns)
+			return -ENOTTY;
+		net = (struct net *)ns;
+		return open_related_ns(&net->ns, get_net_ns);
+	default:
+		return -ENOTTY;
+	}
+}
+
 const struct file_operations kernfs_file_fops = {
 	.read		= kernfs_fop_read,
 	.write		= kernfs_fop_write,
@@ -899,6 +921,7 @@ const struct file_operations kernfs_file_fops = {
 	.open		= kernfs_fop_open,
 	.release	= kernfs_fop_release,
 	.poll		= kernfs_fop_poll,
+	.unlocked_ioctl = kernfs_ioctl,
 };
 
 /**
diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h
index 0dab7ce93f22..fa102d625a49 100644
--- a/fs/kernfs/kernfs-internal.h
+++ b/fs/kernfs/kernfs-internal.h
@@ -119,6 +119,7 @@ struct kernfs_node *kernfs_new_node(struct kernfs_node *parent,
 extern const struct file_operations kernfs_file_fops;
 
 void kernfs_unmap_bin_file(struct kernfs_node *kn);
+long kernfs_ioctl(struct file *file, unsigned int ioctl, unsigned long arg);
 
 /*
  * symlink.c
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 485360932341..d3fe1f6dbd4f 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -16,6 +16,7 @@
 #include <linux/rbtree.h>
 #include <linux/atomic.h>
 #include <linux/wait.h>
+#include <linux/ioctl.h>
 
 struct file;
 struct dentry;
@@ -479,4 +480,8 @@ kernfs_mount(struct file_system_type *fs_type, int flags,
 				magic, new_sb_created, NULL);
 }
 
+#define KERNIO 0xb8
+
+#define KERNFS_GET_NS _IO(KERNIO, 0x1)
+
 #endif	/* __LINUX_KERNFS_H */
-- 
2.24.1



More information about the Devel mailing list