[sheepdog] [PATCH] collie: add command 'collie vdi reset' to reset a cloned VDI
levin li
levin108 at gmail.com
Wed Aug 29 07:57:57 CEST 2012
From: levin li <xingke.lwp at taobao.com>
With this command, we can reset a cloned VDI to its initial state as
it's just cloned from a snapshot, the usage is simple:
$ collie vdi reset cloned_vdi_name
Signed-off-by: levin li <xingke.lwp at taobao.com>
---
collie/collie.h | 1 +
collie/common.c | 35 ++++++++++++++++++++++++++++++
collie/vdi.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 99 insertions(+), 0 deletions(-)
diff --git a/collie/collie.h b/collie/collie.h
index 7f93ded..5ef2534 100644
--- a/collie/collie.h
+++ b/collie/collie.h
@@ -74,6 +74,7 @@ int sd_read_object(uint64_t oid, void *data, unsigned int datalen,
uint64_t offset);
int sd_write_object(uint64_t oid, uint64_t cow_oid, void *data, unsigned int datalen,
uint64_t offset, uint32_t flags, int copies, int create);
+int sd_remove_object(uint64_t oid, int copies);
int send_light_req(struct sd_req *hdr, const char *host, int port);
int send_light_req_get_response(struct sd_req *hdr, const char *host, int port);
diff --git a/collie/common.c b/collie/common.c
index ce8dcf7..c66c3ff 100644
--- a/collie/common.c
+++ b/collie/common.c
@@ -124,6 +124,41 @@ int sd_write_object(uint64_t oid, uint64_t cow_oid, void *data, unsigned int dat
return SD_RES_SUCCESS;
}
+int sd_remove_object(uint64_t oid, int copies)
+{
+ struct sd_req hdr;
+ struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
+ int fd, ret;
+ unsigned wlen = 0, rlen = 0;
+
+ fd = connect_to(sdhost, sdport);
+ if (fd < 0) {
+ fprintf(stderr, "Failed to connect\n");
+ return SD_RES_EIO;
+ }
+
+ sd_init_req(&hdr, SD_OP_REMOVE_OBJ);
+ hdr.epoch = sd_epoch;
+ hdr.data_length = wlen;
+ hdr.obj.copies = copies;
+ hdr.obj.oid = oid;
+
+ ret = exec_req(fd, &hdr, NULL, &wlen, &rlen);
+ close(fd);
+
+ if (ret) {
+ fprintf(stderr, "Failed to remove object %" PRIx64 "\n", oid);
+ return SD_RES_EIO;
+ }
+ if (rsp->result != SD_RES_SUCCESS) {
+ fprintf(stderr, "Failed to remove object %" PRIx64 ": %s\n", oid,
+ sd_strerror(rsp->result));
+ return rsp->result;
+ }
+
+ return SD_RES_SUCCESS;
+}
+
int parse_vdi(vdi_parser_func_t func, size_t size, void *data)
{
int ret, fd, count;
diff --git a/collie/vdi.c b/collie/vdi.c
index 7e2f5b0..4ac69db 100644
--- a/collie/vdi.c
+++ b/collie/vdi.c
@@ -753,6 +753,66 @@ static int vdi_delete(int argc, char **argv)
return EXIT_SUCCESS;
}
+static int vdi_reset(int argc, char **argv)
+{
+ char *vdiname = argv[optind++];
+ int ret, i;
+ struct sheepdog_inode inode, pinode;
+ uint32_t vid, pvid;
+
+ ret = find_vdi_name(vdiname, 0, "", &vid, 0);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to open VDI %s\n", vdiname);
+ return EXIT_FAILURE;
+ }
+
+ ret = sd_read_object(vid_to_vdi_oid(vid), &inode, sizeof(inode), 0);
+ if (ret != SD_RES_SUCCESS) {
+ fprintf(stderr, "Failed to read VDI %" PRIx32 "\n", vid);
+ return EXIT_FAILURE;
+ }
+
+ /* check whether it's a cloned VDI */
+ if (inode.snap_id != 1 || inode.parent_vdi_id == 0) {
+ fprintf(stderr, "Can not reset a non-cloned VDI\n");
+ return EXIT_FAILURE;
+ }
+
+ pvid = inode.parent_vdi_id;
+ ret = sd_read_object(vid_to_vdi_oid(pvid), &pinode, sizeof(pinode), 0);
+ if (ret != SD_RES_SUCCESS) {
+ fprintf(stderr, "Can not read parent VDI %" PRIx32 "\n", pvid);
+ return EXIT_FAILURE;
+ }
+
+ for (i = 0; i < MAX_DATA_OBJS; i++) {
+ uint64_t oid;
+
+ if (!inode.data_vdi_id[i])
+ continue;
+
+ if (!is_data_obj_writeable(&inode, i))
+ continue;
+
+ oid = vid_to_data_oid(inode.data_vdi_id[i], i);
+ ret = sd_remove_object(oid, inode.nr_copies);
+ if (ret != SD_RES_SUCCESS)
+ fprintf(stderr, "Failed to remove object %" PRIx64
+ "\n", oid);
+ }
+
+ memcpy(inode.data_vdi_id, pinode.data_vdi_id,
+ sizeof(inode.data_vdi_id));
+
+ ret = sd_write_object(vid_to_vdi_oid(vid), 0, &inode, sizeof(inode),
+ 0, 0, inode.nr_copies, 0);
+ if (ret != SD_RES_SUCCESS)
+ fprintf(stderr, "Failed to write object %" PRIx64 "\n",
+ vid_to_vdi_oid(vid));
+
+ return SD_RES_SUCCESS;
+}
+
static int vdi_object(int argc, char **argv)
{
char *vdiname = argv[optind];
@@ -1538,6 +1598,9 @@ static struct subcommand vdi_cmd[] = {
{"delete", "<vdiname>", "saph", "delete an image",
NULL, SUBCMD_FLAG_NEED_NODELIST|SUBCMD_FLAG_NEED_THIRD_ARG,
vdi_delete, vdi_options},
+ {"reset", "<vdiname>", "aph", "reset an cloned image",
+ NULL, SUBCMD_FLAG_NEED_NODELIST|SUBCMD_FLAG_NEED_THIRD_ARG,
+ vdi_reset, vdi_options},
{"list", "[vdiname]", "aprh", "list images",
NULL, SUBCMD_FLAG_NEED_NODELIST, vdi_list, vdi_options},
{"tree", NULL, "aph", "show images in tree view format",
--
1.7.1
More information about the sheepdog
mailing list