[sheepdog] [PATCH v2 1/2] dog: enable 'cluster format -c x:y'

Liu Yuan namei.unix at gmail.com
Thu Nov 14 06:45:47 CET 2013


This patch enables 'cluster format -c x:y' option for users to set a
cluster-wide default scheme.

Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
 dog/cluster.c            |   25 +++++++++++++------------
 dog/common.c             |   38 ++++++++++++++++++++++++++++++++++++++
 dog/dog.h                |    1 +
 dog/vdi.c                |   38 --------------------------------------
 include/internal_proto.h |    1 +
 sheep/config.c           |    5 ++++-
 sheep/ops.c              |   10 ++++++++--
 7 files changed, 65 insertions(+), 53 deletions(-)

diff --git a/dog/cluster.c b/dog/cluster.c
index c2f97ad..b455602 100644
--- a/dog/cluster.c
+++ b/dog/cluster.c
@@ -26,7 +26,8 @@ static struct sd_option cluster_options[] = {
 };
 
 static struct cluster_cmd_data {
-	int copies;
+	uint8_t copies;
+	uint8_t copy_policy;
 	bool force;
 	char name[STORE_LEN];
 } cluster_cmd_data;
@@ -97,6 +98,7 @@ static int cluster_format(int argc, char **argv)
 
 	sd_init_req(&hdr, SD_OP_MAKE_FS);
 	hdr.cluster.copies = cluster_cmd_data.copies;
+	hdr.cluster.copy_policy = cluster_cmd_data.copy_policy;
 	hdr.cluster.ctime = (uint64_t) tv.tv_sec << 32 | tv.tv_usec * 1000;
 
 	if (strlen(cluster_cmd_data.name))
