9ae3f9
From a04592cce9aaa6ccb8a038bc3b4e31bc125d1d10 Mon Sep 17 00:00:00 2001
9ae3f9
From: Sanju Rakonde <srakonde@redhat.com>
9ae3f9
Date: Tue, 16 Jun 2020 18:03:21 +0530
9ae3f9
Subject: [PATCH 453/456] glusterd: add-brick command failure
9ae3f9
9ae3f9
Problem: add-brick operation is failing when replica or disperse
9ae3f9
count is not mentioned in the add-brick command.
9ae3f9
9ae3f9
Reason: with commit a113d93 we are checking brick order while
9ae3f9
doing add-brick operation for replica and disperse volumes. If
9ae3f9
replica count or disperse count is not mentioned in the command,
9ae3f9
the dict get is failing and resulting add-brick operation failure.
9ae3f9
9ae3f9
> upstream patch: https://review.gluster.org/#/c/glusterfs/+/24581/
9ae3f9
> fixes: #1306
9ae3f9
> Change-Id: Ie957540e303bfb5f2d69015661a60d7e72557353
9ae3f9
> Signed-off-by: Sanju Rakonde <srakonde@redhat.com>
9ae3f9
9ae3f9
BUG: 1847081
9ae3f9
Change-Id: Ie957540e303bfb5f2d69015661a60d7e72557353
9ae3f9
Signed-off-by: Sanju Rakonde <srakonde@redhat.com>
9ae3f9
Reviewed-on: https://code.engineering.redhat.com/gerrit/203867
9ae3f9
Tested-by: RHGS Build Bot <nigelb@redhat.com>
9ae3f9
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
9ae3f9
---
9ae3f9
 tests/bugs/glusterd/brick-order-check-add-brick.t | 40 ++++++++++++++++++++++
9ae3f9
 tests/cluster.rc                                  | 11 ++++--
9ae3f9
 xlators/mgmt/glusterd/src/glusterd-brick-ops.c    | 39 ++++++++++++++-------
9ae3f9
 xlators/mgmt/glusterd/src/glusterd-utils.c        | 30 ++---------------
9ae3f9
 xlators/mgmt/glusterd/src/glusterd-utils.h        |  3 +-
9ae3f9
 xlators/mgmt/glusterd/src/glusterd-volume-ops.c   | 41 +++++++++++++++++++----
9ae3f9
 6 files changed, 115 insertions(+), 49 deletions(-)
9ae3f9
 create mode 100644 tests/bugs/glusterd/brick-order-check-add-brick.t
9ae3f9
9ae3f9
diff --git a/tests/bugs/glusterd/brick-order-check-add-brick.t b/tests/bugs/glusterd/brick-order-check-add-brick.t
9ae3f9
new file mode 100644
9ae3f9
index 0000000..29f0ed1
9ae3f9
--- /dev/null
9ae3f9
+++ b/tests/bugs/glusterd/brick-order-check-add-brick.t
9ae3f9
@@ -0,0 +1,40 @@
9ae3f9
+#!/bin/bash
9ae3f9
+. $(dirname $0)/../../include.rc
9ae3f9
+. $(dirname $0)/../../volume.rc
9ae3f9
+. $(dirname $0)/../../cluster.rc
9ae3f9
+. $(dirname $0)/../../snapshot.rc
9ae3f9
+
9ae3f9
+cleanup;
9ae3f9
+
9ae3f9
+TEST verify_lvm_version;
9ae3f9
+#Create cluster with 3 nodes
9ae3f9
+TEST launch_cluster 3 -NO_DEBUG -NO_FORCE
9ae3f9
+TEST setup_lvm 3
9ae3f9
+
9ae3f9
+TEST $CLI_1 peer probe $H2
9ae3f9
+TEST $CLI_1 peer probe $H3
9ae3f9
+EXPECT_WITHIN $PROBE_TIMEOUT 2 peer_count
9ae3f9
+
9ae3f9
+TEST $CLI_1 volume create $V0 replica 3 $H1:$L1/$V0 $H2:$L2/$V0 $H3:$L3/$V0
9ae3f9
+EXPECT '1 x 3 = 3' volinfo_field $V0 'Number of Bricks'
9ae3f9
+EXPECT 'Created' volinfo_field $V0 'Status'
9ae3f9
+
9ae3f9
+TEST $CLI_1 volume start $V0
9ae3f9
+EXPECT 'Started' volinfo_field $V0 'Status'
9ae3f9
+
9ae3f9
+#add-brick with or without mentioning the replica count should not fail
9ae3f9
+TEST $CLI_1 volume add-brick $V0 replica 3 $H1:$L1/${V0}_1 $H2:$L2/${V0}_1 $H3:$L3/${V0}_1
9ae3f9
+EXPECT '2 x 3 = 6' volinfo_field $V0 'Number of Bricks'
9ae3f9
+
9ae3f9
+TEST $CLI_1 volume add-brick $V0 $H1:$L1/${V0}_2 $H2:$L2/${V0}_2 $H3:$L3/${V0}_2
9ae3f9
+EXPECT '3 x 3 = 9' volinfo_field $V0 'Number of Bricks'
9ae3f9
+
9ae3f9
+#adding bricks from same host should fail the brick order check
9ae3f9
+TEST ! $CLI_1 volume add-brick $V0 $H1:$L1/${V0}_3 $H1:$L1/${V0}_4 $H1:$L1/${V0}_5
9ae3f9
+EXPECT '3 x 3 = 9' volinfo_field $V0 'Number of Bricks'
9ae3f9
+
9ae3f9
+#adding bricks from same host with force should succeed
9ae3f9
+TEST $CLI_1 volume add-brick $V0 $H1:$L1/${V0}_3 $H1:$L1/${V0}_4 $H1:$L1/${V0}_5 force
9ae3f9
+EXPECT '4 x 3 = 12' volinfo_field $V0 'Number of Bricks'
9ae3f9
+
9ae3f9
+cleanup
9ae3f9
diff --git a/tests/cluster.rc b/tests/cluster.rc
9ae3f9
index 99be8e7..8b73153 100644
9ae3f9
--- a/tests/cluster.rc
9ae3f9
+++ b/tests/cluster.rc
9ae3f9
@@ -11,7 +11,7 @@ function launch_cluster() {
9ae3f9
     define_backends $count;
9ae3f9
     define_hosts $count;
9ae3f9
     define_glusterds $count $2;
9ae3f9
-    define_clis $count;
9ae3f9
+    define_clis $count $3;
9ae3f9
 
9ae3f9
     start_glusterds;
9ae3f9
 }
