[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