@@ -517,25 +519,24 @@ static struct subcommand cluster_cmd[] = {
 
 static int cluster_parser(int ch, const char *opt)
 {
-	int copies;
-	char *p;
-
 	switch (ch) {
 	case 'b':
 		pstrcpy(cluster_cmd_data.name, sizeof(cluster_cmd_data.name),
 			opt);
 		break;
 	case 'c':
-		copies = strtol(opt, &p, 10);
-		if (opt == p || copies < 1) {
-			sd_err("There must be at least one copy of data");
-			exit(EXIT_FAILURE);
-		} else if (copies > SD_MAX_COPIES) {
-			sd_err("Redundancy may not exceed %d copies",
-			       SD_MAX_COPIES);
+		cluster_cmd_data.copies =
+			parse_copy(opt, &cluster_cmd_data.copy_policy);
+		if (!cluster_cmd_data.copies) {
+			sd_err("Invalid parameter %s\n"
+			       "To create replicated vdi, set -c x\n"
+			       "  x(1 to %d)   - number of replicated copies\n"
+			       "To create erasure coded vdi, set -c x:y\n"
+			       "  x(2,4,8,16)  - number of data strips\n"
+			       "  y(1 to 15)   - number of parity strips",
+			       opt, SD_MAX_COPIES);
 			exit(EXIT_FAILURE);
 		}
-		cluster_cmd_data.copies = copies;
 		break;
 	case 'f':
 		cluster_cmd_data.force = true;
diff --git a/dog/common.c b/dog/common.c
index 8c9b326..cd1692a 100644
--- a/dog/common.c
+++ b/dog/common.c
@@ -438,3 +438,41 @@ void dump_loglevels(bool err)
 			sd_info("%s\t(%d)", loglevel_table[i], i);
 	}
 }
+
+/* Return 0 to indicate ill str */
+uint8_t parse_copy(const char *str, uint8_t *copy_policy)
+{
+	char *n1, *n2;
+	uint8_t copy, parity;
+	char p[10];
+
+	strcpy(p, str);
+	n1 = strtok(p, ":");
+	n2 = strtok(NULL, ":");
+
+	if ((!n1 || !is_numeric(n1)) || (n2 && !is_numeric(n2)))
+		return 0;
+
+	copy = strtol(n1, NULL, 10);
+	if (copy > SD_MAX_COPIES)
+		return 0;
+	if (!n2) {
+		*copy_policy = 0;
+		return copy;
+	}
+
+	if (copy != 2 && copy != 4 && copy != 8 && copy != 16)
+		return 0;
+
+	parity = strtol(n2, NULL, 10);
+	if (parity >= SD_EC_MAX_STRIP || parity == 0)
+		return 0;
+
+	/*
+	 * 4 bits for parity and 4 bits for data.
+	 * We have to compress upper data bits because it can't represent 16
+	 */
+	*copy_policy = ((copy / 2) << 4) + parity;
+	copy = copy + parity;
+	return copy;
+}
diff --git a/dog/dog.h b/dog/dog.h
index 28c36a1..ecf873a 100644
--- a/dog/dog.h
+++ b/dog/dog.h
@@ -84,6 +84,7 @@ int do_vdi_check(const struct sd_inode *inode);
 void show_progress(uint64_t done, uint64_t total, bool raw);
 size_t get_store_objsize(uint8_t copy_policy, uint64_t oid);
 bool is_erasure_oid(uint64_t oid, uint8_t policy);
+uint8_t parse_copy(const char *str, uint8_t *copy_policy);
 
 extern struct command vdi_command;
 extern struct command node_command;
diff --git a/dog/vdi.c b/dog/vdi.c
index 124fef4..7a4d64b 100644
--- a/dog/vdi.c
+++ b/dog/vdi.c
@@ -2335,44 +2335,6 @@ static struct subcommand vdi_cmd[] = {
 	{NULL,},
 };
 
-/* Return 0 to indicate ill str */
-static uint8_t parse_copy(const char *str, uint8_t *copy_policy)
-{
-	char *n1, *n2;
-	uint8_t copy, parity;
-	char p[10];
-
-	strcpy(p, str);
-	n1 = strtok(p, ":");
-	n2 = strtok(NULL, ":");
-
-	if ((n1 && !is_numeric(n1)) || (n2 && !is_numeric(n2)))
-		return 0;
-
-	copy = strtol(n1, NULL, 10);
-	if (copy > SD_MAX_COPIES)
-		return 0;
-	if (!n2) {
-		*copy_policy = 0;
-		return copy;
-	}
-
-	if (copy != 2 && copy != 4 && copy != 8 && copy != 16)
-		return 0;
-
-	parity = strtol(n2, NULL, 10);
-	if (parity >= SD_EC_MAX_STRIP || parity == 0)
-		return 0;
-
-	/*
-	 * 4 bits for parity and 4 bits for data.
-	 * We have to compress upper data bits because it can't represent 16
-	 */
-	*copy_policy = ((copy / 2) << 4) + parity;
-	copy = copy + parity;
-	return copy;
-}
-
 static int vdi_parser(int ch, const char *opt)
 {
 	char *p;
diff --git a/include/internal_proto.h b/include/internal_proto.h
index c6eecaf..e5e0f05 100644
--- a/include/internal_proto.h
+++ b/include/internal_proto.h
@@ -162,6 +162,7 @@ struct cluster_info {
 	uint64_t ctime;
 	uint16_t flags;
 	uint8_t nr_copies;
+	uint8_t copy_policy;
 	enum sd_status status : 8;
 	uint32_t __pad;
 	uint8_t store[STORE_LEN];
diff --git a/sheep/config.c b/sheep/config.c
index 5913c3b..22c6cfe 100644
--- a/sheep/config.c
+++ b/sheep/config.c
@@ -20,7 +20,8 @@ static struct sheepdog_config {
 	uint8_t copies;
 	uint8_t store[STORE_LEN];
 	uint8_t shutdown;
-	uint8_t __pad[2];
+	uint8_t copy_policy;
+	uint8_t __pad;
 	uint16_t version;
 	uint64_t space;
 } config;
@@ -62,6 +63,7 @@ static int get_cluster_config(struct cluster_info *cinfo)
 	cinfo->ctime = config.ctime;
 	cinfo->nr_copies = config.copies;
 	cinfo->flags = config.flags;
+	cinfo->copy_policy = config.copy_policy;
 	memcpy(cinfo->store, config.store, sizeof(config.store));
 
 	return SD_RES_SUCCESS;
@@ -141,6 +143,7 @@ int set_cluster_config(const struct cluster_info *cinfo)
 {
 	config.ctime = cinfo->ctime;
 	config.copies = cinfo->nr_copies;
+	config.copy_policy = cinfo->copy_policy;
 	config.flags = cinfo->flags;
 	memset(config.store, 0, sizeof(config.store));
 	pstrcpy((char *)config.store, sizeof(config.store),
diff --git a/sheep/ops.c b/sheep/ops.c
index b715af6..de0a563 100644
--- a/sheep/ops.c
+++ b/sheep/ops.c
@@ -84,11 +84,16 @@ static int cluster_new_vdi(struct request *req)
 		.base_vid = hdr->vdi.base_vdi_id,
 		.create_snapshot = !!hdr->vdi.snapid,
 		.copy_policy = hdr->vdi.copy_policy,
-		.nr_copies = hdr->vdi.copies ? hdr->vdi.copies :
-				sys->cinfo.nr_copies,
+		.nr_copies = hdr->vdi.copies,
 		.time = (uint64_t) tv.tv_sec << 32 | tv.tv_usec * 1000,
 	};
 
+	/* Client doesn't specify redundancy scheme (copy = 0) */
+	if (!hdr->vdi.copies) {
+		iocb.nr_copies = sys->cinfo.nr_copies;
+		iocb.copy_policy = sys->cinfo.copy_policy;
+	}
+
 	if (iocb.copy_policy)
 		iocb.nr_copies = ec_policy_to_dp(iocb.copy_policy, NULL, NULL);
 
@@ -264,6 +269,7 @@ static int cluster_make_fs(const struct sd_req *req, struct sd_rsp *rsp,
 		return ret;
 
 	sys->cinfo.nr_copies = req->cluster.copies;
+	sys->cinfo.copy_policy = req->cluster.copy_policy;
 	sys->cinfo.flags = req->flags;
 	if (!sys->cinfo.nr_copies)
 		sys->cinfo.nr_copies = SD_DEFAULT_COPIES;
-- 
1.7.9.5




More information about the sheepdog mailing list