[sheepdog] [PATCH v2 04/12] dog: add nfs command

Liu Yuan namei.unix at gmail.com
Wed Jan 29 08:35:50 CET 2014


We support allocate as many nfs backend storage as you want.

usage:
 dog nfs create $name # create a nfs backend named $name
 dog nfs delete $name # delete a nfs backend named $name

$name is the name for users to mount at client in $IP:$NAME

Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
 dog/Makefile.am          |  4 +++
 dog/dog.c                |  5 +++
 dog/dog.h                |  8 +++--
 dog/nfs.c                | 81 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/internal_proto.h |  2 ++
 sheep/Makefile.am        |  3 +-
 sheep/http/http.h        |  2 +-
 sheep/http/kv.c          | 35 ++-------------------
 sheep/nfs/nfsd.c         | 29 +++++++++++++++++
 sheep/ops.c              | 25 +++++++++++++++
 sheep/sheep_priv.h       |  3 ++
 sheep/vdi.c              | 30 ++++++++++++++++++
 12 files changed, 190 insertions(+), 37 deletions(-)
 create mode 100644 dog/nfs.c

diff --git a/dog/Makefile.am b/dog/Makefile.am
index cfb0b20..a7ead61 100644
--- a/dog/Makefile.am
+++ b/dog/Makefile.am
@@ -32,6 +32,10 @@ dog_SOURCES		+= trace.c
 override CFLAGS         := $(subst -pg,,$(CFLAGS))
 endif
 
+if BUILD_NFS
+dog_SOURCES		+= nfs.c
+endif
+
 dog_LDADD		= ../lib/libsheepdog.a -lpthread
 dog_DEPENDENCIES	= ../lib/libsheepdog.a
 
diff --git a/dog/dog.c b/dog/dog.c
index a4859f4..6e55b2f 100644
--- a/dog/dog.c
+++ b/dog/dog.c
@@ -157,7 +157,12 @@ static void init_commands(const struct command **commands)
 		vdi_command,
 		node_command,
 		cluster_command,
+#ifdef HAVE_TRACE
 		trace_command,
+#endif
+#ifdef HAVE_NFS
+		nfs_command,
+#endif
 		{NULL,}
 	};
 
diff --git a/dog/dog.h b/dog/dog.h
index 383df30..76d5b49 100644
--- a/dog/dog.h
+++ b/dog/dog.h
@@ -109,11 +109,13 @@ extern struct command node_command;
 extern struct command cluster_command;
 
 #ifdef HAVE_TRACE
-  extern struct command trace_command;
-#else
-  #define trace_command {}
+extern struct command trace_command;
 #endif /* HAVE_TRACE */
 
+#ifdef HAVE_NFS
+extern struct command nfs_command;
+#endif /* HAVE_NFS */
+
 int do_loglevel_set(const struct node_id *nid, const char *loglevel_str);
 int do_loglevel_get(const struct node_id *nid, int32_t *ret_loglevel);
 const char *loglevel_to_str(int loglevel);
diff --git a/dog/nfs.c b/dog/nfs.c
new file mode 100644
index 0000000..784b6ec
--- /dev/null
+++ b/dog/nfs.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2014 Taobao Inc.
+ *
+ * Liu Yuan <namei.unix at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include "dog.h"
+
+static int nfs_create_delete(char *name, bool create)
+{
+	int ret;
+	struct sd_req hdr;
+	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
+
+	if (create)
+		sd_init_req(&hdr, SD_OP_NFS_CREATE);
+	else
+		sd_init_req(&hdr, SD_OP_NFS_DELETE);
+
+	hdr.flags = SD_FLAG_CMD_WRITE;
+	hdr.data_length = strlen(name) + 1;
+	ret = dog_exec_req(&sd_nid, &hdr, name);
+	if (ret < 0)
+		return EXIT_SYSFAIL;
+
+	switch (rsp->result) {
+	case SD_RES_SUCCESS:
+		break;
+	default:
+		sd_err("failed to create nfs %s, %s", name,
+		       sd_strerror(rsp->result));
+		return EXIT_SYSFAIL;
+	}
+
+	return EXIT_SUCCESS;
+}
+
+static int nfs_create(int argc, char **argv)
+{
+	return nfs_create_delete(argv[optind], true);
+}
+
+static int nfs_delete(int argc, char **argv)
+{
+	return nfs_create_delete(argv[optind], false);
+}
+
+static int nfs_parser(int ch, const char *opt)
+{
+	return 0;
+}
+
+static struct subcommand nfs_cmd[] = {
+	{"create", "<name>", "aph", "create a NFS file system", NULL,
+	 CMD_NEED_ARG, nfs_create},
+	{"delete", "<name>", "aph", "delete a NFS file system", NULL,
+	 CMD_NEED_ARG, nfs_delete},
+	{NULL},
+};
+
+struct command nfs_command = {
+	"nfs",
+	nfs_cmd,
+	nfs_parser,
+};
diff --git a/include/internal_proto.h b/include/internal_proto.h
index ceb8f84..d302c26 100644
--- a/include/internal_proto.h
+++ b/include/internal_proto.h
@@ -97,6 +97,8 @@
 #define SD_OP_STAT	0xB8
 #define SD_OP_GET_LOGLEVEL	0xB9
 #define SD_OP_SET_LOGLEVEL	0xBA
