[sheepdog] [PATCH v2 UPDATE 2/4] erasure: support user-defined redundancy

MORITA Kazutaka morita.kazutaka at gmail.com
Fri Oct 18 20:14:40 CEST 2013


At Fri, 18 Oct 2013 02:08:48 +0800,
Liu Yuan wrote:
> 
> usage:
> $ dog vdi create -c x:y test 10g # create a erasured vdi
> 
> x represent number of data strips and y number of parity strips
> 
> x can be 2, 4, 8, 16 , 0 < y < 8 and x > y
> 
> Signed-off-by: Liu Yuan <namei.unix at gmail.com>
> ---
>  dog/common.c               |    8 ++-
>  dog/vdi.c                  |   68 +++++++++++++++----
>  include/fec.h              |   33 +++++++--
>  include/internal_proto.h   |    7 +-
>  lib/fec.c                  |   15 +++--
>  sheep/gateway.c            |   38 +++++++----
>  sheep/ops.c                |    2 +-
>  sheep/plain_store.c        |   30 +++++++--
>  sheep/recovery.c           |   47 ++++++++-----
>  tests/functional/022       |    4 +-
>  tests/functional/029       |   16 +++--
>  tests/functional/029.out   |  161 ++++++++++++++++++++++++++++++++++++++++----
>  tests/functional/031       |    2 +-
>  tests/functional/common.rc |    2 +-
>  14 files changed, 349 insertions(+), 84 deletions(-)
> 
> diff --git a/dog/common.c b/dog/common.c
> index a2fb945..028d367 100644
> --- a/dog/common.c
> +++ b/dog/common.c
> @@ -334,7 +334,11 @@ size_t get_store_objsize(uint8_t copy_policy, uint64_t oid)
>  {
>  	if (is_vdi_obj(oid))
>  		return SD_INODE_SIZE;
> -	if (copy_policy != 0)
> -		return SD_EC_OBJECT_SIZE;
> +	if (copy_policy != 0) {
> +		int d;
> +
> +		ec_policy_to_dp(copy_policy, &d, NULL);
> +		return SD_DATA_OBJ_SIZE / d;
> +	}
>  	return get_objsize(oid);
>  }
> diff --git a/dog/vdi.c b/dog/vdi.c
> index 7e0fc63..2639007 100644
> --- a/dog/vdi.c
> +++ b/dog/vdi.c
> @@ -28,10 +28,9 @@ static struct sd_option vdi_options[] = {
>  	{'x', "exclusive", false, "write in an exclusive mode"},
>  	{'d', "delete", false, "delete a key"},
>  	{'w', "writeback", false, "use writeback mode"},
> -	{'c', "copies", true, "specify the data redundancy (number of copies)"},
> +	{'c', "copies", true, "specify the data redundancy level"},
>  	{'F', "from", true, "create a differential backup from the snapshot"},
>  	{'f', "force", false, "do operation forcibly"},
> -	{'e', "erasure", false, "create erasure coded vdi"},
>  	{ 0, NULL, false, NULL },
>  };
>  
> @@ -893,7 +892,8 @@ static int vdi_object(int argc, char **argv)
>  			exit(EXIT_FAILURE);
>  		}
>  
> -		size = info.copy_policy ? SD_EC_OBJECT_SIZE : SD_DATA_OBJ_SIZE;
> +		size = get_store_objsize(info.copy_policy,
> +					 vid_to_data_oid(vid, 0));
>  		parse_objs(vid_to_vdi_oid(vid), obj_info_filler, &oid_info,
>  			   size);
>  
> @@ -1020,7 +1020,8 @@ static int vdi_track(int argc, char **argv)
>  	}
>  
>  	parse_objs(vid_to_vdi_oid(vid), obj_info_filler, &oid_info,
> -		   info.copy_policy ? SD_EC_OBJECT_SIZE : SD_DATA_OBJ_SIZE);
> +		   get_store_objsize(info.copy_policy,
> +				     vid_to_data_oid(vid, 0)));
>  
>  	if (!oid_info.success) {
>  		sd_err("Failed to read the inode object 0x%" PRIx32, vid);
> @@ -2121,7 +2122,7 @@ static struct subcommand vdi_cmd[] = {
>  	{"check", "<vdiname>", "saph", "check and repair image's consistency",
>  	 NULL, CMD_NEED_NODELIST|CMD_NEED_ARG,
>  	 vdi_check, vdi_options},
> -	{"create", "<vdiname> <size>", "Pcapherv", "create an image",
> +	{"create", "<vdiname> <size>", "Pcaphrv", "create an image",
>  	 NULL, CMD_NEED_NODELIST|CMD_NEED_ARG,
>  	 vdi_create, vdi_options},
>  	{"snapshot", "<vdiname>", "saphrv", "create a snapshot",
> @@ -2175,10 +2176,47 @@ 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 >= copy || 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;
> -	int nr_copies;
>  
>  	switch (ch) {
>  	case 'P':
> @@ -2213,13 +2251,19 @@ static int vdi_parser(int ch, const char *opt)
>  		vdi_cmd_data.writeback = true;
>  		break;
>  	case 'c':
> -		nr_copies = strtol(opt, &p, 10);
> -		if (opt == p || nr_copies < 0 || nr_copies > SD_MAX_COPIES) {
> -			sd_err("Invalid copies number, must be "
> -			       "an integer between 0 and %d", SD_MAX_COPIES);
> +		vdi_cmd_data.nr_copies = parse_copy(opt,
> +						    &vdi_cmd_data.copy_policy);
> +		if (!vdi_cmd_data.nr_copies) {
> +			sd_err("Invalid parameter %s\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\n"
> +			       "and meet the condition x > y\n"
> +			       "To create replicated vdi, set -c x\n"
> +			       "  x(0 < x <= %d) - number of replicated copies",
> +			       opt, SD_MAX_COPIES);

I'd suggest we explain the case of creating replicated vdi first since
it's a simpler option.

Thanks,

Kazutaka



More information about the sheepdog mailing list