From: levin li <xingke....@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....@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 -- sheepdog mailing list sheepdog@lists.wpkg.org http://lists.wpkg.org/mailman/listinfo/sheepdog