[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