summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd/src')
-rw-r--r--xlators/mgmt/glusterd/src/Makefile.am5
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-peer-utils.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-server-quorum.c423
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-server-quorum.h59
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-syncop.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c403
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h34
11 files changed, 491 insertions, 439 deletions
diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am
index 58a1d2fdb2a..6ca0bf5960f 100644
--- a/xlators/mgmt/glusterd/src/Makefile.am
+++ b/xlators/mgmt/glusterd/src/Makefile.am
@@ -16,7 +16,7 @@ glusterd_la_SOURCES = glusterd.c glusterd-handler.c glusterd-sm.c \
glusterd-proc-mgmt.c glusterd-svc-mgmt.c glusterd-shd-svc.c \
glusterd-nfs-svc.c glusterd-quotad-svc.c glusterd-svc-helper.c \
glusterd-conn-helper.c glusterd-snapd-svc.c glusterd-snapd-svc-helper.c \
- glusterd-bitd-svc.c glusterd-scrub-svc.c
+ glusterd-bitd-svc.c glusterd-scrub-svc.c glusterd-server-quorum.c
glusterd_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
@@ -37,7 +37,8 @@ noinst_HEADERS = glusterd.h glusterd-utils.h glusterd-op-sm.h \
glusterd-svc-mgmt.h glusterd-shd-svc.h glusterd-nfs-svc.h \
glusterd-quotad-svc.h glusterd-svc-helper.h glusterd-snapd-svc.h \
glusterd-snapd-svc-helper.h glusterd-rcu.h glusterd-bitd-svc.h \
- glusterd-scrub-svc.h $(CONTRIBDIR)/userspace-rcu/rculist-extra.h
+ glusterd-scrub-svc.h $(CONTRIBDIR)/userspace-rcu/rculist-extra.h \
+ glusterd-server-quorum.h
AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
-I$(rpclibdir) -I$(CONTRIBDIR)/rbtree \
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index 7cd05f40ddf..03c28c541fe 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -31,6 +31,7 @@
#include "glusterd-sm.h"
#include "glusterd-op-sm.h"
#include "glusterd-utils.h"
+#include "glusterd-server-quorum.h"
#include "glusterd-store.h"
#include "glusterd-locks.h"
#include "glusterd-snapshot-utils.h"
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index 8407c57c4cd..c994d762664 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -49,6 +49,7 @@
#include "glusterd-shd-svc.h"
#include "glusterd-nfs-svc.h"
#include "glusterd-quotad-svc.h"
+#include "glusterd-server-quorum.h"
#include <sys/types.h>
#include <signal.h>
diff --git a/xlators/mgmt/glusterd/src/glusterd-peer-utils.c b/xlators/mgmt/glusterd/src/glusterd-peer-utils.c
index 1626cd799cc..2d555a83193 100644
--- a/xlators/mgmt/glusterd/src/glusterd-peer-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-peer-utils.c
@@ -10,6 +10,7 @@
#include "glusterd-peer-utils.h"
#include "glusterd-store.h"
+#include "glusterd-server-quorum.h"
#include "common-utils.h"
void
diff --git a/xlators/mgmt/glusterd/src/glusterd-server-quorum.c b/xlators/mgmt/glusterd/src/glusterd-server-quorum.c
new file mode 100644
index 00000000000..cb707a0caae
--- /dev/null
+++ b/xlators/mgmt/glusterd/src/glusterd-server-quorum.c
@@ -0,0 +1,423 @@
+/*
+ Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "common-utils.h"
+#include "glusterd.h"
+#include "glusterd-utils.h"
+#include "glusterd-messages.h"
+#include "glusterd-server-quorum.h"
+#include "glusterd-syncop.h"
+#include "glusterd-op-sm.h"
+
+#define CEILING_POS(X) (((X)-(int)(X)) > 0 ? (int)((X)+1) : (int)(X))
+
+static gf_boolean_t
+glusterd_is_get_op (xlator_t *this, glusterd_op_t op, dict_t *dict)
+{
+ char *key = NULL;
+ char *volname = NULL;
+ int ret = 0;
+
+ if (op == GD_OP_STATUS_VOLUME)
+ return _gf_true;
+
+ if (op == GD_OP_SET_VOLUME) {
+ /*check for set volume help*/
+ ret = dict_get_str (dict, "volname", &volname);
+ if (volname &&
+ ((strcmp (volname, "help") == 0) ||
+ (strcmp (volname, "help-xml") == 0))) {
+ ret = dict_get_str (dict, "key1", &key);
+ if (ret < 0)
+ return _gf_true;
+ }
+ }
+ return _gf_false;
+}
+
+gf_boolean_t
+glusterd_is_quorum_validation_required (xlator_t *this, glusterd_op_t op,
+ dict_t *dict)
+{
+ gf_boolean_t required = _gf_true;
+ char *key = NULL;
+ char *key_fixed = NULL;
+ int ret = -1;
+
+ if (glusterd_is_get_op (this, op, dict)) {
+ required = _gf_false;
+ goto out;
+ }
+ if ((op != GD_OP_SET_VOLUME) && (op != GD_OP_RESET_VOLUME))
+ goto out;
+ if (op == GD_OP_SET_VOLUME)
+ ret = dict_get_str (dict, "key1", &key);
+ else if (op == GD_OP_RESET_VOLUME)
+ ret = dict_get_str (dict, "key", &key);
+ if (ret)
+ goto out;
+ ret = glusterd_check_option_exists (key, &key_fixed);
+ if (ret <= 0)
+ goto out;
+ if (key_fixed)
+ key = key_fixed;
+ if (glusterd_is_quorum_option (key))
+ required = _gf_false;
+out:
+ GF_FREE (key_fixed);
+ return required;
+}
+
+/* This function should not be used when the quorum validation needs to happen
+ * on non-global peer list */
+int
+glusterd_validate_quorum (xlator_t *this, glusterd_op_t op,
+ dict_t *dict, char **op_errstr)
+{
+ int ret = 0;
+ char *volname = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ char *errstr = NULL;
+
+ errstr = "Quorum not met. Volume operation not allowed.";
+ if (!glusterd_is_quorum_validation_required (this, op, dict))
+ goto out;
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ ret = 0;
+ goto out;
+ }
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ ret = 0;
+ goto out;
+ }
+
+ /* Passing NULL implies quorum calculation will happen on global peer
+ * list */
+ if (does_gd_meet_server_quorum (this, NULL, _gf_false)) {
+ ret = 0;
+ goto out;
+ }
+
+ if (glusterd_is_volume_in_server_quorum (volinfo)) {
+ ret = -1;
+ *op_errstr = gf_strdup (errstr);
+ goto out;
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+gf_boolean_t
+glusterd_is_quorum_option (char *option)
+{
+ gf_boolean_t res = _gf_false;
+ int i = 0;
+ char *keys[] = {GLUSTERD_QUORUM_TYPE_KEY,
+ GLUSTERD_QUORUM_RATIO_KEY, NULL};
+
+ for (i = 0; keys[i]; i++) {
+ if (strcmp (option, keys[i]) == 0) {
+ res = _gf_true;
+ break;
+ }
+ }
+ return res;
+}
+
+gf_boolean_t
+glusterd_is_quorum_changed (dict_t *options, char *option, char *value)
+{
+ int ret = 0;
+ gf_boolean_t reconfigured = _gf_false;
+ gf_boolean_t all = _gf_false;
+ char *oldquorum = NULL;
+ char *newquorum = NULL;
+ char *oldratio = NULL;
+ char *newratio = NULL;
+
+ if ((strcmp ("all", option) != 0) &&
+ !glusterd_is_quorum_option (option))
+ goto out;
+
+ if (strcmp ("all", option) == 0)
+ all = _gf_true;
+
+ if (all || (strcmp (GLUSTERD_QUORUM_TYPE_KEY, option) == 0)) {
+ newquorum = value;
+ ret = dict_get_str (options, GLUSTERD_QUORUM_TYPE_KEY,
+ &oldquorum);
+ }
+
+ if (all || (strcmp (GLUSTERD_QUORUM_RATIO_KEY, option) == 0)) {
+ newratio = value;
+ ret = dict_get_str (options, GLUSTERD_QUORUM_RATIO_KEY,
+ &oldratio);
+ }
+
+ reconfigured = _gf_true;
+
+ if (oldquorum && newquorum && (strcmp (oldquorum, newquorum) == 0))
+ reconfigured = _gf_false;
+ if (oldratio && newratio && (strcmp (oldratio, newratio) == 0))
+ reconfigured = _gf_false;
+
+ if ((oldratio == NULL) && (newratio == NULL) && (oldquorum == NULL) &&
+ (newquorum == NULL))
+ reconfigured = _gf_false;
+out:
+ return reconfigured;
+}
+
+static inline gf_boolean_t
+_is_contributing_to_quorum (gd_quorum_contrib_t contrib)
+{
+ if ((contrib == QUORUM_UP) || (contrib == QUORUM_DOWN))
+ return _gf_true;
+ return _gf_false;
+}
+
+static inline gf_boolean_t
+_does_quorum_meet (int active_count, int quorum_count)
+{
+ return (active_count >= quorum_count);
+}
+
+int
+glusterd_get_quorum_cluster_counts (xlator_t *this, int *active_count,
+ int *quorum_count,
+ struct list_head *peer_list,
+ gf_boolean_t _local_xaction_peers)
+{
+ glusterd_peerinfo_t *peerinfo = NULL;
+ glusterd_conf_t *conf = NULL;
+ int ret = -1;
+ int inquorum_count = 0;
+ char *val = NULL;
+ double quorum_percentage = 0.0;
+ gf_boolean_t ratio = _gf_false;
+ int count = 0;
+
+ conf = this->private;
+
+ /* Start with counting self */
+ inquorum_count = 1;
+ if (active_count)
+ *active_count = 1;
+
+ if (!peer_list) {
+ list_for_each_entry (peerinfo, &conf->peers, uuid_list) {
+ glusterd_quorum_count(peerinfo, inquorum_count,
+ active_count, out);
+ }
+ } else {
+ if (_local_xaction_peers) {
+ list_for_each_local_xaction_peers (peerinfo,
+ peer_list) {
+ glusterd_quorum_count(peerinfo, inquorum_count,
+ active_count, out);
+ }
+ } else {
+ list_for_each_entry (peerinfo, peer_list,
+ op_peers_list) {
+ glusterd_quorum_count(peerinfo, inquorum_count,
+ active_count, out);
+ }
+ }
+ }
+ ret = dict_get_str (conf->opts, GLUSTERD_QUORUM_RATIO_KEY, &val);
+ if (ret == 0) {
+ ratio = _gf_true;
+ ret = gf_string2percent (val, &quorum_percentage);
+ if (!ret)
+ ratio = _gf_true;
+ }
+ if (ratio)
+ count = CEILING_POS (inquorum_count *
+ quorum_percentage / 100.0);
+ else
+ count = (inquorum_count * 50 / 100) + 1;
+
+ *quorum_count = count;
+ ret = 0;
+out:
+ return ret;
+}
+
+gf_boolean_t
+glusterd_is_volume_in_server_quorum (glusterd_volinfo_t *volinfo)
+{
+ gf_boolean_t res = _gf_false;
+ char *quorum_type = NULL;
+ int ret = 0;
+
+ ret = dict_get_str (volinfo->dict, GLUSTERD_QUORUM_TYPE_KEY,
+ &quorum_type);
+ if (ret)
+ goto out;
+
+ if (strcmp (quorum_type, GLUSTERD_SERVER_QUORUM) == 0)
+ res = _gf_true;
+out:
+ return res;
+}
+
+gf_boolean_t
+glusterd_is_any_volume_in_server_quorum (xlator_t *this)
+{
+ glusterd_conf_t *conf = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+
+ conf = this->private;
+ list_for_each_entry (volinfo, &conf->volumes, vol_list) {
+ if (glusterd_is_volume_in_server_quorum (volinfo)) {
+ return _gf_true;
+ }
+ }
+ return _gf_false;
+}
+
+gf_boolean_t
+does_gd_meet_server_quorum (xlator_t *this, struct list_head *peers_list,
+ gf_boolean_t _local_xaction_peers)
+{
+ int quorum_count = 0;
+ int active_count = 0;
+ gf_boolean_t in = _gf_false;
+ glusterd_conf_t *conf = NULL;
+ int ret = -1;
+
+ conf = this->private;
+ ret = glusterd_get_quorum_cluster_counts (this, &active_count,
+ &quorum_count,
+ peers_list,
+ _local_xaction_peers);
+ if (ret)
+ goto out;
+
+ if (!_does_quorum_meet (active_count, quorum_count)) {
+ goto out;
+ }
+
+ in = _gf_true;
+out:
+ return in;
+}
+
+void
+glusterd_do_volume_quorum_action (xlator_t *this, glusterd_volinfo_t *volinfo,
+ gf_boolean_t meets_quorum)
+{
+ glusterd_brickinfo_t *brickinfo = NULL;
+ glusterd_conf_t *conf = NULL;
+ gd_quorum_status_t quorum_status = NOT_APPLICABLE_QUORUM;
+ gf_boolean_t follows_quorum = _gf_false;
+
+ conf = this->private;
+ if (volinfo->status != GLUSTERD_STATUS_STARTED) {
+ volinfo->quorum_status = NOT_APPLICABLE_QUORUM;
+ goto out;
+ }
+
+ follows_quorum = glusterd_is_volume_in_server_quorum (volinfo);
+ if (follows_quorum) {
+ if (meets_quorum)
+ quorum_status = MEETS_QUORUM;
+ else
+ quorum_status = DOESNT_MEET_QUORUM;
+ } else {
+ quorum_status = NOT_APPLICABLE_QUORUM;
+ }
+
+ /*
+ * The following check is added to prevent spurious brick starts when
+ * events occur that affect quorum.
+ * Example:
+ * There is a cluster of 10 peers. Volume is in quorum. User
+ * takes down one brick from the volume to perform maintenance.
+ * Suddenly one of the peers go down. Cluster is still in quorum. But
+ * because of this 'peer going down' event, quorum is calculated and
+ * the bricks that are down are brought up again. In this process it
+ * also brings up the brick that is purposefully taken down.
+ */
+ if (volinfo->quorum_status == quorum_status)
+ goto out;
+
+ if (quorum_status == MEETS_QUORUM) {
+ gf_msg (this->name, GF_LOG_CRITICAL, 0,
+ GD_MSG_SERVER_QUORUM_MET_STARTING_BRICKS,
+ "Server quorum regained for volume %s. Starting local "
+ "bricks.", volinfo->volname);
+ } else if (quorum_status == DOESNT_MEET_QUORUM) {
+ gf_msg (this->name, GF_LOG_CRITICAL, 0,
+ GD_MSG_SERVER_QUORUM_LOST_STOPPING_BRICKS,
+ "Server quorum lost for volume %s. Stopping local "
+ "bricks.", volinfo->volname);
+ }
+
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ if (!glusterd_is_local_brick (this, volinfo, brickinfo))
+ continue;
+ if (quorum_status == DOESNT_MEET_QUORUM)
+ glusterd_brick_stop (volinfo, brickinfo, _gf_false);
+ else
+ glusterd_brick_start (volinfo, brickinfo, _gf_false);
+ }
+ volinfo->quorum_status = quorum_status;
+out:
+ return;
+}
+
+int
+glusterd_do_quorum_action ()
+{
+ xlator_t *this = NULL;
+ glusterd_conf_t *conf = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ int ret = 0;
+ int active_count = 0;
+ int quorum_count = 0;
+ gf_boolean_t meets = _gf_false;
+
+ this = THIS;
+ conf = this->private;
+
+ conf->pending_quorum_action = _gf_true;
+ ret = glusterd_lock (conf->uuid);
+ if (ret)
+ goto out;
+
+ {
+ ret = glusterd_get_quorum_cluster_counts (this, &active_count,
+ &quorum_count, NULL,
+ _gf_false);
+ if (ret)
+ goto unlock;
+
+ if (_does_quorum_meet (active_count, quorum_count))
+ meets = _gf_true;
+ list_for_each_entry (volinfo, &conf->volumes, vol_list) {
+ glusterd_do_volume_quorum_action (this, volinfo, meets);
+ }
+ }
+unlock:
+ (void)glusterd_unlock (conf->uuid);
+ conf->pending_quorum_action = _gf_false;
+out:
+ return ret;
+}
diff --git a/xlators/mgmt/glusterd/src/glusterd-server-quorum.h b/xlators/mgmt/glusterd/src/glusterd-server-quorum.h
new file mode 100644
index 00000000000..96aba06df24
--- /dev/null
+++ b/xlators/mgmt/glusterd/src/glusterd-server-quorum.h
@@ -0,0 +1,59 @@
+/*
+ Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+#ifndef _GLUSTERD_SERVER_QUORUM_H
+#define _GLUSTERD_SERVER_QUORUM_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#define glusterd_quorum_count(peerinfo, inquorum_count,\
+ active_count, _exit)\
+do {\
+ if (peerinfo->quorum_contrib == QUORUM_WAITING)\
+ goto _exit;\
+ if (_is_contributing_to_quorum (peerinfo->quorum_contrib))\
+ inquorum_count = inquorum_count + 1;\
+ if (active_count && (peerinfo->quorum_contrib == QUORUM_UP))\
+ *active_count = *active_count + 1;\
+} while (0)
+
+
+int
+glusterd_validate_quorum (xlator_t *this, glusterd_op_t op, dict_t *dict,
+ char **op_errstr);
+
+gf_boolean_t
+glusterd_is_quorum_changed (dict_t *options, char *option, char *value);
+
+int
+glusterd_do_quorum_action ();
+
+int
+glusterd_get_quorum_cluster_counts (xlator_t *this, int *active_count,
+ int *quorum_count,
+ struct list_head *peer_list,
+ gf_boolean_t _local__xaction_peers);
+
+gf_boolean_t
+glusterd_is_quorum_option (char *option);
+
+gf_boolean_t
+glusterd_is_volume_in_server_quorum (glusterd_volinfo_t *volinfo);
+
+gf_boolean_t
+glusterd_is_any_volume_in_server_quorum (xlator_t *this);
+
+gf_boolean_t
+does_gd_meet_server_quorum (xlator_t *this,
+ struct list_head *peers_list,
+ gf_boolean_t _local__xaction_peers);
+#endif /* _GLUSTERD_SERVER_QUORUM_H */
diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.c b/xlators/mgmt/glusterd/src/glusterd-sm.c
index db34ef1ddf8..9de701ed6bf 100644
--- a/xlators/mgmt/glusterd/src/glusterd-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-sm.c
@@ -36,6 +36,7 @@
#include "glusterd-utils.h"
#include "glusterd-store.h"
#include "glusterd-snapshot-utils.h"
+#include "glusterd-server-quorum.h"
static struct cds_list_head gd_friend_sm_queue;
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c
index fb22fc1c23e..fb3fad243aa 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c
@@ -30,6 +30,7 @@
#include "glusterd-svc-helper.h"
#include "glusterd-snapd-svc-helper.h"
#include "glusterd-snapshot-utils.h"
+#include "glusterd-server-quorum.h"
/*
* glusterd_snap_geo_rep_restore:
diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c
index 50ecb6b9218..508a3883e6e 100644
--- a/xlators/mgmt/glusterd/src/glusterd-syncop.c
+++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c
@@ -18,6 +18,7 @@
#include "glusterd.h"
#include "glusterd-op-sm.h"
#include "glusterd-utils.h"
+#include "glusterd-server-quorum.h"
#include "glusterd-locks.h"
#include "glusterd-snapshot-utils.h"
#include "glusterd-messages.h"
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 65bd4044164..3195110ece6 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -93,8 +93,6 @@
#define NLMV4_VERSION 4
#define NLMV1_VERSION 1
-#define CEILING_POS(X) (((X)-(int)(X)) > 0 ? (int)((X)+1) : (int)(X))
-
extern struct volopt_map_entry glusterd_volopt_map[];
static glusterd_lock_t lock;
@@ -1106,106 +1104,6 @@ out:
}
#endif
-gf_boolean_t
-glusterd_is_get_op (xlator_t *this, glusterd_op_t op, dict_t *dict)
-{
- char *key = NULL;
- char *volname = NULL;
- int ret = 0;
-
- if (op == GD_OP_STATUS_VOLUME)
- return _gf_true;
-
- if (op == GD_OP_SET_VOLUME) {
- /*check for set volume help*/
- ret = dict_get_str (dict, "volname", &volname);
- if (volname &&
- ((strcmp (volname, "help") == 0) ||
- (strcmp (volname, "help-xml") == 0))) {
- ret = dict_get_str (dict, "key1", &key);
- if (ret < 0)
- return _gf_true;
- }
- }
- return _gf_false;
-}
-
-gf_boolean_t
-glusterd_is_quorum_validation_required (xlator_t *this, glusterd_op_t op,
- dict_t *dict)
-{
- gf_boolean_t required = _gf_true;
- char *key = NULL;
- char *key_fixed = NULL;
- int ret = -1;
-
- if (glusterd_is_get_op (this, op, dict)) {
- required = _gf_false;
- goto out;
- }
- if ((op != GD_OP_SET_VOLUME) && (op != GD_OP_RESET_VOLUME))
- goto out;
- if (op == GD_OP_SET_VOLUME)
- ret = dict_get_str (dict, "key1", &key);
- else if (op == GD_OP_RESET_VOLUME)
- ret = dict_get_str (dict, "key", &key);
- if (ret)
- goto out;
- ret = glusterd_check_option_exists (key, &key_fixed);
- if (ret <= 0)
- goto out;
- if (key_fixed)
- key = key_fixed;
- if (glusterd_is_quorum_option (key))
- required = _gf_false;
-out:
- GF_FREE (key_fixed);
- return required;
-}
-
-/* This function should not be used when the quorum validation needs to happen
- * on non-global peer list */
-int
-glusterd_validate_quorum (xlator_t *this, glusterd_op_t op,
- dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- char *errstr = NULL;
-
- errstr = "Quorum not met. Volume operation not allowed.";
- if (!glusterd_is_quorum_validation_required (this, op, dict))
- goto out;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- ret = 0;
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- ret = 0;
- goto out;
- }
-
- /* Passing NULL implies quorum calculation will happen on global peer
- * list */
- if (does_gd_meet_server_quorum (this, NULL, _gf_false)) {
- ret = 0;
- goto out;
- }
-
- if (glusterd_is_volume_in_server_quorum (volinfo)) {
- ret = -1;
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
- ret = 0;
-out:
- return ret;
-}
int
glusterd_validate_and_create_brickpath (glusterd_brickinfo_t *brickinfo,
@@ -2823,205 +2721,6 @@ out:
}
-gf_boolean_t
-glusterd_is_quorum_option (char *option)
-{
- gf_boolean_t res = _gf_false;
- int i = 0;
- char *keys[] = {GLUSTERD_QUORUM_TYPE_KEY,
- GLUSTERD_QUORUM_RATIO_KEY, NULL};
-
- for (i = 0; keys[i]; i++) {
- if (strcmp (option, keys[i]) == 0) {
- res = _gf_true;
- break;
- }
- }
- return res;
-}
-
-gf_boolean_t
-glusterd_is_quorum_changed (dict_t *options, char *option, char *value)
-{
- int ret = 0;
- gf_boolean_t reconfigured = _gf_false;
- gf_boolean_t all = _gf_false;
- char *oldquorum = NULL;
- char *newquorum = NULL;
- char *oldratio = NULL;
- char *newratio = NULL;
-
- if ((strcmp ("all", option) != 0) &&
- !glusterd_is_quorum_option (option))
- goto out;
-
- if (strcmp ("all", option) == 0)
- all = _gf_true;
-
- if (all || (strcmp (GLUSTERD_QUORUM_TYPE_KEY, option) == 0)) {
- newquorum = value;
- ret = dict_get_str (options, GLUSTERD_QUORUM_TYPE_KEY,
- &oldquorum);
- }
-
- if (all || (strcmp (GLUSTERD_QUORUM_RATIO_KEY, option) == 0)) {
- newratio = value;
- ret = dict_get_str (options, GLUSTERD_QUORUM_RATIO_KEY,
- &oldratio);
- }
-
- reconfigured = _gf_true;
-
- if (oldquorum && newquorum && (strcmp (oldquorum, newquorum) == 0))
- reconfigured = _gf_false;
- if (oldratio && newratio && (strcmp (oldratio, newratio) == 0))
- reconfigured = _gf_false;
-
- if ((oldratio == NULL) && (newratio == NULL) && (oldquorum == NULL) &&
- (newquorum == NULL))
- reconfigured = _gf_false;
-out:
- return reconfigured;
-}
-
-static inline gf_boolean_t
-_is_contributing_to_quorum (gd_quorum_contrib_t contrib)
-{
- if ((contrib == QUORUM_UP) || (contrib == QUORUM_DOWN))
- return _gf_true;
- return _gf_false;
-}
-
-static inline gf_boolean_t
-_does_quorum_meet (int active_count, int quorum_count)
-{
- return (active_count >= quorum_count);
-}
-
-int
-glusterd_get_quorum_cluster_counts (xlator_t *this, int *active_count,
- int *quorum_count,
- struct cds_list_head *peer_list,
- gf_boolean_t _local_xaction_peers)
-{
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *conf = NULL;
- int ret = -1;
- int inquorum_count = 0;
- char *val = NULL;
- double quorum_percentage = 0.0;
- gf_boolean_t ratio = _gf_false;
- int count = 0;
-
- conf = this->private;
-
- //Start with counting self
- inquorum_count = 1;
- if (active_count)
- *active_count = 1;
-
- rcu_read_lock ();
- if (!peer_list) {
- cds_list_for_each_entry_rcu (peerinfo, &conf->peers,
- uuid_list) {
- GLUSTERD_QUORUM_COUNT(peerinfo, inquorum_count,
- active_count, out);
- }
- } else {
- if (_local_xaction_peers) {
- list_for_each_local_xaction_peers (peerinfo,
- peer_list) {
- GLUSTERD_QUORUM_COUNT(peerinfo, inquorum_count,
- active_count, out);
- }
- } else {
- cds_list_for_each_entry (peerinfo, peer_list,
- op_peers_list) {
- GLUSTERD_QUORUM_COUNT(peerinfo, inquorum_count,
- active_count, out);
- }
- }
- }
- ret = dict_get_str (conf->opts, GLUSTERD_QUORUM_RATIO_KEY, &val);
- if (ret == 0) {
- ratio = _gf_true;
- ret = gf_string2percent (val, &quorum_percentage);
- if (!ret)
- ratio = _gf_true;
- }
- if (ratio)
- count = CEILING_POS (inquorum_count *
- quorum_percentage / 100.0);
- else
- count = (inquorum_count * 50 / 100) + 1;
-
- *quorum_count = count;
- ret = 0;
-out:
- rcu_read_unlock ();
-
- return ret;
-}
-
-gf_boolean_t
-glusterd_is_volume_in_server_quorum (glusterd_volinfo_t *volinfo)
-{
- gf_boolean_t res = _gf_false;
- char *quorum_type = NULL;
- int ret = 0;
-
- ret = dict_get_str (volinfo->dict, GLUSTERD_QUORUM_TYPE_KEY,
- &quorum_type);
- if (ret)
- goto out;
-
- if (strcmp (quorum_type, GLUSTERD_SERVER_QUORUM) == 0)
- res = _gf_true;
-out:
- return res;
-}
-
-gf_boolean_t
-glusterd_is_any_volume_in_server_quorum (xlator_t *this)
-{
- glusterd_conf_t *conf = NULL;
- glusterd_volinfo_t *volinfo = NULL;
-
- conf = this->private;
- cds_list_for_each_entry (volinfo, &conf->volumes, vol_list) {
- if (glusterd_is_volume_in_server_quorum (volinfo)) {
- return _gf_true;
- }
- }
- return _gf_false;
-}
-
-gf_boolean_t
-does_gd_meet_server_quorum (xlator_t *this, struct cds_list_head *peers_list,
- gf_boolean_t _local_xaction_peers)
-{
- int quorum_count = 0;
- int active_count = 0;
- gf_boolean_t in = _gf_false;
- glusterd_conf_t *conf = NULL;
- int ret = -1;
-
- conf = this->private;
- ret = glusterd_get_quorum_cluster_counts (this, &active_count,
- &quorum_count,
- peers_list,
- _local_xaction_peers);
- if (ret)
- goto out;
-
- if (!_does_quorum_meet (active_count, quorum_count)) {
- goto out;
- }
-
- in = _gf_true;
-out:
- return in;
-}
int
glusterd_spawn_daemons (void *opaque)
@@ -3041,108 +2740,6 @@ glusterd_spawn_daemons (void *opaque)
return ret;
}
-void
-glusterd_do_volume_quorum_action (xlator_t *this, glusterd_volinfo_t *volinfo,
- gf_boolean_t meets_quorum)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_conf_t *conf = NULL;
- gd_quorum_status_t quorum_status = NOT_APPLICABLE_QUORUM;
- gf_boolean_t follows_quorum = _gf_false;
-
- conf = this->private;
- if (volinfo->status != GLUSTERD_STATUS_STARTED) {
- volinfo->quorum_status = NOT_APPLICABLE_QUORUM;
- goto out;
- }
-
- follows_quorum = glusterd_is_volume_in_server_quorum (volinfo);
- if (follows_quorum) {
- if (meets_quorum)
- quorum_status = MEETS_QUORUM;
- else
- quorum_status = DOESNT_MEET_QUORUM;
- } else {
- quorum_status = NOT_APPLICABLE_QUORUM;
- }
-
- /*
- * The following check is added to prevent spurious brick starts when
- * events occur that affect quorum.
- * Example:
- * There is a cluster of 10 peers. Volume is in quorum. User
- * takes down one brick from the volume to perform maintenance.
- * Suddenly one of the peers go down. Cluster is still in quorum. But
- * because of this 'peer going down' event, quorum is calculated and
- * the bricks that are down are brought up again. In this process it
- * also brings up the brick that is purposefully taken down.
- */
- if (volinfo->quorum_status == quorum_status)
- goto out;
-
- if (quorum_status == MEETS_QUORUM) {
- gf_msg (this->name, GF_LOG_CRITICAL, 0,
- GD_MSG_SERVER_QUORUM_MET_STARTING_BRICKS,
- "Server quorum regained for volume %s. Starting local "
- "bricks.", volinfo->volname);
- } else if (quorum_status == DOESNT_MEET_QUORUM) {
- gf_msg (this->name, GF_LOG_CRITICAL, 0,
- GD_MSG_SERVER_QUORUM_LOST_STOPPING_BRICKS,
- "Server quorum lost for volume %s. Stopping local "
- "bricks.", volinfo->volname);
- }
-
- cds_list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (!glusterd_is_local_brick (this, volinfo, brickinfo))
- continue;
- if (quorum_status == DOESNT_MEET_QUORUM)
- glusterd_brick_stop (volinfo, brickinfo, _gf_false);
- else
- glusterd_brick_start (volinfo, brickinfo, _gf_false);
- }
- volinfo->quorum_status = quorum_status;
-out:
- return;
-}
-
-int
-glusterd_do_quorum_action ()
-{
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int ret = 0;
- int active_count = 0;
- int quorum_count = 0;
- gf_boolean_t meets = _gf_false;
-
- this = THIS;
- conf = this->private;
-
- conf->pending_quorum_action = _gf_true;
- ret = glusterd_lock (conf->uuid);
- if (ret)
- goto out;
-
- {
- ret = glusterd_get_quorum_cluster_counts (this, &active_count,
- &quorum_count, NULL,
- _gf_false);
- if (ret)
- goto unlock;
-
- if (_does_quorum_meet (active_count, quorum_count))
- meets = _gf_true;
- cds_list_for_each_entry (volinfo, &conf->volumes, vol_list) {
- glusterd_do_volume_quorum_action (this, volinfo, meets);
- }
- }
-unlock:
- (void)glusterd_unlock (conf->uuid);
- conf->pending_quorum_action = _gf_false;
-out:
- return ret;
-}
int32_t
glusterd_import_friend_volume_opts (dict_t *peer_data, int count,
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index e34b0058f59..abe687eb89c 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -37,15 +37,6 @@
volinfo->volname, brickid);\
} while (0)
-#define GLUSTERD_QUORUM_COUNT(peerinfo, inquorum_count, active_count, _exit) do {\
- if (peerinfo->quorum_contrib == QUORUM_WAITING)\
- goto _exit;\
- if (_is_contributing_to_quorum (peerinfo->quorum_contrib))\
- inquorum_count = inquorum_count + 1;\
- if (active_count && (peerinfo->quorum_contrib == QUORUM_UP))\
- *active_count = *active_count + 1;\
-} while (0)
-
#define list_for_each_local_xaction_peers(xact_peer, xact_peers_head) \
glusterd_local_peers_t *pos = NULL; \
for (pos = cds_list_entry ((xact_peers_head)->next, \
@@ -149,10 +140,6 @@ glusterd_service_stop(const char *service, char *pidfile, int sig,
int
glusterd_get_next_available_brickid (glusterd_volinfo_t *volinfo);
-int
-glusterd_validate_quorum (xlator_t *this, glusterd_op_t op, dict_t *dict,
- char **op_errstr);
-
int32_t
glusterd_resolve_brick (glusterd_brickinfo_t *brickinfo);
@@ -479,29 +466,8 @@ glusterd_set_originator_uuid (dict_t *dict);
gf_boolean_t
is_origin_glusterd (dict_t *dict);
-gf_boolean_t
-glusterd_is_quorum_changed (dict_t *options, char *option, char *value);
-
-int
-glusterd_do_quorum_action ();
-
-int
-glusterd_get_quorum_cluster_counts (xlator_t *this, int *active_count,
- int *quorum_count,
- struct cds_list_head *peer_list,
- gf_boolean_t _local__xaction_peers);
-
int
glusterd_get_next_global_opt_version_str (dict_t *opts, char **version_str);
-gf_boolean_t
-glusterd_is_quorum_option (char *option);
-gf_boolean_t
-glusterd_is_volume_in_server_quorum (glusterd_volinfo_t *volinfo);
-gf_boolean_t
-glusterd_is_any_volume_in_server_quorum (xlator_t *this);
-gf_boolean_t
-does_gd_meet_server_quorum (xlator_t *this, struct cds_list_head *peers_list,
- gf_boolean_t _local__xaction_peers);
int
glusterd_generate_and_set_task_id (dict_t *dict, char *key);