9ae3f9
@@ -133,8 +133,13 @@ function define_clis() {
9ae3f9
         lopt1="--log-file=$logdir/$logfile1"
9ae3f9
 
9ae3f9
 
9ae3f9
-        eval "CLI_$i='$CLI --glusterd-sock=${!b}/glusterd/gd.sock $lopt'";
9ae3f9
-        eval "CLI$i='$CLI --glusterd-sock=${!b}/glusterd/gd.sock $lopt1'";
9ae3f9
+        if [ "$2" == "-NO_FORCE" ]; then
9ae3f9
+                eval "CLI_$i='$CLI_NO_FORCE --glusterd-sock=${!b}/glusterd/gd.sock $lopt'";
9ae3f9
+                eval "CLI$i='$CLI_NO_FORCE --glusterd-sock=${!b}/glusterd/gd.sock $lopt1'";
9ae3f9
+        else
9ae3f9
+                eval "CLI_$i='$CLI --glusterd-sock=${!b}/glusterd/gd.sock $lopt'";
9ae3f9
+                eval "CLI$i='$CLI --glusterd-sock=${!b}/glusterd/gd.sock $lopt1'";
9ae3f9
+        fi
9ae3f9
     done
9ae3f9
 }
9ae3f9
 
9ae3f9
diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
9ae3f9
index 121346c..5ae577a 100644
9ae3f9
--- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
9ae3f9
+++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
9ae3f9
@@ -1576,20 +1576,35 @@ glusterd_op_stage_add_brick(dict_t *dict, char **op_errstr, dict_t *rsp_dict)
9ae3f9
 
9ae3f9
     /* Check brick order if the volume type is replicate or disperse. If
9ae3f9
      * force at the end of command not given then check brick order.
9ae3f9
+     * doing this check at the originator node is sufficient.
9ae3f9
      */
9ae3f9
 
9ae3f9
-    if (!is_force) {
9ae3f9
-        if ((volinfo->type == GF_CLUSTER_TYPE_REPLICATE) ||
9ae3f9
-            (volinfo->type == GF_CLUSTER_TYPE_DISPERSE)) {
9ae3f9
-            ret = glusterd_check_brick_order(dict, msg, volinfo->type);
9ae3f9
-            if (ret) {
9ae3f9
-                gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BAD_BRKORDER,
9ae3f9
-                       "Not adding brick because of "
9ae3f9
-                       "bad brick order. %s",
9ae3f9
-                       msg);
9ae3f9
-                *op_errstr = gf_strdup(msg);
9ae3f9
-                goto out;
9ae3f9
-            }
9ae3f9
+    if (is_origin_glusterd(dict) && !is_force) {
9ae3f9
+        ret = 0;
9ae3f9
+        if (volinfo->type == GF_CLUSTER_TYPE_REPLICATE) {
9ae3f9
+            gf_msg_debug(this->name, 0,
9ae3f9
+                         "Replicate cluster type "
9ae3f9
+                         "found. Checking brick order.");
9ae3f9
+            if (replica_count)
9ae3f9
+                ret = glusterd_check_brick_order(dict, msg, volinfo->type,
9ae3f9
+                                                 replica_count);
9ae3f9
+            else
9ae3f9
+                ret = glusterd_check_brick_order(dict, msg, volinfo->type,
9ae3f9
+                                                 volinfo->replica_count);
9ae3f9
+        } else if (volinfo->type == GF_CLUSTER_TYPE_DISPERSE) {
9ae3f9
+            gf_msg_debug(this->name, 0,
9ae3f9
+                         "Disperse cluster type"
9ae3f9
+                         " found. Checking brick order.");
9ae3f9
+            ret = glusterd_check_brick_order(dict, msg, volinfo->type,
9ae3f9
+                                             volinfo->disperse_count);
9ae3f9
+        }
9ae3f9
+        if (ret) {
9ae3f9
+            gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BAD_BRKORDER,
9ae3f9
+                   "Not adding brick because of "
9ae3f9
+                   "bad brick order. %s",
9ae3f9
+                   msg);
9ae3f9
+            *op_errstr = gf_strdup(msg);
9ae3f9
+            goto out;
9ae3f9
         }
9ae3f9
     }
9ae3f9
 
9ae3f9
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
9ae3f9
index 6f904ae..545e688 100644
9ae3f9
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
9ae3f9
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
9ae3f9
@@ -14802,7 +14802,8 @@ glusterd_compare_addrinfo(struct addrinfo *first, struct addrinfo *next)
9ae3f9
  * volume are present on the same server
9ae3f9
  */
9ae3f9
 int32_t
9ae3f9
-glusterd_check_brick_order(dict_t *dict, char *err_str, int32_t type)
9ae3f9
+glusterd_check_brick_order(dict_t *dict, char *err_str, int32_t type,
9ae3f9
+                           int32_t sub_count)
9ae3f9
 {
9ae3f9
     int ret = -1;
9ae3f9
     int i = 0;
9ae3f9
@@ -14819,7 +14820,6 @@ glusterd_check_brick_order(dict_t *dict, char *err_str, int32_t type)
9ae3f9
     char *tmpptr = NULL;
9ae3f9
     char *volname = NULL;
9ae3f9
     int32_t brick_count = 0;
9ae3f9
-    int32_t sub_count = 0;
9ae3f9
     struct addrinfo *ai_info = NULL;
9ae3f9
     char brick_addr[128] = {
9ae3f9
         0,
9ae3f9
@@ -14870,31 +14870,6 @@ glusterd_check_brick_order(dict_t *dict, char *err_str, int32_t type)
9ae3f9
         goto out;
9ae3f9
     }
9ae3f9
 
9ae3f9
-    if (type != GF_CLUSTER_TYPE_DISPERSE) {
9ae3f9
-        ret = dict_get_int32n(dict, "replica-count", SLEN("replica-count"),
9ae3f9
-                              &sub_count);
9ae3f9
-        if (ret) {
9ae3f9
-            gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
9ae3f9
-                   "Bricks check : Could"
9ae3f9
-                   " not retrieve replica count");
9ae3f9
-            goto out;
9ae3f9
-        }
9ae3f9
-        gf_msg_debug(this->name, 0,
9ae3f9
-                     "Replicate cluster type "
9ae3f9
-                     "found. Checking brick order.");
9ae3f9
-    } else {
9ae3f9
-        ret = dict_get_int32n(dict, "disperse-count", SLEN("disperse-count"),
9ae3f9
-                              &sub_count);
9ae3f9
-        if (ret) {
9ae3f9
-            gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
9ae3f9
-                   "Bricks check : Could"
9ae3f9
-                   " not retrieve disperse count");
9ae3f9
-            goto out;
9ae3f9
-        }
9ae3f9
-        gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_DISPERSE_CLUSTER_FOUND,
9ae3f9
-               "Disperse cluster type"
9ae3f9
-               " found. Checking brick order.");
9ae3f9
-    }
9ae3f9
     brick_list_dup = brick_list_ptr = gf_strdup(brick_list);
9ae3f9
     /* Resolve hostnames and get addrinfo */
