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.u...@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 | 23 ++++++++++++++ sheep/sheep_priv.h | 3 ++ sheep/vdi.c | 30 ++++++++++++++++++ 12 files changed, 188 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.u...@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..ad8847a 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,20 @@ static struct sd_op_template sd_ops[] = { .process_work = local_set_loglevel, }, + [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, + }, + /* 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 -- sheepdog mailing list sheepdog@lists.wpkg.org http://lists.wpkg.org/mailman/listinfo/sheepdog