[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