[RFC 4/4] fslist netlink interface

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch provides a netlink interaface for the namespace filesystem list.
It is quite simple, and I need at least one more operation (query).

Also, keep in mind that although I wrote it believing it is a nice
interface to manipulate the list, I don't feel strongly about the
interface per-se. So feel free to suggest something better.

Signed-off-by: Glauber Costa <glommer@xxxxxxxxxxxxx>
---
 fs/Kconfig                     |    9 +++
 fs/Makefile                    |    1 +
 fs/fsnetlink.c                 |  145 ++++++++++++++++++++++++++++++++++++++++
 include/linux/fslist_netlink.h |   35 ++++++++++
 4 files changed, 190 insertions(+), 0 deletions(-)
 create mode 100644 fs/fsnetlink.c
 create mode 100644 include/linux/fslist_netlink.h

diff --git a/fs/Kconfig b/fs/Kconfig
index 440d189..842dcc4 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -78,6 +78,15 @@ config GENERIC_ACL
 	bool
 	select FS_POSIX_ACL
 
+config FSLIST_NETLINK
+	bool "Filesystem Lists Netlink"
+	help
+	  This option allows userspace to select a sublist of the available
+	  filesystems that are mountable by a particular namespace. It provides
+	  a netlink interface through which one can manage such a set.
+
+
+
 menu "Caches"
 
 source "fs/fscache/Kconfig"
diff --git a/fs/Makefile b/fs/Makefile
index 57d446d..675f613 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_FS_MBCACHE)	+= mbcache.o
 obj-$(CONFIG_FS_POSIX_ACL)	+= posix_acl.o xattr_acl.o
 obj-$(CONFIG_NFS_COMMON)	+= nfs_common/
 obj-$(CONFIG_GENERIC_ACL)	+= generic_acl.o
+obj-$(CONFIG_FSLIST_NETLINK)	+= fsnetlink.o
 
 obj-$(CONFIG_FHANDLE)		+= fhandle.o
 
