public inbox for cluster-cvs@sourceware.org
help / color / mirror / Atom feed
* cluster: master - cman: quorum tidying.
@ 2009-01-20 11:03 Christine Caulfield
  0 siblings, 0 replies; only message in thread
From: Christine Caulfield @ 2009-01-20 11:03 UTC (permalink / raw)
  To: cluster-cvs-relay

Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=cb8f019ea31adcce8f9c552f3d2df0ca59ae5b68
Commit:        cb8f019ea31adcce8f9c552f3d2df0ca59ae5b68
Parent:        47a0449477358995395fa21f3f8a898434998b4a
Author:        Christine Caulfield <ccaulfie@redhat.com>
AuthorDate:    Tue Jan 20 11:02:37 2009 +0000
Committer:     Christine Caulfield <ccaulfie@redhat.com>
CommitterDate: Tue Jan 20 11:02:37 2009 +0000

cman: quorum tidying.

Make all instances of nodeid and votes into unsigned values.

Add more validation to votes & expected_votes calls, as per cman.

Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
---
 cman/services/quorum/include/corosync/cmanquorum.h |   14 ++--
 .../quorum/include/corosync/ipc_cmanquorum.h       |    8 +-
 cman/services/quorum/lib/libcmanquorum.c           |    8 +-
 cman/services/quorum/services/cmanquorum.c         |   64 ++++++++++++++++----
 4 files changed, 67 insertions(+), 27 deletions(-)

