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

Signed-off-by: Liu Yuan <[email protected]>
---
 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

-- 
sheepdog mailing list
[email protected]
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to