[sheepdog] [PATCH v2 1/2] dog: add a new option for reducing identical snapshots

Hitoshi Mitake mitake.hitoshi at lab.ntt.co.jp
Thu Feb 12 09:26:59 CET 2015


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.

Motivations:
1. why we need it in dog command instead of combination of parsing
   "dog vdi list" and existing "dog vdi snapshot"?
"dog vdi list" tends to be slow in a cluster which has thousands of
VDIs because it issues bunch of read requests for inode headers. It
should be avoided as much as possible.
2. why identical snapshots harmful?
Creating identical snapshots means increasing a number of inode
objects (especially in EC, 16:4 VDI creates 20 inodes). It harms
performance of recovery process. And exhaustion of VID space will come
early.

Signed-off-by: Hitoshi Mitake <mitake.hitoshi at lab.ntt.co.jp>
---
 dog/vdi.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)

v2:
 - use conventional style for has_own_objects()
 - enhance commit log

diff --git a/dog/vdi.c b/dog/vdi.c
index 66f2801..aa6c38d 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 {
@@ -606,6 +609,32 @@ fail:
 	return NULL;
 }
 
+static int has_own_objects(uint32_t vid, bool *result)
+{
+	struct sd_inode *inode;
+	int ret = SD_RES_SUCCESS;
+
+	*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 ret;
+}
+
 static int vdi_snapshot(int argc, char **argv)
 {
 	const char *vdiname = argv[optind++];
@@ -704,6 +733,23 @@ static int vdi_snapshot(int argc, char **argv)
 		nr_issued_prevent_inode_update++;
 	}
 
+	if (vdi_cmd_data.reduce_identical_snapshots) {
+		bool result;
+		ret = has_own_objects(vid, &result);
+
+		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,
@@ -3066,7 +3112,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",
@@ -3231,6 +3277,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




More information about the sheepdog mailing list