diff --git a/fs/fsnetlink.c b/fs/fsnetlink.c
new file mode 100644
index 0000000..619fad1
--- /dev/null
+++ b/fs/fsnetlink.c
@@ -0,0 +1,145 @@
+#include <net/genetlink.h>
+#include <linux/fslist_netlink.h>
+#include <linux/gfp.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/nsproxy.h>
+#include <linux/mnt_namespace.h>
+#include <linux/fs_struct.h>
+#include <linux/dcache.h>
+
+static struct nla_policy fslist_genl_policy[FSLIST_A_MAX + 1] = {
+	[FSLIST_A_OP] = { .type = NLA_U32 },
+	[FSLIST_A_OP_ARG] = { .type = NLA_STRING, .len = 200 },
+};
+
+static struct genl_family fslist_gnl_family = {
+	.id		= GENL_ID_GENERATE,
+	.name		= FSLIST_GENL_NAME,
+	.version	= FSLIST_GENL_VERSION,
+	.maxattr	= FSLIST_A_MAX,
+};
+
+static int msg_reply(int ret, struct genl_info *info)
+{
+        struct sk_buff *skb;
+        void *reply;
+	size_t size;
+	struct genlmsghdr *genlhdr;
+	void *data;
+
+	size =  nla_total_size(1) +
+		nla_total_size(0);
+
+	skb = genlmsg_new(size, GFP_KERNEL);
+	if (!skb)
+		return -ENOMEM;
+
+	reply = genlmsg_put_reply(skb, info, &fslist_gnl_family, 0, FSLIST_CMD_REPLY);
+	if (reply == NULL) {
+		nlmsg_free(skb);
+		return -EINVAL;
+	}
+
+	nla_put_u32(skb, FSLIST_A_OP, ret);
+
+	genlhdr = nlmsg_data((struct nlmsghdr *)skb->data);
+	data = genlmsg_data(genlhdr);
+
+	ret = genlmsg_end(skb, data);
+	if (ret < 0) {
+		nlmsg_free(skb);
+		return ret;
+	}
+
+	return genlmsg_reply(skb, info);
+}
+
+
+static int cmd_ask(struct sk_buff *skb, struct genl_info *info)
+{
+	struct nlattr *na;
+	int op = 0;
+	char *data = NULL;
+	int ret = 0;
+	struct mnt_namespace *mnt = current->nsproxy->mnt_ns;
+	struct dentry *curr_root;
+	int msg_ret = 0;
+
+	/*
+	 * Once a process is contained by a chroot environment,
+	 * we don't allow the list to grow further, or be by
+	 * any means modified. 
+	 *
+	 * It should still work after pivot_root, though.
+	 */
+	curr_root = current->fs->root.dentry;
+	if (curr_root->d_parent != curr_root)
+		return -EINVAL;
+
+	na = info->attrs[FSLIST_A_OP];
+	if (na) 
+		op = nla_get_u32(na);
+
+	na = info->attrs[FSLIST_A_OP_ARG];
+	if (na) {
+		int len = nla_len(na);
+
+		data = kmalloc(len, GFP_KERNEL);
+		if (!data)
+			return -ENOMEM;
+
+		nla_strlcpy(data, na, len);
+	}
+
+	switch (op) {
+	case FSLIST_OP_RESET:
+		enable_filesystems_list(mnt);
+		break;
+	case FSLIST_OP_ADD:
+		if (!data) {
+			ret = -EINVAL;
+			break;
+		}
+		msg_ret = add_filesystem_list(data, mnt);
+		break;
+	case FSLIST_OP_QUERY:
+		ret = -ENOSYS;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	
+	kfree(data);
+	if (!ret)
+		msg_reply(msg_ret, info);
+	return ret;
+}
+
+static struct genl_ops fslist_nl_ops = {
+	.cmd		= FSLIST_CMD_ASK,
+	.doit		= cmd_ask,
+	.policy 	= fslist_genl_policy,
+};
+
+int __init fslist_netlink_init(void)
+{
+	int ret;
+	ret = genl_register_family(&fslist_gnl_family);
+	if (ret) 
+		return ret;
+	
+	ret = genl_register_ops(&fslist_gnl_family, &fslist_nl_ops);
+	if (ret)
+		goto fail_unregister;
+
+	return 0;
+
+fail_unregister:
+	genl_unregister_family(&fslist_gnl_family);
+	return ret;
+}
+
+fs_initcall(fslist_netlink_init);
+
diff --git a/include/linux/fslist_netlink.h b/include/linux/fslist_netlink.h
new file mode 100644
index 0000000..926760d
--- /dev/null
+++ b/include/linux/fslist_netlink.h
@@ -0,0 +1,35 @@
+#ifndef _FSLIST_NETLINK_H
+#define _FSLIST_NETLINK_H
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#endif
+
+enum {
+	FSLIST_A_UNSPEC,
+	FSLIST_A_OP,
+	FSLIST_A_OP_ARG,
+	__FSLIST_A_MAX,
+};
+
+#define FSLIST_A_MAX (__FSLIST_A_MAX - 1)
+
+enum {
+	FSLIST_CMD_UNSPEC = 0,
+	FSLIST_CMD_ASK,		/* user->kernel */
+	FSLIST_CMD_REPLY,	/* kernel->user */
+	__FSLIST_CMD_MAX,
+};
+
+#define FSLIST_CMD_MAX (__FSLIST_CMD_MAX - 1)
+
+#define FSLIST_GENL_VERSION 0x1
+#define FSLIST_GENL_NAME "FSLIST"
+
+enum {
+	FSLIST_OP_RESET = 1,
+	FSLIST_OP_ADD,
+	FSLIST_OP_QUERY,
+};
+
+#endif /* _FSLIST_NETLINK_H */
-- 
1.7.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux