|
|
d84cf8 |
From d7c52ddd2cbadb1d9a55767c2f7fe6ba38d9a2ed Mon Sep 17 00:00:00 2001
|
|
|
d84cf8 |
From: Sheetal Pamecha <spamecha@redhat.com>
|
|
|
d84cf8 |
Date: Wed, 20 Nov 2019 12:42:12 +0530
|
|
|
d84cf8 |
Subject: [PATCH 431/449] glusterd: check for same node while adding bricks in
|
|
|
d84cf8 |
disperse volume
|
|
|
d84cf8 |
|
|
|
d84cf8 |
The optimal way for configuring disperse and replicate volumes
|
|
|
d84cf8 |
is to have all bricks in different nodes.
|
|
|
d84cf8 |
|
|
|
d84cf8 |
During create operation it fails saying it is not optimal, user
|
|
|
d84cf8 |
must use force to over-ride this behavior. Implementing same
|
|
|
d84cf8 |
during add-brick operation to avoid situation where all the added
|
|
|
d84cf8 |
bricks end up from same host. Operation will error out accordingly.
|
|
|
d84cf8 |
and this can be over-ridden by using force same as create.
|
|
|
d84cf8 |
|
|
|
d84cf8 |
> Upstream Patch Link: https://review.gluster.org/#/c/glusterfs/+/23729
|
|
|
d84cf8 |
> fixes: #1047
|
|
|
d84cf8 |
> Change-Id: I3ee9c97c1a14b73f4532893bc00187ef9355238b
|
|
|
d84cf8 |
> Signed-off-by: Sheetal Pamecha <spamecha@redhat.com>
|
|
|
d84cf8 |
|
|
|
d84cf8 |
BUG: 1524457
|
|
|
d84cf8 |
Change-Id: I3ee9c97c1a14b73f4532893bc00187ef9355238b
|
|
|
d84cf8 |
Signed-off-by: Sheetal Pamecha <spamecha@redhat.com>
|
|
|
d84cf8 |
Reviewed-on: https://code.engineering.redhat.com/gerrit/202621
|
|
|
d84cf8 |
Tested-by: RHGS Build Bot <nigelb@redhat.com>
|
|
|
d84cf8 |
Reviewed-by: Sanju Rakonde <srakonde@redhat.com>
|
|
|
d84cf8 |
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
|
|
|
d84cf8 |
---
|
|
|
d84cf8 |
xlators/mgmt/glusterd/src/glusterd-brick-ops.c | 20 +-
|
|
|
d84cf8 |
xlators/mgmt/glusterd/src/glusterd-utils.c | 224 ++++++++++++++++++
|
|
|
d84cf8 |
xlators/mgmt/glusterd/src/glusterd-utils.h | 4 +
|
|
|
d84cf8 |
xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 293 +++---------------------
|
|
|
d84cf8 |
4 files changed, 276 insertions(+), 265 deletions(-)
|
|
|
d84cf8 |
|
|
|
d84cf8 |
diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
|
|
|
d84cf8 |
index c5141de..d424f31 100644
|
|
|
d84cf8 |
--- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
|
|
|
d84cf8 |
+++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
|
|
|
d84cf8 |
@@ -21,7 +21,6 @@
|
|
|
d84cf8 |
#include "glusterd-messages.h"
|
|
|
d84cf8 |
#include "glusterd-server-quorum.h"
|
|
|
d84cf8 |
#include <glusterfs/run.h>
|
|
|
d84cf8 |
-#include "glusterd-volgen.h"
|
|
|
d84cf8 |
#include <glusterfs/syscall.h>
|
|
|
d84cf8 |
#include <sys/signal.h>
|
|
|
d84cf8 |
|
|
|
d84cf8 |
@@ -1575,6 +1574,25 @@ glusterd_op_stage_add_brick(dict_t *dict, char **op_errstr, dict_t *rsp_dict)
|
|
|
d84cf8 |
|
|
|
d84cf8 |
is_force = dict_get_str_boolean(dict, "force", _gf_false);
|
|
|
d84cf8 |
|
|
|
d84cf8 |
+ /* Check brick order if the volume type is replicate or disperse. If
|
|
|
d84cf8 |
+ * force at the end of command not given then check brick order.
|
|
|
d84cf8 |
+ */
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+ if (!is_force) {
|
|
|
d84cf8 |
+ if ((volinfo->type == GF_CLUSTER_TYPE_REPLICATE) ||
|
|
|
d84cf8 |
+ (volinfo->type == GF_CLUSTER_TYPE_DISPERSE)) {
|
|
|
d84cf8 |
+ ret = glusterd_check_brick_order(dict, msg, volinfo->type);
|
|
|
d84cf8 |
+ if (ret) {
|
|
|
d84cf8 |
+ gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BAD_BRKORDER,
|
|
|
d84cf8 |
+ "Not adding brick because of "
|
|
|
d84cf8 |
+ "bad brick order. %s",
|
|
|
d84cf8 |
+ msg);
|
|
|
d84cf8 |
+ *op_errstr = gf_strdup(msg);
|
|
|
d84cf8 |
+ goto out;
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
if (volinfo->replica_count < replica_count && !is_force) {
|
|
|
d84cf8 |
cds_list_for_each_entry(brickinfo, &volinfo->bricks, brick_list)
|
|
|
d84cf8 |
{
|
|
|
d84cf8 |
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
|
|
|
d84cf8 |
index a1299bc..14e23d1 100644
|
|
|
d84cf8 |
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
|
|
|
d84cf8 |
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
|
|
|
d84cf8 |
@@ -14759,3 +14759,227 @@ glusterd_is_profile_on(glusterd_volinfo_t *volinfo)
|
|
|
d84cf8 |
return _gf_true;
|
|
|
d84cf8 |
return _gf_false;
|
|
|
d84cf8 |
}
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+static gf_ai_compare_t
|
|
|
d84cf8 |
+glusterd_compare_addrinfo(struct addrinfo *first, struct addrinfo *next)
|
|
|
d84cf8 |
+{
|
|
|
d84cf8 |
+ int ret = -1;
|
|
|
d84cf8 |
+ struct addrinfo *tmp1 = NULL;
|
|
|
d84cf8 |
+ struct addrinfo *tmp2 = NULL;
|
|
|
d84cf8 |
+ char firstip[NI_MAXHOST] = {0.};
|
|
|
d84cf8 |
+ char nextip[NI_MAXHOST] = {
|
|
|
d84cf8 |
+ 0,
|
|
|
d84cf8 |
+ };
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+ for (tmp1 = first; tmp1 != NULL; tmp1 = tmp1->ai_next) {
|
|
|
d84cf8 |
+ ret = getnameinfo(tmp1->ai_addr, tmp1->ai_addrlen, firstip, NI_MAXHOST,
|
|
|
d84cf8 |
+ NULL, 0, NI_NUMERICHOST);
|
|
|
d84cf8 |
+ if (ret)
|
|
|
d84cf8 |
+ return GF_AI_COMPARE_ERROR;
|
|
|
d84cf8 |
+ for (tmp2 = next; tmp2 != NULL; tmp2 = tmp2->ai_next) {
|
|
|
d84cf8 |
+ ret = getnameinfo(tmp2->ai_addr, tmp2->ai_addrlen, nextip,
|
|
|
d84cf8 |
+ NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
|
|
|
d84cf8 |
+ if (ret)
|
|
|
d84cf8 |
+ return GF_AI_COMPARE_ERROR;
|
|
|
d84cf8 |
+ if (!strcmp(firstip, nextip)) {
|
|
|
d84cf8 |
+ return GF_AI_COMPARE_MATCH;
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ return GF_AI_COMPARE_NO_MATCH;
|
|
|
d84cf8 |
+}
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+/* Check for non optimal brick order for Replicate/Disperse :
|
|
|
d84cf8 |
+ * Checks if bricks belonging to a replicate or disperse
|
|
|
d84cf8 |
+ * volume are present on the same server
|
|
|
d84cf8 |
+ */
|
|
|
d84cf8 |
+int32_t
|
|
|
d84cf8 |
+glusterd_check_brick_order(dict_t *dict, char *err_str, int32_t type)
|
|
|
d84cf8 |
+{
|
|
|
d84cf8 |
+ int ret = -1;
|
|
|
d84cf8 |
+ int i = 0;
|
|
|
d84cf8 |
+ int j = 0;
|
|
|
d84cf8 |
+ int k = 0;
|
|
|
d84cf8 |
+ xlator_t *this = NULL;
|
|
|
d84cf8 |
+ addrinfo_list_t *ai_list = NULL;
|
|
|
d84cf8 |
+ addrinfo_list_t *ai_list_tmp1 = NULL;
|
|
|
d84cf8 |
+ addrinfo_list_t *ai_list_tmp2 = NULL;
|
|
|
d84cf8 |
+ char *brick = NULL;
|
|
|
d84cf8 |
+ char *brick_list = NULL;
|
|
|
d84cf8 |
+ char *brick_list_dup = NULL;
|
|
|
d84cf8 |
+ char *brick_list_ptr = NULL;
|
|
|
d84cf8 |
+ char *tmpptr = NULL;
|
|
|
d84cf8 |
+ char *volname = NULL;
|
|
|
d84cf8 |
+ int32_t brick_count = 0;
|
|
|
d84cf8 |
+ int32_t sub_count = 0;
|
|
|
d84cf8 |
+ struct addrinfo *ai_info = NULL;
|
|
|
d84cf8 |
+ char brick_addr[128] = {
|
|
|
d84cf8 |
+ 0,
|
|
|
d84cf8 |
+ };
|
|
|
d84cf8 |
+ int addrlen = 0;
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+ const char failed_string[2048] =
|
|
|
d84cf8 |
+ "Failed to perform brick order "
|
|
|
d84cf8 |
+ "check. Use 'force' at the end of the command"
|
|
|
d84cf8 |
+ " if you want to override this behavior. ";
|
|
|
d84cf8 |
+ const char found_string[2048] =
|
|
|
d84cf8 |
+ "Multiple bricks of a %s "
|
|
|
d84cf8 |
+ "volume are present on the same server. This "
|
|
|
d84cf8 |
+ "setup is not optimal. Bricks should be on "
|
|
|
d84cf8 |
+ "different nodes to have best fault tolerant "
|
|
|
d84cf8 |
+ "configuration. Use 'force' at the end of the "
|
|
|
d84cf8 |
+ "command if you want to override this "
|
|
|
d84cf8 |
+ "behavior. ";
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+ this = THIS;
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+ GF_ASSERT(this);
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+ ai_list = MALLOC(sizeof(addrinfo_list_t));
|
|
|
d84cf8 |
+ ai_list->info = NULL;
|
|
|
d84cf8 |
+ CDS_INIT_LIST_HEAD(&ai_list->list);
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+ ret = dict_get_strn(dict, "volname", SLEN("volname"), &volname);
|
|
|
d84cf8 |
+ if (ret) {
|
|
|
d84cf8 |
+ gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
|
|
|
d84cf8 |
+ "Unable to get volume name");
|
|
|
d84cf8 |
+ goto out;
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+ ret = dict_get_strn(dict, "bricks", SLEN("bricks"), &brick_list);
|
|
|
d84cf8 |
+ if (ret) {
|
|
|
d84cf8 |
+ gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
|
|
|
d84cf8 |
+ "Bricks check : Could not "
|
|
|
d84cf8 |
+ "retrieve bricks list");
|
|
|
d84cf8 |
+ goto out;
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+ ret = dict_get_int32n(dict, "count", SLEN("count"), &brick_count);
|
|
|
d84cf8 |
+ if (ret) {
|
|
|
d84cf8 |
+ gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
|
|
|
d84cf8 |
+ "Bricks check : Could not "
|
|
|
d84cf8 |
+ "retrieve brick count");
|
|
|
d84cf8 |
+ goto out;
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+ if (type != GF_CLUSTER_TYPE_DISPERSE) {
|
|
|
d84cf8 |
+ ret = dict_get_int32n(dict, "replica-count", SLEN("replica-count"),
|
|
|
d84cf8 |
+ &sub_count);
|
|
|
d84cf8 |
+ if (ret) {
|
|
|
d84cf8 |
+ gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
|
|
|
d84cf8 |
+ "Bricks check : Could"
|
|
|
d84cf8 |
+ " not retrieve replica count");
|
|
|
d84cf8 |
+ goto out;
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ gf_msg_debug(this->name, 0,
|
|
|
d84cf8 |
+ "Replicate cluster type "
|
|
|
d84cf8 |
+ "found. Checking brick order.");
|
|
|
d84cf8 |
+ } else {
|
|
|
d84cf8 |
+ ret = dict_get_int32n(dict, "disperse-count", SLEN("disperse-count"),
|
|
|
d84cf8 |
+ &sub_count);
|
|
|
d84cf8 |
+ if (ret) {
|
|
|
d84cf8 |
+ gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
|
|
|
d84cf8 |
+ "Bricks check : Could"
|
|
|
d84cf8 |
+ " not retrieve disperse count");
|
|
|
d84cf8 |
+ goto out;
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_DISPERSE_CLUSTER_FOUND,
|
|
|
d84cf8 |
+ "Disperse cluster type"
|
|
|
d84cf8 |
+ " found. Checking brick order.");
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ brick_list_dup = brick_list_ptr = gf_strdup(brick_list);
|
|
|
d84cf8 |
+ /* Resolve hostnames and get addrinfo */
|
|
|
d84cf8 |
+ while (i < brick_count) {
|
|
|
d84cf8 |
+ ++i;
|
|
|
d84cf8 |
+ brick = strtok_r(brick_list_dup, " \n", &tmpptr);
|
|
|
d84cf8 |
+ brick_list_dup = tmpptr;
|
|
|
d84cf8 |
+ if (brick == NULL)
|
|
|
d84cf8 |
+ goto check_failed;
|
|
|
d84cf8 |
+ tmpptr = strrchr(brick, ':');
|
|
|
d84cf8 |
+ if (tmpptr == NULL)
|
|
|
d84cf8 |
+ goto check_failed;
|
|
|
d84cf8 |
+ addrlen = strlen(brick) - strlen(tmpptr);
|
|
|
d84cf8 |
+ strncpy(brick_addr, brick, addrlen);
|
|
|
d84cf8 |
+ brick_addr[addrlen] = '\0';
|
|
|
d84cf8 |
+ ret = getaddrinfo(brick_addr, NULL, NULL, &ai_info);
|
|
|
d84cf8 |
+ if (ret != 0) {
|
|
|
d84cf8 |
+ ret = 0;
|
|
|
d84cf8 |
+ gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_HOSTNAME_RESOLVE_FAIL,
|
|
|
d84cf8 |
+ "unable to resolve host name for addr %s", brick_addr);
|
|
|
d84cf8 |
+ goto out;
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ ai_list_tmp1 = MALLOC(sizeof(addrinfo_list_t));
|
|
|
d84cf8 |
+ if (ai_list_tmp1 == NULL) {
|
|
|
d84cf8 |
+ ret = 0;
|
|
|
d84cf8 |
+ gf_msg(this->name, GF_LOG_ERROR, ENOMEM, GD_MSG_NO_MEMORY,
|
|
|
d84cf8 |
+ "failed to allocate "
|
|
|
d84cf8 |
+ "memory");
|
|
|
d84cf8 |
+ freeaddrinfo(ai_info);
|
|
|
d84cf8 |
+ goto out;
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ ai_list_tmp1->info = ai_info;
|
|
|
d84cf8 |
+ cds_list_add_tail(&ai_list_tmp1->list, &ai_list->list);
|
|
|
d84cf8 |
+ ai_list_tmp1 = NULL;
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+ i = 0;
|
|
|
d84cf8 |
+ ai_list_tmp1 = cds_list_entry(ai_list->list.next, addrinfo_list_t, list);
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+ /* Check for bad brick order */
|
|
|
d84cf8 |
+ while (i < brick_count) {
|
|
|
d84cf8 |
+ ++i;
|
|
|
d84cf8 |
+ ai_info = ai_list_tmp1->info;
|
|
|
d84cf8 |
+ ai_list_tmp1 = cds_list_entry(ai_list_tmp1->list.next, addrinfo_list_t,
|
|
|
d84cf8 |
+ list);
|
|
|
d84cf8 |
+ if (0 == i % sub_count) {
|
|
|
d84cf8 |
+ j = 0;
|
|
|
d84cf8 |
+ continue;
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ ai_list_tmp2 = ai_list_tmp1;
|
|
|
d84cf8 |
+ k = j;
|
|
|
d84cf8 |
+ while (k < sub_count - 1) {
|
|
|
d84cf8 |
+ ++k;
|
|
|
d84cf8 |
+ ret = glusterd_compare_addrinfo(ai_info, ai_list_tmp2->info);
|
|
|
d84cf8 |
+ if (GF_AI_COMPARE_ERROR == ret)
|
|
|
d84cf8 |
+ goto check_failed;
|
|
|
d84cf8 |
+ if (GF_AI_COMPARE_MATCH == ret)
|
|
|
d84cf8 |
+ goto found_bad_brick_order;
|
|
|
d84cf8 |
+ ai_list_tmp2 = cds_list_entry(ai_list_tmp2->list.next,
|
|
|
d84cf8 |
+ addrinfo_list_t, list);
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ ++j;
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ gf_msg_debug(this->name, 0, "Brick order okay");
|
|
|
d84cf8 |
+ ret = 0;
|
|
|
d84cf8 |
+ goto out;
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+check_failed:
|
|
|
d84cf8 |
+ gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BAD_BRKORDER_CHECK_FAIL,
|
|
|
d84cf8 |
+ "Failed bad brick order check");
|
|
|
d84cf8 |
+ snprintf(err_str, sizeof(failed_string), failed_string);
|
|
|
d84cf8 |
+ ret = -1;
|
|
|
d84cf8 |
+ goto out;
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+found_bad_brick_order:
|
|
|
d84cf8 |
+ gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_BAD_BRKORDER,
|
|
|
d84cf8 |
+ "Bad brick order found");
|
|
|
d84cf8 |
+ if (type == GF_CLUSTER_TYPE_DISPERSE) {
|
|
|
d84cf8 |
+ snprintf(err_str, sizeof(found_string), found_string, "disperse");
|
|
|
d84cf8 |
+ } else {
|
|
|
d84cf8 |
+ snprintf(err_str, sizeof(found_string), found_string, "replicate");
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+ ret = -1;
|
|
|
d84cf8 |
+out:
|
|
|
d84cf8 |
+ ai_list_tmp2 = NULL;
|
|
|
d84cf8 |
+ GF_FREE(brick_list_ptr);
|
|
|
d84cf8 |
+ cds_list_for_each_entry(ai_list_tmp1, &ai_list->list, list)
|
|
|
d84cf8 |
+ {
|
|
|
d84cf8 |
+ if (ai_list_tmp1->info)
|
|
|
d84cf8 |
+ freeaddrinfo(ai_list_tmp1->info);
|
|
|
d84cf8 |
+ free(ai_list_tmp2);
|
|
|
d84cf8 |
+ ai_list_tmp2 = ai_list_tmp1;
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ free(ai_list_tmp2);
|
|
|
d84cf8 |
+ return ret;
|
|
|
d84cf8 |
+}
|
|
|
d84cf8 |
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
|
|
|
d84cf8 |
index ead16b2..e2e2454 100644
|
|
|
d84cf8 |
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
|
|
|
d84cf8 |
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
|
|
|
d84cf8 |
@@ -881,4 +881,8 @@ glusterd_is_profile_on(glusterd_volinfo_t *volinfo);
|
|
|
d84cf8 |
|
|
|
d84cf8 |
char *
|
|
|
d84cf8 |
search_brick_path_from_proc(pid_t brick_pid, char *brickpath);
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+int32_t
|
|
|
d84cf8 |
+glusterd_check_brick_order(dict_t *dict, char *err_str, int32_t type);
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
#endif
|
|
|
d84cf8 |
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
|
|
|
d84cf8 |
index 93042ab..8da2ff3 100644
|
|
|
d84cf8 |
--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
|
|
|
d84cf8 |
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
|
|
|
d84cf8 |
@@ -41,240 +41,6 @@
|
|
|
d84cf8 |
#define glusterd_op_start_volume_args_get(dict, volname, flags) \
|
|
|
d84cf8 |
glusterd_op_stop_volume_args_get(dict, volname, flags)
|
|
|
d84cf8 |
|
|
|
d84cf8 |
-gf_ai_compare_t
|
|
|
d84cf8 |
-glusterd_compare_addrinfo(struct addrinfo *first, struct addrinfo *next)
|
|
|
d84cf8 |
-{
|
|
|
d84cf8 |
- int ret = -1;
|
|
|
d84cf8 |
- struct addrinfo *tmp1 = NULL;
|
|
|
d84cf8 |
- struct addrinfo *tmp2 = NULL;
|
|
|
d84cf8 |
- char firstip[NI_MAXHOST] = {0.};
|
|
|
d84cf8 |
- char nextip[NI_MAXHOST] = {
|
|
|
d84cf8 |
- 0,
|
|
|
d84cf8 |
- };
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
- for (tmp1 = first; tmp1 != NULL; tmp1 = tmp1->ai_next) {
|
|
|
d84cf8 |
- ret = getnameinfo(tmp1->ai_addr, tmp1->ai_addrlen, firstip, NI_MAXHOST,
|
|
|
d84cf8 |
- NULL, 0, NI_NUMERICHOST);
|
|
|
d84cf8 |
- if (ret)
|
|
|
d84cf8 |
- return GF_AI_COMPARE_ERROR;
|
|
|
d84cf8 |
- for (tmp2 = next; tmp2 != NULL; tmp2 = tmp2->ai_next) {
|
|
|
d84cf8 |
- ret = getnameinfo(tmp2->ai_addr, tmp2->ai_addrlen, nextip,
|
|
|
d84cf8 |
- NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
|
|
|
d84cf8 |
- if (ret)
|
|
|
d84cf8 |
- return GF_AI_COMPARE_ERROR;
|
|
|
d84cf8 |
- if (!strcmp(firstip, nextip)) {
|
|
|
d84cf8 |
- return GF_AI_COMPARE_MATCH;
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
- return GF_AI_COMPARE_NO_MATCH;
|
|
|
d84cf8 |
-}
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
-/* Check for non optimal brick order for replicate :
|
|
|
d84cf8 |
- * Checks if bricks belonging to a replicate volume
|
|
|
d84cf8 |
- * are present on the same server
|
|
|
d84cf8 |
- */
|
|
|
d84cf8 |
-int32_t
|
|
|
d84cf8 |
-glusterd_check_brick_order(dict_t *dict, char *err_str)
|
|
|
d84cf8 |
-{
|
|
|
d84cf8 |
- int ret = -1;
|
|
|
d84cf8 |
- int i = 0;
|
|
|
d84cf8 |
- int j = 0;
|
|
|
d84cf8 |
- int k = 0;
|
|
|
d84cf8 |
- xlator_t *this = NULL;
|
|
|
d84cf8 |
- addrinfo_list_t *ai_list = NULL;
|
|
|
d84cf8 |
- addrinfo_list_t *ai_list_tmp1 = NULL;
|
|
|
d84cf8 |
- addrinfo_list_t *ai_list_tmp2 = NULL;
|
|
|
d84cf8 |
- char *brick = NULL;
|
|
|
d84cf8 |
- char *brick_list = NULL;
|
|
|
d84cf8 |
- char *brick_list_dup = NULL;
|
|
|
d84cf8 |
- char *brick_list_ptr = NULL;
|
|
|
d84cf8 |
- char *tmpptr = NULL;
|
|
|
d84cf8 |
- char *volname = NULL;
|
|
|
d84cf8 |
- int32_t brick_count = 0;
|
|
|
d84cf8 |
- int32_t type = GF_CLUSTER_TYPE_NONE;
|
|
|
d84cf8 |
- int32_t sub_count = 0;
|
|
|
d84cf8 |
- struct addrinfo *ai_info = NULL;
|
|
|
d84cf8 |
- char brick_addr[128] = {
|
|
|
d84cf8 |
- 0,
|
|
|
d84cf8 |
- };
|
|
|
d84cf8 |
- int addrlen = 0;
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
- const char failed_string[2048] =
|
|
|
d84cf8 |
- "Failed to perform brick order "
|
|
|
d84cf8 |
- "check. Use 'force' at the end of the command"
|
|
|
d84cf8 |
- " if you want to override this behavior. ";
|
|
|
d84cf8 |
- const char found_string[2048] =
|
|
|
d84cf8 |
- "Multiple bricks of a %s "
|
|
|
d84cf8 |
- "volume are present on the same server. This "
|
|
|
d84cf8 |
- "setup is not optimal. Bricks should be on "
|
|
|
d84cf8 |
- "different nodes to have best fault tolerant "
|
|
|
d84cf8 |
- "configuration. Use 'force' at the end of the "
|
|
|
d84cf8 |
- "command if you want to override this "
|
|
|
d84cf8 |
- "behavior. ";
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
- this = THIS;
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
- GF_ASSERT(this);
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
- ai_list = MALLOC(sizeof(addrinfo_list_t));
|
|
|
d84cf8 |
- ai_list->info = NULL;
|
|
|
d84cf8 |
- CDS_INIT_LIST_HEAD(&ai_list->list);
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
- ret = dict_get_strn(dict, "volname", SLEN("volname"), &volname);
|
|
|
d84cf8 |
- if (ret) {
|
|
|
d84cf8 |
- gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
|
|
|
d84cf8 |
- "Unable to get volume name");
|
|
|
d84cf8 |
- goto out;
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
- ret = dict_get_int32n(dict, "type", SLEN("type"), &type);
|
|
|
d84cf8 |
- if (ret) {
|
|
|
d84cf8 |
- snprintf(err_str, 512, "Unable to get type of volume %s", volname);
|
|
|
d84cf8 |
- gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_DICT_GET_FAILED, "%s",
|
|
|
d84cf8 |
- err_str);
|
|
|
d84cf8 |
- goto out;
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
- ret = dict_get_strn(dict, "bricks", SLEN("bricks"), &brick_list);
|
|
|
d84cf8 |
- if (ret) {
|
|
|
d84cf8 |
- gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
|
|
|
d84cf8 |
- "Bricks check : Could not "
|
|
|
d84cf8 |
- "retrieve bricks list");
|
|
|
d84cf8 |
- goto out;
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
- ret = dict_get_int32n(dict, "count", SLEN("count"), &brick_count);
|
|
|
d84cf8 |
- if (ret) {
|
|
|
d84cf8 |
- gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
|
|
|
d84cf8 |
- "Bricks check : Could not "
|
|
|
d84cf8 |
- "retrieve brick count");
|
|
|
d84cf8 |
- goto out;
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
- if (type != GF_CLUSTER_TYPE_DISPERSE) {
|
|
|
d84cf8 |
- ret = dict_get_int32n(dict, "replica-count", SLEN("replica-count"),
|
|
|
d84cf8 |
- &sub_count);
|
|
|
d84cf8 |
- if (ret) {
|
|
|
d84cf8 |
- gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
|
|
|
d84cf8 |
- "Bricks check : Could"
|
|
|
d84cf8 |
- " not retrieve replica count");
|
|
|
d84cf8 |
- goto out;
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
- gf_msg_debug(this->name, 0,
|
|
|
d84cf8 |
- "Replicate cluster type "
|
|
|
d84cf8 |
- "found. Checking brick order.");
|
|
|
d84cf8 |
- } else {
|
|
|
d84cf8 |
- ret = dict_get_int32n(dict, "disperse-count", SLEN("disperse-count"),
|
|
|
d84cf8 |
- &sub_count);
|
|
|
d84cf8 |
- if (ret) {
|
|
|
d84cf8 |
- gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
|
|
|
d84cf8 |
- "Bricks check : Could"
|
|
|
d84cf8 |
- " not retrieve disperse count");
|
|
|
d84cf8 |
- goto out;
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
- gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_DISPERSE_CLUSTER_FOUND,
|
|
|
d84cf8 |
- "Disperse cluster type"
|
|
|
d84cf8 |
- " found. Checking brick order.");
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
- brick_list_dup = brick_list_ptr = gf_strdup(brick_list);
|
|
|
d84cf8 |
- /* Resolve hostnames and get addrinfo */
|
|
|
d84cf8 |
- while (i < brick_count) {
|
|
|
d84cf8 |
- ++i;
|
|
|
d84cf8 |
- brick = strtok_r(brick_list_dup, " \n", &tmpptr);
|
|
|
d84cf8 |
- brick_list_dup = tmpptr;
|
|
|
d84cf8 |
- if (brick == NULL)
|
|
|
d84cf8 |
- goto check_failed;
|
|
|
d84cf8 |
- tmpptr = strrchr(brick, ':');
|
|
|
d84cf8 |
- if (tmpptr == NULL)
|
|
|
d84cf8 |
- goto check_failed;
|
|
|
d84cf8 |
- addrlen = strlen(brick) - strlen(tmpptr);
|
|
|
d84cf8 |
- strncpy(brick_addr, brick, addrlen);
|
|
|
d84cf8 |
- brick_addr[addrlen] = '\0';
|
|
|
d84cf8 |
- ret = getaddrinfo(brick_addr, NULL, NULL, &ai_info);
|
|
|
d84cf8 |
- if (ret != 0) {
|
|
|
d84cf8 |
- ret = 0;
|
|
|
d84cf8 |
- gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_HOSTNAME_RESOLVE_FAIL,
|
|
|
d84cf8 |
- "unable to resolve host name for addr %s", brick_addr);
|
|
|
d84cf8 |
- goto out;
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
- ai_list_tmp1 = MALLOC(sizeof(addrinfo_list_t));
|
|
|
d84cf8 |
- if (ai_list_tmp1 == NULL) {
|
|
|
d84cf8 |
- ret = 0;
|
|
|
d84cf8 |
- gf_msg(this->name, GF_LOG_ERROR, ENOMEM, GD_MSG_NO_MEMORY,
|
|
|
d84cf8 |
- "failed to allocate "
|
|
|
d84cf8 |
- "memory");
|
|
|
d84cf8 |
- freeaddrinfo(ai_info);
|
|
|
d84cf8 |
- goto out;
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
- ai_list_tmp1->info = ai_info;
|
|
|
d84cf8 |
- cds_list_add_tail(&ai_list_tmp1->list, &ai_list->list);
|
|
|
d84cf8 |
- ai_list_tmp1 = NULL;
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
- i = 0;
|
|
|
d84cf8 |
- ai_list_tmp1 = cds_list_entry(ai_list->list.next, addrinfo_list_t, list);
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
- /* Check for bad brick order */
|
|
|
d84cf8 |
- while (i < brick_count) {
|
|
|
d84cf8 |
- ++i;
|
|
|
d84cf8 |
- ai_info = ai_list_tmp1->info;
|
|
|
d84cf8 |
- ai_list_tmp1 = cds_list_entry(ai_list_tmp1->list.next, addrinfo_list_t,
|
|
|
d84cf8 |
- list);
|
|
|
d84cf8 |
- if (0 == i % sub_count) {
|
|
|
d84cf8 |
- j = 0;
|
|
|
d84cf8 |
- continue;
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
- ai_list_tmp2 = ai_list_tmp1;
|
|
|
d84cf8 |
- k = j;
|
|
|
d84cf8 |
- while (k < sub_count - 1) {
|
|
|
d84cf8 |
- ++k;
|
|
|
d84cf8 |
- ret = glusterd_compare_addrinfo(ai_info, ai_list_tmp2->info);
|
|
|
d84cf8 |
- if (GF_AI_COMPARE_ERROR == ret)
|
|
|
d84cf8 |
- goto check_failed;
|
|
|
d84cf8 |
- if (GF_AI_COMPARE_MATCH == ret)
|
|
|
d84cf8 |
- goto found_bad_brick_order;
|
|
|
d84cf8 |
- ai_list_tmp2 = cds_list_entry(ai_list_tmp2->list.next,
|
|
|
d84cf8 |
- addrinfo_list_t, list);
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
- ++j;
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
- gf_msg_debug(this->name, 0, "Brick order okay");
|
|
|
d84cf8 |
- ret = 0;
|
|
|
d84cf8 |
- goto out;
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
-check_failed:
|
|
|
d84cf8 |
- gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BAD_BRKORDER_CHECK_FAIL,
|
|
|
d84cf8 |
- "Failed bad brick order check");
|
|
|
d84cf8 |
- snprintf(err_str, sizeof(failed_string), failed_string);
|
|
|
d84cf8 |
- ret = -1;
|
|
|
d84cf8 |
- goto out;
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
-found_bad_brick_order:
|
|
|
d84cf8 |
- gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_BAD_BRKORDER,
|
|
|
d84cf8 |
- "Bad brick order found");
|
|
|
d84cf8 |
- if (type == GF_CLUSTER_TYPE_DISPERSE) {
|
|
|
d84cf8 |
- snprintf(err_str, sizeof(found_string), found_string, "disperse");
|
|
|
d84cf8 |
- } else {
|
|
|
d84cf8 |
- snprintf(err_str, sizeof(found_string), found_string, "replicate");
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
- ret = -1;
|
|
|
d84cf8 |
-out:
|
|
|
d84cf8 |
- ai_list_tmp2 = NULL;
|
|
|
d84cf8 |
- GF_FREE(brick_list_ptr);
|
|
|
d84cf8 |
- cds_list_for_each_entry(ai_list_tmp1, &ai_list->list, list)
|
|
|
d84cf8 |
- {
|
|
|
d84cf8 |
- if (ai_list_tmp1->info)
|
|
|
d84cf8 |
- freeaddrinfo(ai_list_tmp1->info);
|
|
|
d84cf8 |
- free(ai_list_tmp2);
|
|
|
d84cf8 |
- ai_list_tmp2 = ai_list_tmp1;
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
- free(ai_list_tmp2);
|
|
|
d84cf8 |
- return ret;
|
|
|
d84cf8 |
-}
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
int
|
|
|
d84cf8 |
__glusterd_handle_create_volume(rpcsvc_request_t *req)
|
|
|
d84cf8 |
{
|
|
|
d84cf8 |
@@ -1337,6 +1103,35 @@ glusterd_op_stage_create_volume(dict_t *dict, char **op_errstr,
|
|
|
d84cf8 |
}
|
|
|
d84cf8 |
}
|
|
|
d84cf8 |
|
|
|
d84cf8 |
+ /*Check brick order if the volume type is replicate or disperse. If
|
|
|
d84cf8 |
+ * force at the end of command not given then check brick order.
|
|
|
d84cf8 |
+ */
|
|
|
d84cf8 |
+ if (is_origin_glusterd(dict)) {
|
|
|
d84cf8 |
+ ret = dict_get_int32n(dict, "type", SLEN("type"), &type);
|
|
|
d84cf8 |
+ if (ret) {
|
|
|
d84cf8 |
+ snprintf(msg, sizeof(msg),
|
|
|
d84cf8 |
+ "Unable to get type of "
|
|
|
d84cf8 |
+ "volume %s",
|
|
|
d84cf8 |
+ volname);
|
|
|
d84cf8 |
+ gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_DICT_GET_FAILED, "%s",
|
|
|
d84cf8 |
+ msg);
|
|
|
d84cf8 |
+ goto out;
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
+ if (!is_force) {
|
|
|
d84cf8 |
+ if ((type == GF_CLUSTER_TYPE_REPLICATE) ||
|
|
|
d84cf8 |
+ (type == GF_CLUSTER_TYPE_DISPERSE)) {
|
|
|
d84cf8 |
+ ret = glusterd_check_brick_order(dict, msg, type);
|
|
|
d84cf8 |
+ if (ret) {
|
|
|
d84cf8 |
+ gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BAD_BRKORDER,
|
|
|
d84cf8 |
+ "Not creating volume because of "
|
|
|
d84cf8 |
+ "bad brick order");
|
|
|
d84cf8 |
+ goto out;
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+ }
|
|
|
d84cf8 |
+
|
|
|
d84cf8 |
while (i < brick_count) {
|
|
|
d84cf8 |
i++;
|
|
|
d84cf8 |
brick = strtok_r(brick_list, " \n", &tmpptr);
|
|
|
d84cf8 |
@@ -1423,36 +1218,6 @@ glusterd_op_stage_create_volume(dict_t *dict, char **op_errstr,
|
|
|
d84cf8 |
brick_info = NULL;
|
|
|
d84cf8 |
}
|
|
|
d84cf8 |
|
|
|
d84cf8 |
- /*Check brick order if the volume type is replicate or disperse. If
|
|
|
d84cf8 |
- * force at the end of command not given then check brick order.
|
|
|
d84cf8 |
- */
|
|
|
d84cf8 |
- if (is_origin_glusterd(dict)) {
|
|
|
d84cf8 |
- ret = dict_get_int32n(dict, "type", SLEN("type"), &type);
|
|
|
d84cf8 |
- if (ret) {
|
|
|
d84cf8 |
- snprintf(msg, sizeof(msg),
|
|
|
d84cf8 |
- "Unable to get type of "
|
|
|
d84cf8 |
- "volume %s",
|
|
|
d84cf8 |
- volname);
|
|
|
d84cf8 |
- gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_DICT_GET_FAILED, "%s",
|
|
|
d84cf8 |
- msg);
|
|
|
d84cf8 |
- goto out;
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
- if (!is_force) {
|
|
|
d84cf8 |
- if ((type == GF_CLUSTER_TYPE_REPLICATE) ||
|
|
|
d84cf8 |
- (type == GF_CLUSTER_TYPE_DISPERSE)) {
|
|
|
d84cf8 |
- ret = glusterd_check_brick_order(dict, msg);
|
|
|
d84cf8 |
- if (ret) {
|
|
|
d84cf8 |
- gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_BAD_BRKORDER,
|
|
|
d84cf8 |
- "Not "
|
|
|
d84cf8 |
- "creating volume because of "
|
|
|
d84cf8 |
- "bad brick order");
|
|
|
d84cf8 |
- goto out;
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
- }
|
|
|
d84cf8 |
-
|
|
|
d84cf8 |
ret = dict_set_int32n(rsp_dict, "brick_count", SLEN("brick_count"),
|
|
|
d84cf8 |
local_brick_count);
|
|
|
d84cf8 |
if (ret) {
|
|
|
d84cf8 |
--
|
|
|
d84cf8 |
1.8.3.1
|
|
|
d84cf8 |
|