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 > |