[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