diff --git a/cman/services/quorum/include/corosync/cmanquorum.h b/cman/services/quorum/include/corosync/cmanquorum.h
index 3705043..3881106 100644
--- a/cman/services/quorum/include/corosync/cmanquorum.h
+++ b/cman/services/quorum/include/corosync/cmanquorum.h
@@ -21,7 +21,7 @@ typedef uint64_t cmanquorum_handle_t;
 /** @} */
 
 struct cmanquorum_info {
-	int node_id;
+	unsigned int node_id;
 	unsigned int node_votes;
 	unsigned int node_expected_votes;
 	unsigned int highest_expected;
@@ -31,8 +31,8 @@ struct cmanquorum_info {
 };
 
 struct cmanquorum_qdisk_info {
-	int votes;
-	int state;
+	unsigned int votes;
+	unsigned int state;
 	char name[CMANQUORUM_MAX_QDISK_NAME_LEN];
 };
 
@@ -82,7 +82,7 @@ cs_error_t cmanquorum_dispatch (
  */
 cs_error_t cmanquorum_getinfo (
 	cmanquorum_handle_t handle,
-	int nodeid,
+	unsigned int nodeid,
 	struct cmanquorum_info *info);
 
 /*
@@ -97,7 +97,7 @@ cs_error_t cmanquorum_setexpected (
  */
 cs_error_t cmanquorum_setvotes (
 	cmanquorum_handle_t handle,
-	int nodeid,
+	unsigned int nodeid,
 	unsigned int votes);
 
 /*
@@ -120,7 +120,7 @@ cs_error_t cmanquorum_qdisk_unregister (
  */
 cs_error_t cmanquorum_qdisk_poll (
 	cmanquorum_handle_t handle,
-	int state);
+	unsigned int state);
 
 /*
  * Get quorum device information
@@ -140,7 +140,7 @@ cs_error_t cmanquorum_setdirty (
  */
 cs_error_t cmanquorum_killnode (
 	cmanquorum_handle_t handle,
-	int nodeid,
+	unsigned int nodeid,
 	unsigned int reason);
 
 /* Track node and quorum changes */
diff --git a/cman/services/quorum/include/corosync/ipc_cmanquorum.h b/cman/services/quorum/include/corosync/ipc_cmanquorum.h
index 4973632..5b04f60 100644
--- a/cman/services/quorum/include/corosync/ipc_cmanquorum.h
+++ b/cman/services/quorum/include/corosync/ipc_cmanquorum.h
@@ -41,7 +41,7 @@ struct req_lib_cmanquorum_setvotes {
 
 struct req_lib_cmanquorum_qdisk_register {
         mar_req_header_t header __attribute__((aligned(8)));
-	int votes;
+	unsigned int votes;
 	char name[CMANQUORUM_MAX_QDISK_NAME_LEN];
 };
 
@@ -52,7 +52,7 @@ struct req_lib_cmanquorum_qdisk_poll {
 
 struct req_lib_cmanquorum_setexpected {
         mar_req_header_t header __attribute__((aligned(8)));
-	int expected_votes;
+	unsigned int expected_votes;
 };
 
 struct req_lib_cmanquorum_trackstart {
@@ -102,8 +102,8 @@ struct res_lib_cmanquorum_getinfo {
 
 struct res_lib_cmanquorum_qdisk_getinfo {
         mar_res_header_t header __attribute__((aligned(8)));
-	int votes;
-	int state;
+	unsigned int votes;
+	unsigned int state;
 	char name[CMANQUORUM_MAX_QDISK_NAME_LEN];
 };
 
diff --git a/cman/services/quorum/lib/libcmanquorum.c b/cman/services/quorum/lib/libcmanquorum.c
index 676a56a..b488367 100644
--- a/cman/services/quorum/lib/libcmanquorum.c
+++ b/cman/services/quorum/lib/libcmanquorum.c
@@ -131,7 +131,7 @@ cs_error_t cmanquorum_finalize (
 
 cs_error_t cmanquorum_getinfo (
 	cmanquorum_handle_t handle,
-	int nodeid,
+	unsigned int nodeid,
 	struct cmanquorum_info *info)
 {
 	cs_error_t error;
@@ -222,7 +222,7 @@ error_exit:
 
 cs_error_t cmanquorum_setvotes (
 	cmanquorum_handle_t handle,
-	int nodeid,
+	unsigned int nodeid,
 	unsigned int votes)
 {
 	cs_error_t error;
@@ -311,7 +311,7 @@ error_exit:
 
 cs_error_t cmanquorum_qdisk_poll (
 	cmanquorum_handle_t handle,
-	int state)
+	unsigned int state)
 {
 	cs_error_t error;
 	struct cmanquorum_inst *cmanquorum_inst;
@@ -516,7 +516,7 @@ error_exit:
 
 cs_error_t cmanquorum_killnode (
 	cmanquorum_handle_t handle,
-	int nodeid,
+	unsigned int nodeid,
 	unsigned int reason)
 {
 	cs_error_t error;
diff --git a/cman/services/quorum/services/cmanquorum.c b/cman/services/quorum/services/cmanquorum.c
index f31859b..100c535 100644
--- a/cman/services/quorum/services/cmanquorum.c
+++ b/cman/services/quorum/services/cmanquorum.c
@@ -380,8 +380,8 @@ struct req_exec_quorum_nodeinfo {
 	unsigned char cmd;
 	unsigned char first_trans;
 	uint16_t cluster_id;
-	int votes;
-	int expected_votes;
+	unsigned int votes;
+	unsigned int expected_votes;
 
 	unsigned int   major_version;	/* Not backwards compatible */
 	unsigned int   minor_version;	/* Backwards compatible */
@@ -638,7 +638,7 @@ static void set_quorate(int total_votes)
 	ENTER();
 }
 
-static int calculate_quorum(int allow_decrease, unsigned int *ret_total_votes)
+static int calculate_quorum(int allow_decrease, int max_expected, unsigned int *ret_total_votes)
 {
 	struct list_head *nodelist;
 	struct cluster_node *node;
@@ -646,7 +646,6 @@ static int calculate_quorum(int allow_decrease, unsigned int *ret_total_votes)
 	unsigned int highest_expected = 0;
 	unsigned int newquorum, q1, q2;
 	unsigned int total_nodes = 0;
-	unsigned int max_expected = 0;
 	unsigned int leaving = 0;
 
 	ENTER();
@@ -657,8 +656,10 @@ static int calculate_quorum(int allow_decrease, unsigned int *ret_total_votes)
 			   node->node_id, node->state, node->votes, node->expected_votes);
 
 		if (node->state == NODESTATE_MEMBER) {
-			highest_expected =
-				max(highest_expected, node->expected_votes);
+			if (max_expected)
+				node->expected_votes = max_expected;
+			else
+				highest_expected = max(highest_expected, node->expected_votes);
 			total_votes += node->votes;
 			total_nodes++;
 		}
@@ -706,7 +707,7 @@ static void recalculate_quorum(int allow_decrease)
 	unsigned int total_votes;
 
 	ENTER();
-	quorum = calculate_quorum(allow_decrease, &total_votes);
+	quorum = calculate_quorum(allow_decrease, 0, &total_votes);
 	set_quorate(total_votes);
 	send_quorum_notification(NULL, 0L);
 	LEAVE();
@@ -975,7 +976,7 @@ static void message_handler_req_exec_quorum_nodeinfo (
 	if (req_exec_quorum_nodeinfo->flags & NODE_FLAGS_SEESDISALLOWED && !have_disallowed()) {
 		/* Must use syslog directly here or the message will never arrive */
 		syslog(LOG_CRIT, "[CMANQ]: Joined a cluster with disallowed nodes. must die");
-		corosync_api->fatal_error(2, __FILE__, __LINE__); // CC:
+		corosync_api->fatal_error(2, __FILE__, __LINE__);
 		exit(2);
 	}
 
@@ -1082,8 +1083,8 @@ static void message_handler_req_lib_cmanquorum_getinfo (void *conn, void *messag
 	struct req_lib_cmanquorum_getinfo *req_lib_cmanquorum_getinfo = (struct req_lib_cmanquorum_getinfo *)message;
 	struct res_lib_cmanquorum_getinfo res_lib_cmanquorum_getinfo;
 	struct cluster_node *node;
-	int highest_expected = 0;
-	int total_votes = 0;
+	unsigned int highest_expected = 0;
+	unsigned int total_votes = 0;
 	cs_error_t error = CS_OK;
 
 	log_printf(LOG_LEVEL_DEBUG, "got getinfo request on %p for node %d\n", conn, req_lib_cmanquorum_getinfo->nodeid);
@@ -1167,14 +1168,32 @@ static void message_handler_req_lib_cmanquorum_setexpected (void *conn, void *me
 	struct req_lib_cmanquorum_setexpected *req_lib_cmanquorum_setexpected = (struct req_lib_cmanquorum_setexpected *)message;
 	struct res_lib_cmanquorum_status res_lib_cmanquorum_status;
 	cs_error_t error = CS_OK;
+	unsigned int newquorum;
+	unsigned int total_votes;
 
 	ENTER();
 
-	// TODO validate as cman does
+	/*
+	 * If there are disallowed nodes, then we can't allow the user
+	 * to bypass them by fiddling with expected votes.
+	 */
+	if (quorum_flags & CMANQUORUM_FLAG_FEATURE_DISALLOWED && have_disallowed()) {
+		error = -EINVAL;
+		goto error_exit;
+	}
+
+	/* Validate new expected votes */
+	newquorum = calculate_quorum(1, req_lib_cmanquorum_setexpected->expected_votes, &total_votes);
+	if (newquorum < total_votes / 2
+	    || newquorum > total_votes) {
+		error = -EINVAL;
+		goto error_exit;
+	}
 
 	quorum_exec_send_reconfigure(RECONFIG_PARAM_EXPECTED_VOTES, us->node_id, req_lib_cmanquorum_setexpected->expected_votes);
 
 	/* send status */
+error_exit:
 	res_lib_cmanquorum_status.header.size = sizeof(res_lib_cmanquorum_status);
 	res_lib_cmanquorum_status.header.id = MESSAGE_RES_CMANQUORUM_STATUS;
 	res_lib_cmanquorum_status.header.error = error;
@@ -1187,17 +1206,38 @@ static void message_handler_req_lib_cmanquorum_setvotes (void *conn, void *messa
 {
 	struct req_lib_cmanquorum_setvotes *req_lib_cmanquorum_setvotes = (struct req_lib_cmanquorum_setvotes *)message;
 	struct res_lib_cmanquorum_status res_lib_cmanquorum_status;
+	struct cluster_node *node;
+	unsigned int newquorum;
+	unsigned int total_votes;
+	unsigned int saved_votes;
 	cs_error_t error = CS_OK;
 
 	ENTER();
 
-	// TODO validate as cman does
+	node = find_node_by_nodeid(req_lib_cmanquorum_setvotes->nodeid);
+	if (!node) {
+		error = -EINVAL;
+		goto error_exit;
+	}
+
+	/* Check votes is valid */
+	saved_votes = node->votes;
+	node->votes = req_lib_cmanquorum_setvotes->votes;
+
+	newquorum = calculate_quorum(1, 0, &total_votes);
+
+	if (newquorum < total_votes / 2 || newquorum > total_votes) {
+		node->votes = saved_votes;
+		error = -EINVAL;
+		goto error_exit;
+	}
 
 	if (!req_lib_cmanquorum_setvotes->nodeid)
 		req_lib_cmanquorum_setvotes->nodeid = corosync_api->totem_nodeid_get();
 
 	quorum_exec_send_reconfigure(RECONFIG_PARAM_NODE_VOTES, req_lib_cmanquorum_setvotes->nodeid, req_lib_cmanquorum_setvotes->votes);
 
+error_exit:
 	/* send status */
 	res_lib_cmanquorum_status.header.size = sizeof(res_lib_cmanquorum_status);
 	res_lib_cmanquorum_status.header.id = MESSAGE_RES_CMANQUORUM_STATUS;


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2009-01-20 11:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-01-20 11:03 cluster: master - cman: quorum tidying Christine Caulfield

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).