[sheepdog] [PATCH v2 10/15] sheepfs: teach volumes to unmount
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Sun May 20 12:09:14 CEST 2012
At Mon, 14 May 2012 17:47:35 +0800,
Liu Yuan wrote:
>
> From: Liu Yuan <tailai.ly at taobao.com>
>
> This is how we can deattach the volumes from sheep cluster storage.
>
> Usage:
> echo vdi_name > sheepfs_dir/vdi/unmount
>
> Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
> ---
> include/sheep.h | 1 +
> sheep/ops.c | 20 ++++++++++++++++++++
> sheepfs/core.c | 3 ++-
> sheepfs/sheepfs.h | 3 +++
> sheepfs/vdi.c | 14 ++++++++++++++
> sheepfs/volume.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
> 6 files changed, 87 insertions(+), 2 deletions(-)
>
> diff --git a/include/sheep.h b/include/sheep.h
> index 7e287c4..4a45f9b 100644
> --- a/include/sheep.h
> +++ b/include/sheep.h
> @@ -46,6 +46,7 @@
> #define SD_OP_TRACE 0x95
> #define SD_OP_TRACE_CAT 0x96
> #define SD_OP_STAT_RECOVERY 0x97
> +#define SD_OP_FLUSH_DEL_CACHE 0x98
>
> #define SD_FLAG_CMD_IO_LOCAL 0x0010
> #define SD_FLAG_CMD_RECOVERY 0x0020
> diff --git a/sheep/ops.c b/sheep/ops.c
> index b6f8eb2..a1c4ad3 100644
> --- a/sheep/ops.c
> +++ b/sheep/ops.c
> @@ -617,6 +617,21 @@ static int local_flush_vdi(const struct sd_req *req, struct sd_rsp *rsp, void *d
> return SD_RES_SUCCESS;
> }
>
> +static int local_flush_and_del(const struct sd_req *req, struct sd_rsp *rsp,
> + void *data)
> +{
> + struct sd_obj_req *hdr = (struct sd_obj_req *)req;
> + uint64_t oid = hdr->oid;
> + uint32_t vid = oid_to_vid(oid);
> + struct object_cache *cache = find_object_cache(vid, 0);
> +
> + if (cache)
> + if (object_cache_flush_and_delete(cache) < 0)
> + return SD_RES_EIO;
> +
> + return SD_RES_SUCCESS;
> +}
> +
> static int local_trace_ops(const struct sd_req *req, struct sd_rsp *rsp, void *data)
> {
> int enable = req->data_length, ret;
> @@ -1007,6 +1022,11 @@ static struct sd_op_template sd_ops[] = {
> .process_work = local_flush_vdi,
> },
>
> + [SD_OP_FLUSH_DEL_CACHE] = {
> + .type = SD_OP_TYPE_LOCAL,
> + .process_work = local_flush_and_del,
> + },
> +
> [SD_OP_TRACE] = {
> .type = SD_OP_TYPE_LOCAL,
> .force = 1,
> diff --git a/sheepfs/core.c b/sheepfs/core.c
> index 0298ee8..4ff60cf 100644
> --- a/sheepfs/core.c
> +++ b/sheepfs/core.c
> @@ -52,7 +52,8 @@ static struct sheepfs_file_operation {
> [OP_NULL] = { NULL, NULL, NULL },
> [OP_CLUSTER_INFO] = { cluster_info_read, NULL, cluster_info_get_size },
> [OP_VDI_LIST] = { vdi_list_read, NULL, vdi_list_get_size },
> - [OP_VDI_MOUNT] = { NULL, vdi_mount_write, NULL },
> + [OP_VDI_MOUNT] = { NULL, vdi_mount_write },
> + [OP_VDI_UNMOUNT] = { NULL, vdi_unmount_write },
> [OP_VOLUME] = { volume_read, volume_write, volume_get_size,
> volume_sync, volume_open },
> };
> diff --git a/sheepfs/sheepfs.h b/sheepfs/sheepfs.h
> index e0be541..9e2d4bc 100644
> --- a/sheepfs/sheepfs.h
> +++ b/sheepfs/sheepfs.h
> @@ -8,6 +8,7 @@ enum sheepfs_opcode {
> OP_CLUSTER_INFO,
> OP_VDI_LIST,
> OP_VDI_MOUNT,
> + OP_VDI_UNMOUNT,
> OP_VOLUME,
> };
>
> @@ -34,6 +35,7 @@ extern int volume_read(const char *path, char *buf, size_t size, off_t offset);
> extern int volume_write(const char *, const char *buf, size_t size, off_t);
> extern size_t volume_get_size(const char *);
> extern int volume_create_entry(const char *entry);
> +extern int volume_remove_entry(const char *entry);
> extern int volume_sync(const char *path);
> extern int volume_open(const char *path, struct fuse_file_info *);
>
> @@ -48,5 +50,6 @@ extern int vdi_list_read(const char *path, char *buf, size_t size, off_t);
> extern size_t vdi_list_get_size(const char *path);
>
> extern int vdi_mount_write(const char *, const char *buf, size_t size, off_t);
> +extern int vdi_unmount_write(const char *, const char *buf, size_t, off_t);
>
> #endif
> diff --git a/sheepfs/vdi.c b/sheepfs/vdi.c
> index 8eefd59..bd4f875 100644
> --- a/sheepfs/vdi.c
> +++ b/sheepfs/vdi.c
> @@ -27,6 +27,7 @@
> #define PATH_VDI "/vdi"
> #define PATH_VDI_LIST "/vdi/list"
> #define PATH_VDI_MOUNT "/vdi/mount"
> +#define PATH_VDI_UNMOUNT "/vdi/unmount"
>
> int create_vdi_layout(void)
> {
> @@ -43,6 +44,11 @@ int create_vdi_layout(void)
> if (sheepfs_set_op(PATH_VDI_MOUNT, OP_VDI_MOUNT) < 0)
> return -1;
>
> + if (shadow_file_create(PATH_VDI_UNMOUNT) < 0)
> + return -1;
> + if (sheepfs_set_op(PATH_VDI_UNMOUNT, OP_VDI_UNMOUNT) < 0)
> + return -1;
> +
> return 0;
> }
>
> @@ -71,3 +77,11 @@ int vdi_mount_write(const char *path, const char *buf, size_t size,
> return -EIO;
> return size;
> }
> +
> +int vdi_unmount_write(const char *path, const char *buf, size_t size,
> + off_t ignore)
> +{
> + if (volume_remove_entry(buf) < 0)
> + return -EIO;
> + return size;
> +}
> diff --git a/sheepfs/volume.c b/sheepfs/volume.c
> index 17c2e9b..2a6ba4c 100644
> --- a/sheepfs/volume.c
> +++ b/sheepfs/volume.c
> @@ -21,6 +21,7 @@
> #include <assert.h>
> #include <syslog.h>
>
> +#include "sheep.h"
> #include "strbuf.h"
> #include "sheepfs.h"
> #include "net.h"
> @@ -232,7 +233,7 @@ static int volume_do_sync(uint32_t vid)
> hdr.opcode = SD_OP_FLUSH_VDI;
> hdr.oid = vid_to_vdi_oid(vid);
>
> - ret = exec_req(sheep_fd, (struct sd_req *)&hdr, NULL, &wlen, &rlen);
> + ret = exec_req(0, (struct sd_req *)&hdr, NULL, &wlen, &rlen);
>
> if (ret || rsp->result != SD_RES_SUCCESS) {
> syslog(LOG_ERR, "[%s] failed to flush vdi %"PRIx32"\n",
> @@ -337,3 +338,48 @@ int volume_create_entry(const char *entry)
>
> return 0;
> }
> +
> +static int volume_sync_and_delete(uint32_t vid)
> +{
> + struct sd_obj_req hdr = { 0 };
> + struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr;
> + int ret;
> + unsigned wlen = 0, rlen = 0;
> +
> + hdr.opcode = SD_OP_FLUSH_DEL_CACHE;
> + hdr.oid = vid_to_vdi_oid(vid);
> +
> + ret = exec_req(0, (struct sd_req *)&hdr, NULL, &wlen, &rlen);
> +
> + if (ret || rsp->result != SD_RES_SUCCESS) {
> + syslog(LOG_ERR, "[%s] failed to flush vdi %" PRIx32 "\n",
> + __func__, vid);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +int volume_remove_entry(const char *entry)
> +{
> + char path[PATH_MAX], *ch;
> + uint32_t vid;
> +
> + ch = strchr(entry, '\n');
> + if (ch != NULL)
> + *ch = '\0';
> +
> + sprintf(path, "%s/%s", PATH_VOLUME, entry);
> + if (!shadow_file_exsit(path))
> + return 0;
Should return -1?
Thanks,
Kazutaka
> +
> + if (shadow_file_getxattr(path, SH_VID_NAME, &vid, SH_VID_SIZE) < 0)
> + return -1;
> +
> + if (volume_sync_and_delete(vid) < 0)
> + return -1;
> +
> + shadow_file_delete(path);
> +
> + return 0;
> +}
> --
> 1.7.8.2
>
More information about the sheepdog
mailing list