[sheepdog] [PATCH 1/2] collie: add command 'collie vdi rollback'
levin li
levin108 at gmail.com
Thu Aug 30 07:59:54 CEST 2012
From: levin li <xingke.lwp at taobao.com>
With this command we can rollback a cloned VDI to any specified
snapshot, or easily reset to its parent VDI, the usage is easy.
To rollback to a specified snapshot:
$ collie vdi rollback -s 1 base_vdi clone_vdi
To reset to its parent:
$ collie vdi rollback clone_vdi
Signed-off-by: levin li <xingke.lwp at taobao.com>
---
collie/vdi.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++
include/internal_proto.h | 1 +
2 files changed, 89 insertions(+), 0 deletions(-)
diff --git a/collie/vdi.c b/collie/vdi.c
index 2e01091..77cdd80 100644
--- a/collie/vdi.c
+++ b/collie/vdi.c
@@ -752,6 +752,91 @@ static int vdi_delete(int argc, char **argv)
return EXIT_SUCCESS;
}
+static int do_vdi_rollback(uint32_t vid, uint32_t snap_vid)
+{
+ int ret, fd;
+ struct sd_req hdr;
+ struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
+ unsigned int rlen, wlen = sizeof(vid);
+
+ fd = connect_to(sdhost, sdport);
+ if (fd < 0) {
+ fprintf(stderr, "Failed to connect to %s:%d\n",
+ sdhost, sdport);
+ return SD_RES_NETWORK_ERROR;
+ }
+
+ sd_init_req(&hdr, SD_OP_ROLLBACK_VDI);
+ hdr.vdi.base_vdi_id = snap_vid;
+ hdr.data_length = wlen;
+ hdr.flags = SD_FLAG_CMD_WRITE;
+
+ ret = exec_req(fd, &hdr, &vid, &wlen, &rlen);
+ close(fd);
+
+ if (ret) {
+ fprintf(stderr, "Failed to connect to %s:%d\n",
+ sdhost, sdport);
+ return SD_RES_NETWORK_ERROR;
+ }
+
+ return rsp->result;
+}
+
+static int vdi_rollback(int argc, char **argv)
+{
+ int ret, has_dest;
+ char *vdiname;
+ char *snap_vdiname = NULL;
+ uint32_t vid, snap_vid = 0;
+ struct sheepdog_inode inode;
+
+ if (!vdi_cmd_data.snapshot_id && !vdi_cmd_data.snapshot_tag[0]) {
+ vdiname = argv[optind++];
+ has_dest = 0;
+ } else {
+ snap_vdiname = argv[optind++];
+ vdiname = argv[optind++];
+ has_dest = 1;
+ }
+
+ ret = find_vdi_name(vdiname, 0, "", &vid, 0);
+ if (ret != SD_RES_SUCCESS) {
+ fprintf(stderr, "Failed to read VDI %s\n", vdiname);
+ return EXIT_FAILURE;
+ }
+
+ if (has_dest) {
+ ret = find_vdi_name(snap_vdiname, vdi_cmd_data.snapshot_id,
+ vdi_cmd_data.snapshot_tag, &snap_vid, 0);
+ if (ret != SD_RES_SUCCESS) {
+ fprintf(stderr, "Failed to read snapshot %s\n",
+ snap_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 object %s\n", vdiname);
+ return EXIT_FAILURE;
+ }
+
+ if (inode.snap_id != 1 || inode.parent_vdi_id == 0) {
+ fprintf(stderr, "Can not rollback a non-cloned VDI\n");
+ return EXIT_FAILURE;
+ }
+
+ if (!has_dest)
+ snap_vid = inode.parent_vdi_id;
+
+ ret = do_vdi_rollback(vid, snap_vid);
+ if (ret != SD_RES_SUCCESS)
+ return EXIT_FAILURE;
+
+ return EXIT_SUCCESS;
+}
+
static int vdi_object(int argc, char **argv)
{
char *vdiname = argv[optind];
@@ -1537,6 +1622,9 @@ static struct subcommand vdi_cmd[] = {
{"delete", "<vdiname>", "saph", "delete an image",
NULL, SUBCMD_FLAG_NEED_THIRD_ARG,
vdi_delete, vdi_options},
+ {"rollback", "<snapshot vdiname> <vdiname> ", "saph", "rollback to a snapshot",
+ NULL, SUBCMD_FLAG_NEED_THIRD_ARG,
+ vdi_rollback, vdi_options},
{"list", "[vdiname]", "aprh", "list images",
NULL, 0, vdi_list, vdi_options},
{"tree", NULL, "aph", "show images in tree view format",
diff --git a/include/internal_proto.h b/include/internal_proto.h
index c1d116a..a8b3c69 100644
--- a/include/internal_proto.h
+++ b/include/internal_proto.h
@@ -65,6 +65,7 @@
#define SD_OP_INFO_RECOVER 0xAA
#define SD_OP_GET_VDI_COPIES 0xAB
#define SD_OP_COMPLETE_RECOVERY 0xAC
+#define SD_OP_ROLLBACK_VDI 0xAD
/* internal flags for hdr.flags, must be above 0x80 */
#define SD_FLAG_CMD_RECOVERY 0x0080
--
1.7.1
More information about the sheepdog
mailing list