From: Yu Yang <[email protected]>

Rollback a working VDI to it's early snapshot

Signed-off-by: Yu Yang <[email protected]>
---
 lib/shared/sheepdog.h |   11 +++++++++++
 lib/shared/vdi.c      |   52 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/lib/shared/sheepdog.h b/lib/shared/sheepdog.h
index 5abf4c2..47bae6f 100644
--- a/lib/shared/sheepdog.h
+++ b/lib/shared/sheepdog.h
@@ -173,4 +173,15 @@ int sd_vdi_clone(struct sd_cluster *c, char *srcname,
  */
 int sd_vdi_delete(struct sd_cluster *c, char *name, char *tag);
 
+/*
+ * Rollback a VDI from it's early snapshot
+ *
+ * @c: pointer to the cluster descriptor
+ * @name: the name of the VDI to be deleted
+ * @tag: the snapshot tag of the VDI
+ *
+ * Return error code defined in sheepdog_proto.h
+ */
+int sd_vdi_rollback(struct sd_cluster *c, char *name, char *tag);
+
 #endif
diff --git a/lib/shared/vdi.c b/lib/shared/vdi.c
index 776c14b..d99685a 100644
--- a/lib/shared/vdi.c
+++ b/lib/shared/vdi.c
@@ -568,3 +568,55 @@ out:
        free(inode);
        return ret;
 }
+
+int sd_vdi_rollback(struct sd_cluster *c, char *name, char *tag)
+{
+       int ret;
+       char buf[SD_INODE_HEADER_SIZE];
+       struct sd_inode *inode = (struct sd_inode *)buf;
+
+       if (!tag || *tag == '\0') {
+               fprintf(stderr, "Snapshot tag can NOT be null for rollback\n");
+               return SD_RES_INVALID_PARMS;
+       }
+       if (!name || *name == '\0') {
+               fprintf(stderr, "VDI name can NOT be null\n");
+               return SD_RES_INVALID_PARMS;
+       }
+
+       ret = find_vdi(c, name, NULL, NULL);
+       if (ret != SD_RES_SUCCESS) {
+               fprintf(stderr, "Working VDI %s does NOT exist\n", name);
+               return SD_RES_INVALID_PARMS;
+       }
+       ret = find_vdi(c, name, tag, NULL);
+       if (ret != SD_RES_SUCCESS) {
+               fprintf(stderr, "Snapshot VDI %s(tag: %s) does NOT exist\n",
+                               name, tag);
+               return SD_RES_INVALID_PARMS;
+       }
+
+       ret = vdi_read_inode(c, name, tag, inode, true);
+       if (ret != SD_RES_SUCCESS) {
+               fprintf(stderr, "Read inode for VDI %s failed: %s\n",
+                               name, sd_strerror(ret));
+               return ret;
+       }
+
+       ret = sd_vdi_delete(c, name, NULL);
+       if (ret != SD_RES_SUCCESS) {
+               fprintf(stderr, "Failed to delete current VDI state: %s\n",
+                               sd_strerror(ret));
+               return ret;
+       }
+
+       ret = do_vdi_create(c, name, inode->vdi_size, inode->vdi_id,
+                       false, inode->nr_copies, inode->copy_policy,
+                       inode->store_policy, inode->block_size_shift);
+
+       if (ret != SD_RES_SUCCESS)
+               fprintf(stderr, "Failed to rollback VDI: %s\n",
+                               sd_strerror(ret));
+
+       return ret;
+}
-- 
1.7.9.5

-- 
sheepdog mailing list
[email protected]
https://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to