[sheepdog] [PATCH 2/2] sheep: add VDI rollback function support
levin li
levin108 at gmail.com
Thu Aug 30 07:59:55 CEST 2012
From: levin li <xingke.lwp at taobao.com>
Signed-off-by: levin li <xingke.lwp at taobao.com>
---
sheep/ops.c | 13 ++++++++
sheep/sheep_priv.h | 1 +
sheep/vdi.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 97 insertions(+), 0 deletions(-)
diff --git a/sheep/ops.c b/sheep/ops.c
index ccb1c5e..e35e96f 100644
--- a/sheep/ops.c
+++ b/sheep/ops.c
@@ -353,6 +353,13 @@ static int cluster_get_vdi_attr(struct request *req)
return ret;
}
+static int cluster_rollback_vdi(struct request *req)
+{
+ uint32_t vid = *(uint32_t *)req->data;
+
+ return rollback_vdi(vid, req->rq.vdi.base_vdi_id);
+}
+
static int local_get_store_list(struct request *req)
{
struct strbuf buf = STRBUF_INIT;
@@ -956,6 +963,12 @@ static struct sd_op_template sd_ops[] = {
.type = SD_OP_TYPE_CLUSTER,
},
+ [SD_OP_ROLLBACK_VDI] = {
+ .name = "ROLLBACK_VDI",
+ .type = SD_OP_TYPE_CLUSTER,
+ .process_work = cluster_rollback_vdi,
+ },
+
[SD_OP_FORCE_RECOVER] = {
.name = "FORCE_RECOVER",
.type = SD_OP_TYPE_CLUSTER,
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index 90006f6..38b66ad 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -230,6 +230,7 @@ int lookup_vdi(char *name, char *tag, uint32_t *vid, uint32_t snapid,
unsigned int *nr_copies, uint64_t *ctime);
int read_vdis(char *data, int len, unsigned int *rsp_len);
+int rollback_vdi(uint32_t vid, uint32_t snap_vid);
int get_vdi_attr(struct sheepdog_vdi_attr *vattr, int data_len, uint32_t vid,
uint32_t *attrid, uint64_t ctime, int write,
diff --git a/sheep/vdi.c b/sheep/vdi.c
index f7e762f..36bfa4e 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -513,6 +513,89 @@ out:
return ret;
}
+int rollback_vdi(uint32_t vid, uint32_t snap_vid)
+{
+ int ret, i;
+ struct sheepdog_inode *inode, *snap_inode;
+
+ dprintf("%" PRIx32 ", %" PRIx32 "\n", vid, snap_vid);
+
+ inode = xzalloc(sizeof(*inode));
+ snap_inode = xzalloc(sizeof(*snap_inode));
+
+ ret = read_object(vid_to_vdi_oid(vid), (char *)inode,
+ sizeof(*inode), 0, 0);
+ if (ret != SD_RES_SUCCESS) {
+ eprintf("failed to read VDI %" PRIx32 "\n", vid);
+ ret = SD_RES_NO_VDI;
+ goto out;
+ }
+
+ ret = read_object(vid_to_vdi_oid(snap_vid), (char *)snap_inode,
+ sizeof(*snap_inode), 0, 0);
+ if (ret != SD_RES_SUCCESS) {
+ eprintf("failed to read VDI %" PRIx32 "\n", snap_vid);
+ ret = SD_RES_NO_BASE_VDI;
+ goto out;
+ }
+
+ if (inode->parent_vdi_id == snap_vid)
+ goto reset_child;
+
+ for (i = 0; i < ARRAY_SIZE(snap_inode->child_vdi_id); i++) {
+ if (!snap_inode->child_vdi_id[i]) {
+ snap_inode->child_vdi_id[i] = vid;
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(snap_inode->child_vdi_id)) {
+ eprintf("failed to set child vdi id(%" PRIx32 ") for %"
+ PRIx32 "\n", vid, snap_vid);
+ ret = SD_RES_NO_BASE_VDI;
+ goto out;
+ }
+
+ ret = write_object(vid_to_vdi_oid(snap_vid), (char *)snap_inode,
+ sizeof(*snap_inode), 0, 0, 0, snap_inode->nr_copies);
+ if (ret != SD_RES_SUCCESS) {
+ eprintf("failed to write snapshot VDI %" PRIx32 "\n",
+ snap_vid);
+ goto out;
+ }
+
+ inode->parent_vdi_id = snap_inode->vdi_id;
+
+reset_child:
+ for (i = 0; i < MAX_DATA_OBJS; i++) {
+ uint64_t oid;
+
+ if (!inode->data_vdi_id[i])
+ continue;
+
+ if (inode->data_vdi_id[i] != vid)
+ continue;
+
+ oid = vid_to_data_oid(inode->data_vdi_id[i], i);
+ ret = remove_object(oid, inode->nr_copies);
+ if (ret != SD_RES_SUCCESS)
+ eprintf("failed to remove object %" PRIx64 "\n", oid);
+ }
+
+ memcpy(inode->data_vdi_id, snap_inode->data_vdi_id,
+ sizeof(inode->data_vdi_id));
+ inode->vdi_size = snap_inode->vdi_size;
+
+ ret = write_object(vid_to_vdi_oid(vid), (char *)inode, sizeof(*inode),
+ 0, 0, 0, inode->nr_copies);
+ if (ret != SD_RES_SUCCESS)
+ eprintf("failed to write VDI %" PRIx32 "\n", vid);
+
+out:
+ free(inode);
+ free(snap_inode);
+ return ret;
+}
+
int read_vdis(char *data, int len, unsigned int *rsp_len)
{
if (len != sizeof(sys->vdi_inuse))
--
1.7.1
More information about the sheepdog
mailing list