9ae3f9
     while (i < brick_count) {
9ae3f9
@@ -14989,5 +14964,6 @@ out:
9ae3f9
         ai_list_tmp2 = ai_list_tmp1;
9ae3f9
     }
9ae3f9
     free(ai_list_tmp2);
9ae3f9
+    gf_msg_debug("glusterd", 0, "Returning %d", ret);
9ae3f9
     return ret;
9ae3f9
 }
9ae3f9
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
9ae3f9
index e2e2454..5f5de82 100644
9ae3f9
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
9ae3f9
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
9ae3f9
@@ -883,6 +883,7 @@ char *
9ae3f9
 search_brick_path_from_proc(pid_t brick_pid, char *brickpath);
9ae3f9
 
9ae3f9
 int32_t
9ae3f9
-glusterd_check_brick_order(dict_t *dict, char *err_str, int32_t type);
9ae3f9
+glusterd_check_brick_order(dict_t *dict, char *err_str, int32_t type,
9ae3f9
+                           int32_t sub_count);
9ae3f9
 
9ae3f9
 #endif
9ae3f9
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
9ae3f9
index 8da2ff3..134b04c 100644
9ae3f9
--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
9ae3f9
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
9ae3f9
@@ -1024,6 +1024,8 @@ glusterd_op_stage_create_volume(dict_t *dict, char **op_errstr,
9ae3f9
     int32_t local_brick_count = 0;
9ae3f9
     int32_t i = 0;
9ae3f9
     int32_t type = 0;
9ae3f9
+    int32_t replica_count = 0;
9ae3f9
+    int32_t disperse_count = 0;
9ae3f9
     char *brick = NULL;
9ae3f9
     char *tmpptr = NULL;
9ae3f9
     xlator_t *this = NULL;
9ae3f9
@@ -1119,15 +1121,42 @@ glusterd_op_stage_create_volume(dict_t *dict, char **op_errstr,
9ae3f9
         }
9ae3f9
 
9ae3f9
         if (!is_force) {
9ae3f9
-            if ((type == GF_CLUSTER_TYPE_REPLICATE) ||
9ae3f9
-                (type == GF_CLUSTER_TYPE_DISPERSE)) {
9ae3f9
-                ret = glusterd_check_brick_order(dict, msg, type);
9ae3f9
+            if (type == GF_CLUSTER_TYPE_REPLICATE) {
9ae3f9
+                ret = dict_get_int32n(dict, "replica-count",
9ae3f9
+                                      SLEN("replica-count"), &replica_count);
9ae3f9
                 if (ret) {
9ae3f9
-                    gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BAD_BRKORDER,
9ae3f9
-                           "Not creating volume because of "
9ae3f9
-                           "bad brick order");
9ae3f9
+                    gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
9ae3f9
+                           "Bricks check : Could"
9ae3f9
+                           " not retrieve replica count");
9ae3f9
+                    goto out;
9ae3f9
+                }
9ae3f9
+                gf_msg_debug(this->name, 0,
9ae3f9
+                             "Replicate cluster type "
9ae3f9
+                             "found. Checking brick order.");
9ae3f9
+                ret = glusterd_check_brick_order(dict, msg, type,
9ae3f9
+                                                 replica_count);
9ae3f9
+            } else if (type == GF_CLUSTER_TYPE_DISPERSE) {
9ae3f9
+                ret = dict_get_int32n(dict, "disperse-count",
9ae3f9
+                                      SLEN("disperse-count"), &disperse_count);
9ae3f9
+                if (ret) {
9ae3f9
+                    gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
9ae3f9
+                           "Bricks check : Could"
9ae3f9
+                           " not retrieve disperse count");
9ae3f9
                     goto out;
9ae3f9
                 }
9ae3f9
+                gf_msg_debug(this->name, 0,
9ae3f9
+                             "Disperse cluster type"
9ae3f9
+                             " found. Checking brick order.");
9ae3f9
+                ret = glusterd_check_brick_order(dict, msg, type,
9ae3f9
+                                                 disperse_count);
9ae3f9
+            }
9ae3f9
+            if (ret) {
9ae3f9
+                gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BAD_BRKORDER,
9ae3f9
+                       "Not creating the volume because of "
9ae3f9
+                       "bad brick order. %s",
9ae3f9
+                       msg);
9ae3f9
+                *op_errstr = gf_strdup(msg);
9ae3f9
+                goto out;
9ae3f9
             }
9ae3f9
         }
9ae3f9
     }
9ae3f9
-- 
9ae3f9
1.8.3.1
9ae3f9