glusterd: compute quorum on peers in cluster
... and not on peers participating in an ongoing transaction. Change-Id: I6bdb80fd3bf3e7593fdf37e45a441d4a490469b8 BUG: 1205592 Signed-off-by: Kaushal M <kaushal@redhat.com> Reviewed-on: http://review.gluster.org/9493 Reviewed-by: Atin Mukherjee <amukherj@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com>
This commit is contained in:
parent
08d35497e3
commit
f66a85a484
30
tests/bugs/snapshot/bug-1205592.t
Normal file
30
tests/bugs/snapshot/bug-1205592.t
Normal file
@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
. $(dirname $0)/../../include.rc
|
||||
. $(dirname $0)/../../cluster.rc
|
||||
. $(dirname $0)/../../volume.rc
|
||||
. $(dirname $0)/../../snapshot.rc
|
||||
|
||||
cleanup;
|
||||
TEST verify_lvm_version
|
||||
TEST launch_cluster 3
|
||||
TEST setup_lvm 3
|
||||
|
||||
TEST $CLI_1 peer probe $H2
|
||||
EXPECT_WITHIN $PROBE_TIMEOUT 1 peer_count
|
||||
|
||||
TEST $CLI_1 peer probe $H3
|
||||
EXPECT_WITHIN $PROBE_TIMEOUT 2 peer_count
|
||||
|
||||
TEST $CLI_1 volume create $V0 $H1:$L1 $H2:$L2 $H3:$L3
|
||||
EXPECT 'Created' volinfo_field $V0 'Status'
|
||||
|
||||
TEST $CLI_1 volume start $V0
|
||||
EXPECT 'Started' volinfo_field $V0 'Status'
|
||||
|
||||
|
||||
kill_glusterd 3
|
||||
# If glusterd-quorum is not met then snapshot-create should fail
|
||||
TEST ! $CLI_1 snapshot create ${V0}_snap1 ${V0} no-timestamp
|
||||
|
||||
cleanup;
|
@ -1046,7 +1046,7 @@ __glusterd_handle_cli_probe (rpcsvc_request_t *req)
|
||||
}
|
||||
|
||||
if (glusterd_is_any_volume_in_server_quorum (this) &&
|
||||
!does_gd_meet_server_quorum (this, NULL, _gf_false)) {
|
||||
!does_gd_meet_server_quorum (this)) {
|
||||
glusterd_xfer_cli_probe_resp (req, -1, GF_PROBE_QUORUM_NOT_MET,
|
||||
NULL, hostname, port, dict);
|
||||
gf_msg (this->name, GF_LOG_CRITICAL, 0,
|
||||
@ -1220,7 +1220,7 @@ __glusterd_handle_cli_deprobe (rpcsvc_request_t *req)
|
||||
|
||||
if (!(flags & GF_CLI_FLAG_OP_FORCE)) {
|
||||
if (glusterd_is_any_volume_in_server_quorum (this) &&
|
||||
!does_gd_meet_server_quorum (this, NULL, _gf_false)) {
|
||||
!does_gd_meet_server_quorum (this)) {
|
||||
gf_msg (this->name, GF_LOG_CRITICAL, 0,
|
||||
GD_MSG_SERVER_QUORUM_NOT_MET,
|
||||
"Server quorum not met. Rejecting operation.");
|
||||
|
@ -1840,8 +1840,7 @@ glusterd_mgmt_v3_initiate_snap_phases (rpcsvc_request_t *req, glusterd_op_t op,
|
||||
}
|
||||
|
||||
/* quorum check of the volume is done here */
|
||||
ret = glusterd_snap_quorum_check (req_dict, _gf_false, &op_errstr,
|
||||
&xaction_peers);
|
||||
ret = glusterd_snap_quorum_check (req_dict, _gf_false, &op_errstr);
|
||||
if (ret) {
|
||||
gf_log (this->name, GF_LOG_WARNING,
|
||||
"Volume quorum check failed");
|
||||
@ -1926,8 +1925,7 @@ unbarrier:
|
||||
/*Do a quorum check if the commit phase is successful*/
|
||||
if (success) {
|
||||
//quorum check of the snapshot volume
|
||||
ret = glusterd_snap_quorum_check (dict, _gf_true, &op_errstr,
|
||||
&xaction_peers);
|
||||
ret = glusterd_snap_quorum_check (dict, _gf_true, &op_errstr);
|
||||
if (ret) {
|
||||
gf_log (this->name, GF_LOG_WARNING,
|
||||
"Snapshot Volume quorum check failed");
|
||||
|
@ -79,8 +79,6 @@ out:
|
||||
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)
|
||||
@ -106,9 +104,7 @@ glusterd_validate_quorum (xlator_t *this, glusterd_op_t op,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Passing NULL implies quorum calculation will happen on global peer
|
||||
* list */
|
||||
if (does_gd_meet_server_quorum (this, NULL, _gf_false)) {
|
||||
if (does_gd_meet_server_quorum (this)) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
@ -128,8 +124,9 @@ 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};
|
||||
static const char * const keys[] = {GLUSTERD_QUORUM_TYPE_KEY,
|
||||
GLUSTERD_QUORUM_RATIO_KEY,
|
||||
NULL};
|
||||
|
||||
for (i = 0; keys[i]; i++) {
|
||||
if (strcmp (option, keys[i]) == 0) {
|
||||
@ -200,9 +197,7 @@ _does_quorum_meet (int active_count, int 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)
|
||||
int *quorum_count)
|
||||
{
|
||||
glusterd_peerinfo_t *peerinfo = NULL;
|
||||
glusterd_conf_t *conf = NULL;
|
||||
@ -221,26 +216,19 @@ glusterd_get_quorum_cluster_counts (xlator_t *this, int *active_count,
|
||||
*active_count = 1;
|
||||
|
||||
rcu_read_lock ();
|
||||
if (!peer_list) {
|
||||
cds_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 {
|
||||
cds_list_for_each_entry (peerinfo, peer_list,
|
||||
op_peers_list) {
|
||||
GLUSTERD_QUORUM_COUNT (peerinfo, inquorum_count,
|
||||
active_count, out);
|
||||
}
|
||||
cds_list_for_each_entry_rcu (peerinfo, &conf->peers, uuid_list) {
|
||||
if (peerinfo->quorum_contrib == QUORUM_WAITING) {
|
||||
rcu_read_unlock ();
|
||||
goto out;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
rcu_read_unlock ();
|
||||
|
||||
ret = dict_get_str (conf->opts, GLUSTERD_QUORUM_RATIO_KEY, &val);
|
||||
if (ret == 0) {
|
||||
ratio = _gf_true;
|
||||
@ -257,7 +245,6 @@ glusterd_get_quorum_cluster_counts (xlator_t *this, int *active_count,
|
||||
*quorum_count = count;
|
||||
ret = 0;
|
||||
out:
|
||||
rcu_read_unlock ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -295,8 +282,7 @@ 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)
|
||||
does_gd_meet_server_quorum (xlator_t *this)
|
||||
{
|
||||
int quorum_count = 0;
|
||||
int active_count = 0;
|
||||
@ -306,9 +292,7 @@ does_gd_meet_server_quorum (xlator_t *this, struct cds_list_head *peers_list,
|
||||
|
||||
conf = this->private;
|
||||
ret = glusterd_get_quorum_cluster_counts (this, &active_count,
|
||||
&quorum_count,
|
||||
peers_list,
|
||||
_local_xaction_peers);
|
||||
&quorum_count);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
@ -406,8 +390,7 @@ glusterd_do_quorum_action ()
|
||||
|
||||
{
|
||||
ret = glusterd_get_quorum_cluster_counts (this, &active_count,
|
||||
&quorum_count, NULL,
|
||||
_gf_false);
|
||||
&quorum_count);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
|
@ -15,18 +15,6 @@
|
||||
#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);
|
||||
@ -39,9 +27,7 @@ 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 *quorum_count);
|
||||
|
||||
gf_boolean_t
|
||||
glusterd_is_quorum_option (char *option);
|
||||
@ -53,7 +39,5 @@ 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);
|
||||
does_gd_meet_server_quorum (xlator_t *this);
|
||||
#endif /* _GLUSTERD_SERVER_QUORUM_H */
|
||||
|
@ -2559,8 +2559,7 @@ out:
|
||||
|
||||
int32_t
|
||||
glusterd_snap_quorum_check_for_create (dict_t *dict, gf_boolean_t snap_volume,
|
||||
char **op_errstr,
|
||||
struct cds_list_head *peers_list)
|
||||
char **op_errstr)
|
||||
{
|
||||
int8_t snap_force = 0;
|
||||
int32_t force = 0;
|
||||
@ -2612,7 +2611,7 @@ glusterd_snap_quorum_check_for_create (dict_t *dict, gf_boolean_t snap_volume,
|
||||
* information will be saved by glusterd and if glusterds are not in
|
||||
* quorum, then better fail the snapshot
|
||||
*/
|
||||
if (!does_gd_meet_server_quorum (this, peers_list, _gf_true)) {
|
||||
if (!does_gd_meet_server_quorum (this)) {
|
||||
snprintf (err_str, sizeof (err_str),
|
||||
"glusterds are not in quorum");
|
||||
gf_log (this->name, GF_LOG_WARNING, "%s", err_str);
|
||||
@ -2748,8 +2747,7 @@ out:
|
||||
|
||||
int32_t
|
||||
glusterd_snap_quorum_check (dict_t *dict, gf_boolean_t snap_volume,
|
||||
char **op_errstr,
|
||||
struct cds_list_head *peers_list)
|
||||
char **op_errstr)
|
||||
{
|
||||
int32_t ret = -1;
|
||||
xlator_t *this = NULL;
|
||||
@ -2775,8 +2773,7 @@ glusterd_snap_quorum_check (dict_t *dict, gf_boolean_t snap_volume,
|
||||
switch (snap_command) {
|
||||
case GF_SNAP_OPTION_TYPE_CREATE:
|
||||
ret = glusterd_snap_quorum_check_for_create (dict, snap_volume,
|
||||
op_errstr,
|
||||
peers_list);
|
||||
op_errstr);
|
||||
if (ret) {
|
||||
gf_log (this->name, GF_LOG_WARNING, "Quorum check"
|
||||
"failed during snapshot create command");
|
||||
@ -2785,7 +2782,7 @@ glusterd_snap_quorum_check (dict_t *dict, gf_boolean_t snap_volume,
|
||||
break;
|
||||
case GF_SNAP_OPTION_TYPE_CLONE:
|
||||
|
||||
if (!does_gd_meet_server_quorum (this, peers_list, _gf_true)) {
|
||||
if (!does_gd_meet_server_quorum (this)) {
|
||||
ret = -1;
|
||||
snprintf (err_str, sizeof (err_str),
|
||||
"glusterds are not in quorum");
|
||||
@ -2800,7 +2797,7 @@ glusterd_snap_quorum_check (dict_t *dict, gf_boolean_t snap_volume,
|
||||
break;
|
||||
case GF_SNAP_OPTION_TYPE_DELETE:
|
||||
case GF_SNAP_OPTION_TYPE_RESTORE:
|
||||
if (!does_gd_meet_server_quorum (this, peers_list, _gf_true)) {
|
||||
if (!does_gd_meet_server_quorum (this)) {
|
||||
ret = -1;
|
||||
snprintf (err_str, sizeof (err_str),
|
||||
"glusterds are not in quorum");
|
||||
|
@ -119,13 +119,11 @@ gd_import_volume_snap_details (dict_t *dict, glusterd_volinfo_t *volinfo,
|
||||
|
||||
int32_t
|
||||
glusterd_snap_quorum_check (dict_t *dict, gf_boolean_t snap_volume,
|
||||
char **op_errstr,
|
||||
struct cds_list_head *peers_list);
|
||||
char **op_errstr);
|
||||
|
||||
int32_t
|
||||
glusterd_snap_quorum_check_for_create (dict_t *dict, gf_boolean_t snap_volume,
|
||||
char **op_errstr,
|
||||
struct cds_list_head *peers_list);
|
||||
char **op_errstr);
|
||||
|
||||
int32_t
|
||||
glusterd_snap_brick_create (glusterd_volinfo_t *snap_volinfo,
|
||||
|
Loading…
x
Reference in New Issue
Block a user