[Sheepdog] [PATCH v2 10/15] sheepfs: teach volumes to unmount
Liu Yuan
namei.unix at gmail.com
Mon May 14 11:47:35 CEST 2012
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;
+
+ 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