[Devel] [PATCH RH7] kernfs/sysfs: add ioctl to get fd network namespace tag
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Fri Jul 17 18:26:56 MSK 2020
Note, It produces crash on cleanup_net, will try to fix.
On 7/17/20 5:21 PM, Pavel Tikhomirov wrote:
> 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 */
>
--
Best regards, Tikhomirov Pavel
Software Developer, Virtuozzo.
More information about the Devel
mailing list