diff options
| -rw-r--r-- | xlators/mgmt/glusterd/src/Makefile.am | 5 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-peer-utils.c | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-server-quorum.c | 423 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-server-quorum.h | 59 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-sm.c | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-syncop.c | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 403 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 34 | 
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);  | 
