Current "dog vdi snapshot" command creates a new snapshot
unconditionally, even if a working VDI doesn't have its own
objects. In such a case, the created snapshot is redundant because
same VDI is already existing.

This patch adds a new option -R to the dog command for reducing
the identical snapshots.

Signed-off-by: Hitoshi Mitake <mitake.hito...@lab.ntt.co.jp>
---
 dog/vdi.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/dog/vdi.c b/dog/vdi.c
index 8e612af..ee465c2 100644
--- a/dog/vdi.c
+++ b/dog/vdi.c
@@ -40,6 +40,8 @@ static struct sd_option vdi_options[] = {
         "                          neither comparing nor repairing"},
        {'z', "block_size_shift", true, "specify the bit shift num for"
                               " data object size"},
+       {'R', "reduce-identical-snapshots", false, "do not create snapshot if "
+        "working VDI doesn't have its own objects"},
        { 0, NULL, false, NULL },
 };
 
@@ -61,6 +63,7 @@ static struct vdi_cmd_data {
        uint64_t oid;
        bool no_share;
        bool exist;
+       bool reduce_identical_snapshots;
 } vdi_cmd_data = { ~0, };
 
 struct get_vdi_info {
@@ -605,6 +608,31 @@ fail:
        return NULL;
 }
 
+static bool has_own_objects(uint32_t vid, int *ret)
+{
+       struct sd_inode *inode;
+       bool result = true;
+
+       inode = xzalloc(sizeof(*inode));
+
+       *ret = dog_read_object(vid_to_vdi_oid(vid), inode,
+                             sizeof(*inode), 0, true);
+       if (*ret != SD_RES_SUCCESS)
+               goto out;
+
+       for (int i = 0; i < SD_INODE_DATA_INDEX; i++) {
+               if (inode->data_vdi_id[i] && inode->data_vdi_id[i] == vid)
+                       /* VDI has its own object */
+                       goto out;
+       }
+
+       result = false;
+
+out:
+       free(inode);
+       return result;
+}
+
 static int vdi_snapshot(int argc, char **argv)
 {
        const char *vdiname = argv[optind++];
@@ -703,6 +731,22 @@ static int vdi_snapshot(int argc, char **argv)
                nr_issued_prevent_inode_update++;
        }
 
+       if (vdi_cmd_data.reduce_identical_snapshots) {
+               bool result = has_own_objects(vid, &ret);
+
+               if (ret != SD_RES_SUCCESS)
+                       goto out;
+
+               if (!result) {
+                       if (verbose)
+                               sd_info("VDI %s doesn't have its own objects, "
+                                       "skipping creation of snapshot",
+                                       vdiname);
+
+                       goto out;
+               }
+       }
+
        ret = dog_write_object(vid_to_vdi_oid(vid), 0,
                               vdi_cmd_data.snapshot_tag,
                               SD_MAX_VDI_TAG_LEN,
@@ -3057,7 +3101,7 @@ static struct subcommand vdi_cmd[] = {
        {"create", "<vdiname> <size>", "PycaphrvzT", "create an image",
         NULL, CMD_NEED_NODELIST|CMD_NEED_ARG,
         vdi_create, vdi_options},
-       {"snapshot", "<vdiname>", "saphrvT", "create a snapshot",
+       {"snapshot", "<vdiname>", "saphrvTR", "create a snapshot",
         NULL, CMD_NEED_ARG,
         vdi_snapshot, vdi_options},
        {"clone", "<src vdi> <dst vdi>", "sPnaphrvT", "clone an image",
@@ -3222,6 +3266,8 @@ static int vdi_parser(int ch, const char *opt)
                }
                vdi_cmd_data.block_size_shift = block_size_shift;
                break;
+       case 'R':
+               vdi_cmd_data.reduce_identical_snapshots = true;
        }
 
        return 0;
-- 
1.9.1

-- 
sheepdog mailing list
sheepdog@lists.wpkg.org
https://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to