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 <[email protected]> --- 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 | 157 ++++++++++++++++++++++++++++++++++++++++---- tests/functional/031 | 2 +- tests/functional/common.rc | 2 +- 14 files changed, 345 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); exit(EXIT_FAILURE); } - vdi_cmd_data.nr_copies = nr_copies; break; case 'F': vdi_cmd_data.from_snapshot_id = strtol(opt, &p, 10); @@ -2232,8 +2276,6 @@ static int vdi_parser(int ch, const char *opt) case 'f': vdi_cmd_data.force = true; break; - case 'e': - vdi_cmd_data.copy_policy = 1; } return 0; diff --git a/include/fec.h b/include/fec.h index 55e0bdb..78b3fc8 100644 --- a/include/fec.h +++ b/include/fec.h @@ -1,3 +1,6 @@ +#ifndef __FEC_H__ +#define __FEC_H__ + /* * zfec -- fast forward error correction library * @@ -59,6 +62,8 @@ #include <stddef.h> #include <stdint.h> +#include "util.h" + struct fec { unsigned long magic; unsigned short d, dp; /* parameters of the code */ @@ -101,12 +106,8 @@ void fec_decode(const struct fec *code, uint8_t *const *const outpkts, const int *const index, size_t sz); -#define SD_EC_D 4 /* No. of data strips */ -#define SD_EC_P 2 /* No. of parity strips */ -#define SD_EC_DP (SD_EC_D + SD_EC_P) - /* - * SD_EC_D_SIZE <= 1K is the safe value to run VM after some experimentations. + * data stripe <= 1K is the safe value to run VM after some experimentations. * * Though most OS's file system will operate on 4K block, some softwares like * grub will operate on 512 bytes and Linux kernel itself will sometimes @@ -115,8 +116,26 @@ void fec_decode(const struct fec *code, * VM to run on erasure coded volume. */ #define SD_EC_DATA_STRIPE_SIZE (1024) /* 1K */ -#define SD_EC_OBJECT_SIZE (SD_DATA_OBJ_SIZE / SD_EC_D) #define SD_EC_NR_STRIPE_PER_OBJECT (SD_DATA_OBJ_SIZE / SD_EC_DATA_STRIPE_SIZE) +#define SD_EC_MAX_STRIP (16) + +static inline int ec_policy_to_dp(uint8_t policy, int *d, int *p) +{ + int ed = 0, ep = 0; + + ep = policy & 0b1111; + ed = policy >> 4; + + if(unlikely(!ep)) + panic("invalid policy %d", policy); + + if (d) + *d = ed * 2; + if (p) + *p = ep; + + return ed * 2 + ep; +} /* * Stripe: data strips + parity strips, spread on all replica @@ -176,3 +195,5 @@ static inline void ec_destroy(struct fec *ctx) { fec_free(ctx); } + +#endif diff --git a/include/internal_proto.h b/include/internal_proto.h index 59c6e2a..8a23737 100644 --- a/include/internal_proto.h +++ b/include/internal_proto.h @@ -22,11 +22,16 @@ #include "sheepdog_proto.h" #include "rbtree.h" +#include "fec.h" #define SD_SHEEP_PROTO_VER 0x08 #define SD_DEFAULT_COPIES 3 -#define SD_MAX_COPIES 8 +/* + * For erasure coding, we use at most SD_EC_MAX_STRIP for data strips and + * (SD_EC_MAX_STRIP - 1) for parity strips + */ +#define SD_MAX_COPIES (SD_EC_MAX_STRIP * 2 - 1) /* * The max number of nodes sheep daemon can support is constrained by diff --git a/lib/fec.c b/lib/fec.c index 05dffa0..d5188b6 100644 --- a/lib/fec.c +++ b/lib/fec.c @@ -636,11 +636,18 @@ void ec_decode(struct fec *ctx, const uint8_t *input[], const int inidx[], int strip_size = SD_EC_DATA_STRIPE_SIZE / ed; uint8_t m0[strip_size], m1[strip_size], m2[strip_size], m3[strip_size], m4[strip_size], m5[strip_size], m6[strip_size], m7[strip_size], + m8[strip_size], m9[strip_size], m10[strip_size], + m11[strip_size],m12[strip_size], m13[strip_size], + m14[strip_size], m15[strip_size], p0[strip_size], p1[strip_size], p2[strip_size], p3[strip_size], - p4[strip_size], p5[strip_size], p6[strip_size], p7[strip_size]; -#define SD_EC_MAX_PARITY 8 - uint8_t *missing[SD_EC_MAX_PARITY] = { m0, m1, m2, m3, m4, m5, m6, m7 }; - uint8_t *p[SD_EC_MAX_PARITY] = { p0, p1, p2, p3, p4, p5, p6, p7 }; + p4[strip_size], p5[strip_size], p6[strip_size], p7[strip_size], + p8[strip_size], p9[strip_size], p10[strip_size], + p11[strip_size],p12[strip_size], p13[strip_size], + p14[strip_size]; + uint8_t *missing[SD_EC_MAX_STRIP] = { m0, m1, m2, m3, m4, m5, m6, m7, + m8, m9, m10, m11, m12, m13, m14, m15 }; + uint8_t *p[SD_EC_MAX_STRIP - 1] = { p0, p1, p2, p3, p4, p5, p6, p7, p8, + p9, p10, p11, p12, p13, p14 }; for (i = 0; i < edp; i++) dp[i] = NULL; diff --git a/sheep/gateway.c b/sheep/gateway.c index 4d7e0e2..e2e5a21 100644 --- a/sheep/gateway.c +++ b/sheep/gateway.c @@ -112,16 +112,23 @@ static struct req_iter *prepare_erasure_requests(struct request *req, int *nr) int start = off / SD_EC_DATA_STRIPE_SIZE; int end = DIV_ROUND_UP(off + len, SD_EC_DATA_STRIPE_SIZE), i, j; int nr_stripe = end - start; - struct fec *ctx = ec_init(SD_EC_D, SD_EC_DP); - int nr_to_send = (opcode == SD_OP_READ_OBJ) ? SD_EC_D : SD_EC_DP; - int strip_size = SD_EC_DATA_STRIPE_SIZE / SD_EC_D; - struct req_iter *reqs = xzalloc(sizeof(*reqs) * nr_to_send); + struct fec *ctx; + int strip_size, nr_to_send; + struct req_iter *reqs; char *p, *buf = NULL; + uint8_t policy = req->rq.obj.copy_policy ?: + get_vdi_copy_policy(oid_to_vid(req->rq.obj.oid)); + int ed = 0, ep = 0, edp; + + edp = ec_policy_to_dp(policy, &ed, &ep); + ctx = ec_init(ed, edp); + *nr = nr_to_send = (opcode == SD_OP_READ_OBJ) ? ed : edp; + strip_size = SD_EC_DATA_STRIPE_SIZE / ed; + reqs = xzalloc(sizeof(*reqs) * nr_to_send); sd_debug("start %d, end %d, send %d, off %"PRIu64 ", len %"PRIu32, start, end, nr_to_send, off, len); - *nr = nr_to_send; for (i = 0; i < nr_to_send; i++) { int l = strip_size * nr_stripe; @@ -150,16 +157,16 @@ static struct req_iter *prepare_erasure_requests(struct request *req, int *nr) goto out; } for (i = 0; i < nr_stripe; i++) { - const uint8_t *ds[SD_EC_D]; - uint8_t *ps[SD_EC_P]; + const uint8_t *ds[ed]; + uint8_t *ps[ep]; - for (j = 0; j < SD_EC_D; j++) + for (j = 0; j < ed; j++) ds[j] = reqs[j].buf + strip_size * i; - for (j = 0; j < SD_EC_P; j++) - ps[j] = reqs[SD_EC_D + j].buf + strip_size * i; + for (j = 0; j < ep; j++) + ps[j] = reqs[ed + j].buf + strip_size * i; - for (j = 0; j < SD_EC_D; j++) + for (j = 0; j < ed; j++) memcpy((uint8_t *)ds[j], p + j * strip_size, strip_size); ec_encode(ctx, ds, ps); @@ -218,7 +225,7 @@ static void finish_requests(struct request *req, struct req_iter *reqs, int end = DIV_ROUND_UP(off + len, SD_EC_DATA_STRIPE_SIZE), i, j; int nr_stripe = end - start; - if (!is_erasure_oid(oid)) + if (!is_erasure_obj(oid, req->rq.obj.copy_policy)) goto out; sd_debug("start %d, end %d, send %d, off %"PRIu64 ", len %"PRIu32, @@ -227,7 +234,12 @@ static void finish_requests(struct request *req, struct req_iter *reqs, /* We need to assemble the data strips into the req buffer for read */ if (opcode == SD_OP_READ_OBJ) { char *p, *buf = xmalloc(SD_EC_DATA_STRIPE_SIZE * nr_stripe); - int strip_size = SD_EC_DATA_STRIPE_SIZE / SD_EC_D; + uint8_t policy = req->rq.obj.copy_policy ?: + get_vdi_copy_policy(oid_to_vid(req->rq.obj.oid)); + int ed = 0, strip_size; + + ec_policy_to_dp(policy, &ed, NULL); + strip_size = SD_EC_DATA_STRIPE_SIZE / ed; p = buf; for (i = 0; i < nr_stripe; i++) { diff --git a/sheep/ops.c b/sheep/ops.c index e39a21b..ab1a40d 100644 --- a/sheep/ops.c +++ b/sheep/ops.c @@ -90,7 +90,7 @@ static int cluster_new_vdi(struct request *req) }; if (iocb.copy_policy) - iocb.nr_copies = SD_EC_DP; + iocb.nr_copies = ec_policy_to_dp(iocb.copy_policy, NULL, NULL); if (hdr->data_length != SD_MAX_VDI_LEN) return SD_RES_INVALID_PARMS; diff --git a/sheep/plain_store.c b/sheep/plain_store.c index 7d8b5d0..fde7c9f 100644 --- a/sheep/plain_store.c +++ b/sheep/plain_store.c @@ -330,8 +330,12 @@ int prealloc(int fd, uint32_t size) size_t get_store_objsize(uint64_t oid) { - if (is_erasure_oid(oid)) - return SD_EC_OBJECT_SIZE; + if (is_erasure_oid(oid)) { + uint8_t policy = get_vdi_copy_policy(oid_to_vid(oid)); + int d; + ec_policy_to_dp(policy, &d, NULL); + return SD_DATA_OBJ_SIZE / d; + } return get_objsize(oid); } @@ -342,6 +346,7 @@ int default_create_and_write(uint64_t oid, const struct siocb *iocb) int ret, fd; uint32_t len = iocb->length; bool ec = is_erasure_obj(oid, iocb->copy_policy); + size_t obj_size; sd_debug("%"PRIx64, oid); get_obj_path(oid, path, sizeof(path)); @@ -375,7 +380,16 @@ int default_create_and_write(uint64_t oid, const struct siocb *iocb) return err_to_sderr(path, oid, errno); } - ret = prealloc(fd, ec ? SD_EC_OBJECT_SIZE : get_objsize(oid)); + if (ec) { + uint8_t policy = iocb->copy_policy ?: + get_vdi_copy_policy(oid_to_vid(oid)); + int d; + ec_policy_to_dp(policy, &d, NULL); + obj_size = SD_DATA_OBJ_SIZE / d; + } else + obj_size = get_objsize(oid); + + ret = prealloc(fd, obj_size); if (ret < 0) { ret = err_to_sderr(path, oid, errno); goto out; @@ -447,7 +461,6 @@ static bool oid_stale(uint64_t oid) const struct sd_vnode *v; bool ret = true; const struct sd_vnode *obj_vnodes[SD_MAX_COPIES]; - vinfo = get_vnode_info(); /* @@ -455,8 +468,13 @@ static bool oid_stale(uint64_t oid) * know it is stale or not. In this case, we keep it stay in the working * directory in order to recover it when we get enough zones */ - if (unlikely(vinfo->nr_zones < SD_EC_DP) && is_erasure_oid(oid)) - return false; + if (is_erasure_oid(oid)) { + uint8_t policy = get_vdi_copy_policy(oid_to_vid(oid)); + int edp = ec_policy_to_dp(policy, NULL, NULL); + + if (unlikely(vinfo->nr_zones < edp)) + return false; + } nr_copies = get_obj_copy_number(oid, vinfo->nr_zones); oid_to_vnodes(oid, &vinfo->vroot, nr_copies, obj_vnodes); diff --git a/sheep/recovery.c b/sheep/recovery.c index 037d2c3..790bca8 100644 --- a/sheep/recovery.c +++ b/sheep/recovery.c @@ -164,8 +164,10 @@ static void *read_erasure_object(uint64_t oid, uint8_t idx, struct vnode_info *old = grab_vnode_info(rw->old_vinfo), *new_old; uint32_t epoch = rw->epoch, tgt_epoch = rw->tgt_epoch; const struct sd_node *node; + uint8_t policy = get_vdi_copy_policy(oid_to_vid(oid)); + int edp = ec_policy_to_dp(policy, NULL, NULL); again: - if (old->nr_zones < SD_EC_DP) { + if (unlikely(old->nr_zones < edp)) { if (search_erasure_object(oid, idx, &old->nroot, rw, tgt_epoch, buf) == SD_RES_SUCCESS) @@ -390,14 +392,23 @@ out: static void *rebuild_erasure_object(uint64_t oid, uint8_t idx, struct recovery_work *rw) { - uint8_t *bufs[SD_EC_D] = { 0 }; - int idxs[SD_EC_D], len = get_store_objsize(oid); - struct fec *ctx = ec_init(SD_EC_D, SD_EC_DP); + int len = get_store_objsize(oid); char *lost = xvalloc(len); int i, j; + uint8_t policy = get_vdi_copy_policy(oid_to_vid(oid)); + int ed = 0, edp; + edp = ec_policy_to_dp(policy, &ed, NULL); + struct fec *ctx = ec_init(ed, edp); + uint8_t *bufs[ed]; + int idxs[ed]; + + for (i = 0; i < ed; i++) + bufs[i] = NULL; + for (i = 0; i < ed; i++) + idxs[i] = 0; /* Prepare replica */ - for (i = 0, j = 0; i < SD_EC_DP && j < SD_EC_D; i++) { + for (i = 0, j = 0; i < edp && j < ed; i++) { if (i == idx) continue; bufs[j] = read_erasure_object(oid, i, rw); @@ -405,7 +416,7 @@ static void *rebuild_erasure_object(uint64_t oid, uint8_t idx, continue; idxs[j++] = i; } - if (j != SD_EC_D) { + if (j != ed) { free(lost); lost = NULL; goto out; @@ -413,18 +424,18 @@ static void *rebuild_erasure_object(uint64_t oid, uint8_t idx, /* Rebuild the lost replica */ for (i = 0; i < SD_EC_NR_STRIPE_PER_OBJECT; i++) { - const uint8_t *in[SD_EC_D]; - int strip_size = SD_EC_DATA_STRIPE_SIZE / SD_EC_D; + const uint8_t *in[ed]; + int strip_size = SD_EC_DATA_STRIPE_SIZE / ed; uint8_t out[strip_size]; - for (j = 0; j < SD_EC_D; j++) + for (j = 0; j < ed; j++) in[j] = bufs[j] + strip_size * i; ec_decode(ctx, in, idxs, out, idx); memcpy(lost + strip_size * i, out, strip_size); } out: ec_destroy(ctx); - for (i = 0; i < SD_EC_D; i++) + for (i = 0; i < ed; i++) free(bufs[i]); return lost; } @@ -432,10 +443,12 @@ out: static uint8_t local_node_copy_index(struct rb_root *vroot, uint64_t oid) { const struct sd_node *target_nodes[SD_MAX_NODES]; + uint8_t policy = get_vdi_copy_policy(oid_to_vid(oid)); uint8_t idx; + int edp = ec_policy_to_dp(policy, NULL, NULL); - oid_to_nodes(oid, vroot, SD_EC_DP, target_nodes); - for (idx = 0; idx < SD_EC_DP; idx++) + oid_to_nodes(oid, vroot, edp, target_nodes); + for (idx = 0; idx < edp; idx++) if (node_is_local(target_nodes[idx])) return idx; panic("can't get valid index for %"PRIx64, oid); @@ -450,9 +463,9 @@ static uint8_t local_node_copy_index(struct rb_root *vroot, uint64_t oid) * 2.1 read enough other copies from their tracks in epoch history * 2.2 rebuild the lost object from the content of copies read at 2.1 * - * The subtle case is number for available zones is less than SD_EC_DP or the - * requested index of lost object: - * 1 we need to make sure nr_zones >= SD_EC_DP to avoid panic of + * The subtle case is number for available zones is less than total copy number + * or the requested index of lost object: + * 1 we need to make sure nr_zones >= total_copy_nr to avoid panic of * oid_to_node(s) helpers. * 2 we have to search all the available zones when we can't get idx. Its * okay to do a mad search when number of available zones is small @@ -466,8 +479,10 @@ static int recover_erasure_object(struct recovery_obj_work *row) void *buf = NULL; uint8_t idx; int ret = -1; + uint8_t policy = get_vdi_copy_policy(oid_to_vid(oid)); + int edp = ec_policy_to_dp(policy, NULL, NULL); - if (cur->nr_zones < SD_EC_DP) + if (cur->nr_zones < edp) return -1; idx = local_node_copy_index(&cur->vroot, oid); diff --git a/tests/functional/022 b/tests/functional/022 index 22ad2a1..1325b8b 100755 --- a/tests/functional/022 +++ b/tests/functional/022 @@ -4,11 +4,11 @@ . ./common -for i in `seq 0 2`; do +for i in `seq 0 5`; do _start_sheep $i "-g" done -_wait_for_sheep "3" +_wait_for_sheep 6 _cluster_format -c 3 diff --git a/tests/functional/029 b/tests/functional/029 index 45e0a81..e0eb771 100755 --- a/tests/functional/029 +++ b/tests/functional/029 @@ -4,11 +4,11 @@ . ./common -for i in `seq 0 7`; do +for i in `seq 0 22`; do _start_sheep $i; done -_wait_for_sheep 8 +_wait_for_sheep 23 _cluster_format -c 3 @@ -16,16 +16,20 @@ for i in `seq 2 4`; do $DOG vdi create test$i 20M -c $i -P done -$DOG vdi create -e test5 20M -P +$DOG vdi create -c 4:2 test5 20M -P +$DOG vdi create -c 4:3 test6 20M -P +$DOG vdi create -c 4:4 fail 20M -P +$DOG vdi create -c 4:5 fail 20M -P +$DOG vdi create -c 16:7 test7 20M -P +$DOG vdi create -c 16:8 fail 20M -P $DOG vdi snapshot -s tag test2 $DOG vdi clone -s 1 test2 clone -c 3 - for i in `seq 2 3`; do _kill_sheep $i; done -for i in `seq 8 9`; do +for i in `seq 23 24`; do _start_sheep $i; done @@ -36,7 +40,7 @@ $DOG vdi delete -s 1 test2 _vdi_list -for i in `seq 2 5`; do +for i in `seq 2 7`; do $DOG vdi object test$i -i 1; done diff --git a/tests/functional/029.out b/tests/functional/029.out index 6e1456e..db3db93 100644 --- a/tests/functional/029.out +++ b/tests/functional/029.out @@ -1,47 +1,180 @@ QA output created by 029 using backend plain store +Invalid parameter 4:4 +To create erasure coded vdi, set -c x:y + x(2,4,8,16) - number of data strips + y(1 to 15) - number of parity strips +and meet the condition x > y +To create replicated vdi, set -c x + x(0 < x <= 31) - number of replicated copies +Invalid parameter 4:5 +To create erasure coded vdi, set -c x:y + x(2,4,8,16) - number of data strips + y(1 to 15) - number of parity strips +and meet the condition x > y +To create replicated vdi, set -c x + x(0 < x <= 31) - number of replicated copies +Invalid parameter 16:8 +To create erasure coded vdi, set -c x:y + x(2,4,8,16) - number of data strips + y(1 to 15) - number of parity strips +and meet the condition x > y +To create replicated vdi, set -c x + x(0 < x <= 31) - number of replicated copies Name Id Size Used Shared Creation time VDI id Copies Tag test5 0 20 MB 20 MB 0.0 MB DATE fd2c30 6 test4 0 20 MB 20 MB 0.0 MB DATE fd2de3 4 + test7 0 20 MB 20 MB 0.0 MB DATE fd2f96 23 + test6 0 20 MB 20 MB 0.0 MB DATE fd3149 7 test3 0 20 MB 20 MB 0.0 MB DATE fd3662 3 test2 0 20 MB 0.0 MB 20 MB DATE fd3816 2 -Looking for the object 0xfd381500000001 (the inode vid 0xfd3816 idx 1) with 8 nodes +Looking for the object 0xfd381500000001 (the inode vid 0xfd3816 idx 1) with 23 nodes -127.0.0.1:7000 has the object (should be 2 copies) +127.0.0.1:7000 doesn't have the object 127.0.0.1:7001 doesn't have the object 127.0.0.1:7004 doesn't have the object 127.0.0.1:7005 doesn't have the object 127.0.0.1:7006 doesn't have the object 127.0.0.1:7007 doesn't have the object 127.0.0.1:7008 doesn't have the object -127.0.0.1:7009 has the object (should be 2 copies) -Looking for the object 0xfd366200000001 (the inode vid 0xfd3662 idx 1) with 8 nodes +127.0.0.1:7009 doesn't have the object +127.0.0.1:7010 doesn't have the object +127.0.0.1:7011 doesn't have the object +127.0.0.1:7012 doesn't have the object +127.0.0.1:7013 doesn't have the object +127.0.0.1:7014 doesn't have the object +127.0.0.1:7015 doesn't have the object +127.0.0.1:7016 has the object (should be 2 copies) +127.0.0.1:7017 doesn't have the object +127.0.0.1:7018 doesn't have the object +127.0.0.1:7019 doesn't have the object +127.0.0.1:7020 doesn't have the object +127.0.0.1:7021 doesn't have the object +127.0.0.1:7022 has the object (should be 2 copies) +127.0.0.1:7023 doesn't have the object +127.0.0.1:7024 doesn't have the object +Looking for the object 0xfd366200000001 (the inode vid 0xfd3662 idx 1) with 23 nodes 127.0.0.1:7000 doesn't have the object 127.0.0.1:7001 has the object (should be 3 copies) -127.0.0.1:7004 has the object (should be 3 copies) +127.0.0.1:7004 doesn't have the object 127.0.0.1:7005 doesn't have the object 127.0.0.1:7006 doesn't have the object 127.0.0.1:7007 has the object (should be 3 copies) 127.0.0.1:7008 doesn't have the object 127.0.0.1:7009 doesn't have the object -Looking for the object 0xfd2de300000001 (the inode vid 0xfd2de3 idx 1) with 8 nodes +127.0.0.1:7010 doesn't have the object +127.0.0.1:7011 doesn't have the object +127.0.0.1:7012 has the object (should be 3 copies) +127.0.0.1:7013 doesn't have the object +127.0.0.1:7014 doesn't have the object +127.0.0.1:7015 doesn't have the object +127.0.0.1:7016 doesn't have the object +127.0.0.1:7017 doesn't have the object +127.0.0.1:7018 doesn't have the object +127.0.0.1:7019 doesn't have the object +127.0.0.1:7020 doesn't have the object +127.0.0.1:7021 doesn't have the object +127.0.0.1:7022 doesn't have the object +127.0.0.1:7023 doesn't have the object +127.0.0.1:7024 doesn't have the object +Looking for the object 0xfd2de300000001 (the inode vid 0xfd2de3 idx 1) with 23 nodes 127.0.0.1:7000 doesn't have the object 127.0.0.1:7001 has the object (should be 4 copies) 127.0.0.1:7004 doesn't have the object 127.0.0.1:7005 has the object (should be 4 copies) 127.0.0.1:7006 doesn't have the object -127.0.0.1:7007 has the object (should be 4 copies) -127.0.0.1:7008 has the object (should be 4 copies) +127.0.0.1:7007 doesn't have the object +127.0.0.1:7008 doesn't have the object 127.0.0.1:7009 doesn't have the object -Looking for the object 0xfd2c3000000001 (the inode vid 0xfd2c30 idx 1) with 8 nodes +127.0.0.1:7010 doesn't have the object +127.0.0.1:7011 doesn't have the object +127.0.0.1:7012 doesn't have the object +127.0.0.1:7013 doesn't have the object +127.0.0.1:7014 has the object (should be 4 copies) +127.0.0.1:7015 doesn't have the object +127.0.0.1:7016 doesn't have the object +127.0.0.1:7017 doesn't have the object +127.0.0.1:7018 doesn't have the object +127.0.0.1:7019 has the object (should be 4 copies) +127.0.0.1:7020 doesn't have the object +127.0.0.1:7021 doesn't have the object +127.0.0.1:7022 doesn't have the object +127.0.0.1:7023 doesn't have the object +127.0.0.1:7024 doesn't have the object +Looking for the object 0xfd2c3000000001 (the inode vid 0xfd2c30 idx 1) with 23 nodes 127.0.0.1:7000 has the object (should be 6 copies) 127.0.0.1:7001 has the object (should be 6 copies) -127.0.0.1:7004 has the object (should be 6 copies) +127.0.0.1:7004 doesn't have the object 127.0.0.1:7005 doesn't have the object -127.0.0.1:7006 has the object (should be 6 copies) -127.0.0.1:7007 has the object (should be 6 copies) +127.0.0.1:7006 doesn't have the object +127.0.0.1:7007 doesn't have the object 127.0.0.1:7008 doesn't have the object 127.0.0.1:7009 has the object (should be 6 copies) +127.0.0.1:7010 doesn't have the object +127.0.0.1:7011 has the object (should be 6 copies) +127.0.0.1:7012 doesn't have the object +127.0.0.1:7013 doesn't have the object +127.0.0.1:7014 doesn't have the object +127.0.0.1:7015 doesn't have the object +127.0.0.1:7016 doesn't have the object +127.0.0.1:7017 doesn't have the object +127.0.0.1:7018 doesn't have the object +127.0.0.1:7019 doesn't have the object +127.0.0.1:7020 doesn't have the object +127.0.0.1:7021 has the object (should be 6 copies) +127.0.0.1:7022 doesn't have the object +127.0.0.1:7023 has the object (should be 6 copies) +127.0.0.1:7024 doesn't have the object +Looking for the object 0xfd314900000001 (the inode vid 0xfd3149 idx 1) with 23 nodes + +127.0.0.1:7000 doesn't have the object +127.0.0.1:7001 has the object (should be 7 copies) +127.0.0.1:7004 doesn't have the object +127.0.0.1:7005 doesn't have the object +127.0.0.1:7006 doesn't have the object +127.0.0.1:7007 doesn't have the object +127.0.0.1:7008 has the object (should be 7 copies) +127.0.0.1:7009 doesn't have the object +127.0.0.1:7010 doesn't have the object +127.0.0.1:7011 has the object (should be 7 copies) +127.0.0.1:7012 has the object (should be 7 copies) +127.0.0.1:7013 doesn't have the object +127.0.0.1:7014 doesn't have the object +127.0.0.1:7015 doesn't have the object +127.0.0.1:7016 doesn't have the object +127.0.0.1:7017 doesn't have the object +127.0.0.1:7018 doesn't have the object +127.0.0.1:7019 has the object (should be 7 copies) +127.0.0.1:7020 doesn't have the object +127.0.0.1:7021 doesn't have the object +127.0.0.1:7022 has the object (should be 7 copies) +127.0.0.1:7023 doesn't have the object +127.0.0.1:7024 has the object (should be 7 copies) +Looking for the object 0xfd2f9600000001 (the inode vid 0xfd2f96 idx 1) with 23 nodes + +127.0.0.1:7000 has the object (should be 23 copies) +127.0.0.1:7001 has the object (should be 23 copies) +127.0.0.1:7004 has the object (should be 23 copies) +127.0.0.1:7005 has the object (should be 23 copies) +127.0.0.1:7006 has the object (should be 23 copies) +127.0.0.1:7007 has the object (should be 23 copies) +127.0.0.1:7008 has the object (should be 23 copies) +127.0.0.1:7009 has the object (should be 23 copies) +127.0.0.1:7010 has the object (should be 23 copies) +127.0.0.1:7011 has the object (should be 23 copies) +127.0.0.1:7012 has the object (should be 23 copies) +127.0.0.1:7013 has the object (should be 23 copies) +127.0.0.1:7014 has the object (should be 23 copies) +127.0.0.1:7015 has the object (should be 23 copies) +127.0.0.1:7016 has the object (should be 23 copies) +127.0.0.1:7017 has the object (should be 23 copies) +127.0.0.1:7018 has the object (should be 23 copies) +127.0.0.1:7019 has the object (should be 23 copies) +127.0.0.1:7020 has the object (should be 23 copies) +127.0.0.1:7021 has the object (should be 23 copies) +127.0.0.1:7022 has the object (should be 23 copies) +127.0.0.1:7023 has the object (should be 23 copies) +127.0.0.1:7024 has the object (should be 23 copies) diff --git a/tests/functional/031 b/tests/functional/031 index 56145ec..6af9f0a 100755 --- a/tests/functional/031 +++ b/tests/functional/031 @@ -13,7 +13,7 @@ for i in 1 2 3; do $DOG vdi create test$i ${i}00M -c $i done -$DOG vdi create -e test4 400M +$DOG vdi create -c 4:2 test4 400M _vdi_list diff --git a/tests/functional/common.rc b/tests/functional/common.rc index 24c1d99..eadedf7 100644 --- a/tests/functional/common.rc +++ b/tests/functional/common.rc @@ -513,7 +513,7 @@ _vdi_list() _vdi_create() { if $EC; then - $DOG vdi create -e $* + $DOG vdi create -c 4:2 $* else $DOG vdi create $* fi -- 1.7.9.5 -- sheepdog mailing list [email protected] http://lists.wpkg.org/mailman/listinfo/sheepdog
