diff options
author | GauravKumarGarg <ggarg@redhat.com> | 2014-12-24 16:39:03 +0530 |
---|---|---|
committer | Krishnan Parthasarathi <kparthas@redhat.com> | 2015-01-20 22:38:36 -0800 |
commit | 30ad195d49b971a5389d37c9d9a3583186f3d54a (patch) | |
tree | 84a7e51f14477ddbd1b6cc33f40effc21f692780 /xlators | |
parent | f6a2f152aa9c8a66768e4ba0d1f66737c081639b (diff) |
glusterd: quorum validatation in glusterd syncop framework
Previously glusterd was not checking quorum validation in syncop framework.
So when there is loss in quorum then few operation (for eg. add-brick,
remove-brick, volume set) which is based on syncop framework passed
successfully with out doing quorum validation check.
With this change it will do quorum validation in syncop framework and it will
block all operation (except volume set <quorum options> and "volume reset all"
commands) when there is loss in quorum.
Change-Id: I4c2ef16728d55c98a228bb86795023d9c1f4e9fb
BUG: 1177132
Signed-off-by: Gaurav Kumar Garg <ggarg@redhat.com>
Reviewed-on: http://review.gluster.org/9349
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com>
Tested-by: Krishnan Parthasarathi <kparthas@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 104 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-syncop.c | 11 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 101 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 4 |
4 files changed, 117 insertions, 103 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index a7d1095f4e9..9352b9accab 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -3390,108 +3390,6 @@ out: return ret; } -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_op_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 */ -static int -glusterd_op_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_op_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; -} - static int glusterd_op_ac_send_stage_op (glusterd_op_sm_event_t *event, void *ctx) { @@ -3530,7 +3428,7 @@ glusterd_op_ac_send_stage_op (glusterd_op_sm_event_t *event, void *ctx) goto out; } - ret = glusterd_op_validate_quorum (this, op, dict, &op_errstr); + ret = glusterd_validate_quorum (this, op, dict, &op_errstr); if (ret) { gf_msg (this->name, GF_LOG_CRITICAL, 0, GD_MSG_SERVER_QUORUM_NOT_MET, diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c index 1de9e4603a2..f37aa483a00 100644 --- a/xlators/mgmt/glusterd/src/glusterd-syncop.c +++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c @@ -20,6 +20,7 @@ #include "glusterd-utils.h" #include "glusterd-locks.h" #include "glusterd-snapshot-utils.h" +#include "glusterd-messages.h" extern glusterd_op_info_t opinfo; @@ -1211,6 +1212,8 @@ gd_stage_op_phase (struct list_head *peers, glusterd_op_t op, dict_t *op_ctx, dict_t *aggr_dict = NULL; this = THIS; + GF_ASSERT (this); + rsp_dict = dict_new (); if (!rsp_dict) goto out; @@ -1221,6 +1224,14 @@ gd_stage_op_phase (struct list_head *peers, glusterd_op_t op, dict_t *op_ctx, else aggr_dict = op_ctx; + ret = glusterd_validate_quorum (this, op, req_dict, op_errstr); + if (ret) { + gf_msg (this->name, GF_LOG_CRITICAL, 0, + GD_MSG_SERVER_QUORUM_NOT_MET, + "Server quorum not met. Rejecting operation."); + goto out; + } + ret = glusterd_op_stage_validate (op, req_dict, op_errstr, rsp_dict); if (ret) { hostname = "localhost"; diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index d829676228c..5c2d6f23309 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -1096,6 +1096,107 @@ 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, uuid_t volume_id, char **op_errstr, diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index 274e49e1c22..63be397aeac 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -138,6 +138,10 @@ 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); |