+#define SD_OP_NFS_CREATE	0xBB
+#define SD_OP_NFS_DELETE	0xBC
 
 /* internal flags for hdr.flags, must be above 0x80 */
 #define SD_FLAG_CMD_RECOVERY 0x0080
diff --git a/sheep/Makefile.am b/sheep/Makefile.am
index 82e3af9..3a82918 100644
--- a/sheep/Makefile.am
+++ b/sheep/Makefile.am
@@ -58,7 +58,8 @@ sheep_LDADD	  	= ../lib/libsheepdog.a -lpthread -lm\
 sheep_DEPENDENCIES	= ../lib/libsheepdog.a
 
 
-noinst_HEADERS		= sheep_priv.h cluster.h http/http.h trace/trace.h nfs/nfs.h
+noinst_HEADERS		= sheep_priv.h cluster.h http/http.h trace/trace.h
+			  nfs/nfs.h
 
 EXTRA_DIST		= 
 
diff --git a/sheep/http/http.h b/sheep/http/http.h
index f437f82..2d837c6 100644
--- a/sheep/http/http.h
+++ b/sheep/http/http.h
@@ -147,7 +147,7 @@ int kv_iterate_object(const char *account, const char *bucket,
 		      void (*cb)(const char *object, void *opaque),
 		      void *opaque);
 
-/* object_allocator.c */
+/* http/oalloc.c */
 int oalloc_new_prepare(uint32_t vid, uint64_t *start, uint64_t count);
 int oalloc_new_finish(uint32_t vid, uint64_t start, uint64_t count);
 int oalloc_free(uint32_t vid, uint64_t start, uint64_t count);
diff --git a/sheep/http/kv.c b/sheep/http/kv.c
index bfbf305..6b51b7b 100644
--- a/sheep/http/kv.c
+++ b/sheep/http/kv.c
@@ -60,35 +60,6 @@ struct bucket_iterater_arg {
 	uint64_t bytes_used;
 };
 
-static int kv_create_hyper_volume(const char *name, uint32_t *vdi_id)
-{
-	struct sd_req hdr;
-	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
-	int ret;
-	char buf[SD_MAX_VDI_LEN] = {0};
-
-	pstrcpy(buf, SD_MAX_VDI_LEN, name);
-
-	sd_init_req(&hdr, SD_OP_NEW_VDI);
-	hdr.flags = SD_FLAG_CMD_WRITE;
-	hdr.data_length = SD_MAX_VDI_LEN;
-
-	hdr.vdi.vdi_size = SD_MAX_VDI_SIZE;
-	hdr.vdi.copies = sys->cinfo.nr_copies;
-	hdr.vdi.copy_policy = sys->cinfo.copy_policy;
-	hdr.vdi.store_policy = 1;
-
-	ret = exec_local_req(&hdr, buf);
-	if (rsp->result != SD_RES_SUCCESS)
-		sd_err("Failed to create VDI %s: %s", name,
-		       sd_strerror(rsp->result));
-
-	if (vdi_id)
-		*vdi_id = rsp->vdi.vdi_id;
-
-	return ret;
-}
-
 /* Account operations */
 
 /*
@@ -114,7 +85,7 @@ static int kv_create_hyper_volume(const char *name, uint32_t *vdi_id)
 int kv_create_account(const char *account)
 {
 	uint32_t vdi_id;
-	return kv_create_hyper_volume(account, &vdi_id);
+	return sd_create_hyper_volume(account, &vdi_id);
 }
 
 static void bucket_iterater(void *data, enum btree_node_type type, void *arg)
@@ -317,14 +288,14 @@ static int bucket_create(const char *account, uint32_t account_vid,
 	int ret;
 
 	snprintf(onode_name, SD_MAX_VDI_LEN, "%s/%s", account, bucket);
-	ret = kv_create_hyper_volume(onode_name, &vid);
+	ret = sd_create_hyper_volume(onode_name, &vid);
 	if (ret != SD_RES_SUCCESS) {
 		sd_err("Failed to create bucket %s onode vid", bucket);
 		return ret;
 	}
 	snprintf(alloc_name, SD_MAX_VDI_LEN, "%s/%s/allocator", account,
 		 bucket);
-	ret = kv_create_hyper_volume(alloc_name, &vid);
+	ret = sd_create_hyper_volume(alloc_name, &vid);
 	if (ret != SD_RES_SUCCESS) {
 		sd_err("Failed to create bucket %s data vid", bucket);
 		sd_delete_vdi(onode_name);
diff --git a/sheep/nfs/nfsd.c b/sheep/nfs/nfsd.c
index a1394c5..6556673 100644
--- a/sheep/nfs/nfsd.c
+++ b/sheep/nfs/nfsd.c
@@ -207,3 +207,32 @@ int nfs_init(const char *options)
 
 	return 0;
 }
+
+int nfs_create(const char *name)
+{
+	uint32_t vdi;
+	int ret;
+
+	ret = sd_create_hyper_volume(name, &vdi);
+	if (ret != SD_RES_SUCCESS)
+		return ret;
+
+	return SD_RES_SUCCESS;
+}
+
+int nfs_delete(const char *name)
+{
+	char data_name[SD_MAX_VDI_LEN];
+	int ret;
+
+	ret = sd_delete_vdi(name);
+	if (ret != SD_RES_SUCCESS)
+		return ret;
+
+	snprintf(data_name, SD_MAX_VDI_LEN, "%s_nfs", name);
+	ret = sd_delete_vdi(data_name);
+	if (ret != SD_RES_SUCCESS)
+		return ret;
+
+	return SD_RES_SUCCESS;
+}
diff --git a/sheep/ops.c b/sheep/ops.c
index 1e9bc1e..9c3f429 100644
--- a/sheep/ops.c
+++ b/sheep/ops.c
@@ -998,7 +998,16 @@ static int local_set_loglevel(struct request *req)
 	set_loglevel(new_level);
 
 	return SD_RES_SUCCESS;
+}
+
+static int local_nfs_create(struct request *req)
+{
+	return nfs_create(req->data);
+}
 
+static int local_nfs_delete(struct request *req)
+{
+	return nfs_delete(req->data);
 }
 
 static struct sd_op_template sd_ops[] = {
@@ -1285,6 +1294,22 @@ static struct sd_op_template sd_ops[] = {
 		.process_work = local_set_loglevel,
 	},
 
+#ifdef HAVE_NFS
+	[SD_OP_NFS_CREATE] = {
+		.name = "NFS_CREATE",
+		.type = SD_OP_TYPE_LOCAL,
+		.force = false,
+		.process_work = local_nfs_create,
+	},
+
+	[SD_OP_NFS_DELETE] = {
+		.name = "NFS_DELETE",
+		.type = SD_OP_TYPE_LOCAL,
+		.force = false,
+		.process_work = local_nfs_delete,
+	},
+#endif
+
 	/* gateway I/O operations */
 	[SD_OP_CREATE_AND_WRITE_OBJ] = {
 		.name = "CREATE_AND_WRITE_OBJ",
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index 4289861..e500fa0 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -305,6 +305,7 @@ int vdi_lookup(const struct vdi_iocb *iocb, struct vdi_info *info);
 void clean_vdi_state(void);
 int sd_delete_vdi(const char *name);
 int sd_lookup_vdi(const char *name, uint32_t *vid);
+int sd_create_hyper_volume(const char *name, uint32_t *vdi_id);
 
 extern int ec_max_data_strip;
 
@@ -497,6 +498,8 @@ static inline int http_init(const char *options)
 
 #ifdef HAVE_NFS
 int nfs_init(const char *options);
+int nfs_create(const char *name);
+int nfs_delete(const char *name);
 #else
 static inline int nfs_init(const char *options)
 {
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 7559421..3c06a78 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -1304,3 +1304,33 @@ int sd_lookup_vdi(const char *name, uint32_t *vid)
 
 	return ret;
 }
+
+int sd_create_hyper_volume(const char *name, uint32_t *vdi_id)
+{
+	struct sd_req hdr;
+	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
+	char buf[SD_MAX_VDI_LEN] = {};
+	int ret;
+
+	pstrcpy(buf, SD_MAX_VDI_LEN, name);
+
+	sd_init_req(&hdr, SD_OP_NEW_VDI);
+	hdr.flags = SD_FLAG_CMD_WRITE;
+	hdr.data_length = SD_MAX_VDI_LEN;
+
+	hdr.vdi.vdi_size = SD_MAX_VDI_SIZE;
+	hdr.vdi.copies = sys->cinfo.nr_copies;
+	hdr.vdi.copy_policy = sys->cinfo.copy_policy;
+	hdr.vdi.store_policy = 1;
+
+	ret = exec_local_req(&hdr, buf);
+	if (ret != SD_RES_SUCCESS) {
+		sd_err("Failed to create VDI %s: %s", name, sd_strerror(ret));
+		goto out;
+	}
+
+	if (vdi_id)
+		*vdi_id = rsp->vdi.vdi_id;
+out:
+	return ret;
+}
-- 
1.8.1.2




More information about the sheepdog mailing list