Re: [PATCH] totemconfig: check for duplicate node IDs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 07/04/15 15:00, Jan Friesse wrote:
> Chrissie,
> 
> Christine Caulfield napsal(a):
>> On 20/03/15 10:26, Jan Friesse wrote:
>>> Chrissie,
>>> nice idea but I have two comments.
>>> 1. Nodes without nodeid (so auto generated nodeid) are not checked. It
>>> can happen that user enters nodeid which collides with auto generated
>>> nodeid. In practice not very important, but still make sense to make it
>>> right.
>>
>> I've had a look at this and I'm not sure it's feasible. There's no
>> reasonable way I can think of defining a node that's in the nodelist
>> that shouldn't be there because it clashes with the active list.
>>
> 
> I was actually thinking about following scenario:
> 
> nodelist {
>         node {
>                 ring0_addr: 192.168.1.1
>         }
>         node {
>                 ring0_addr: 192.168.1.2
>                 nodeid: decimal form of 192.168.1.1
>         }
> }
> 
> So there are two nodes with same nodeid.
> 
> Does this fall into one of three scenarios you've wrote?
> 
> Because scenario I've described is not properly detected in corosync
> (and it's one of big todo) and corosync will crash. I believe your patch
> will be more complete if it would be able to detect this case.

Attached :)

Chrissie


diff --git a/exec/totemconfig.c b/exec/totemconfig.c
index b678752..f232ea8 100644
--- a/exec/totemconfig.c
+++ b/exec/totemconfig.c
@@ -481,6 +481,120 @@ static int get_cluster_mcast_addr (
 	return (err);
 }
 
+static unsigned int generate_nodeid_for_duplicate_test(
+	struct totem_config *totem_config,
+	char *addr)
+{
+	unsigned int nodeid;
+	struct totem_ip_address totemip;
+
+	/* AF_INET hard-coded here because auto-generated nodeids
+	   are only for IPv4 */
+	if (totemip_parse(&totemip, addr, AF_INET) != 0)
+		return -1;
+
+	memcpy (&nodeid, &totemip.addr, sizeof (unsigned int));
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	nodeid = swab32 (nodeid);
+#endif
+
+	if (totem_config->clear_node_high_bit) {
+		nodeid &= 0x7FFFFFFF;
+	}
+	return nodeid;
+}
+
+static int check_for_duplicate_nodeids(
+	struct totem_config *totem_config,
+	const char **error_string)
+{
+	icmap_iter_t iter;
+	icmap_iter_t subiter;
+	const char *iter_key;
+	int res = 0;
+	int retval = 0;
+	char tmp_key[ICMAP_KEYNAME_MAXLEN];
+	char *ring0_addr=NULL;
+	char *ring0_addr1=NULL;
+	unsigned int node_pos;
+	unsigned int node_pos1;
+	unsigned int nodeid;
+	unsigned int nodeid1;
+	int autogenerated;
+
+	iter = icmap_iter_init("nodelist.node.");
+	while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
+		res = sscanf(iter_key, "nodelist.node.%u.%s", &node_pos, tmp_key);
+		if (res != 2) {
+			continue;
+		}
+
+		if (strcmp(tmp_key, "ring0_addr") != 0) {
+			continue;
+		}
+
+		snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.nodeid", node_pos);
+		autogenerated = 0;
+		if (icmap_get_uint32(tmp_key, &nodeid) != CS_OK) {
+
+			snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.ring0_addr", node_pos);
+			if (icmap_get_string(tmp_key, &ring0_addr) != CS_OK) {
+				continue;
+			}
+
+			/* Generate nodeid so we can check that auto-generated nodeids don't clash either */
+			nodeid = generate_nodeid_for_duplicate_test(totem_config, ring0_addr);
+			if (nodeid == -1) {
+				continue;
+			}
+			autogenerated = 1;
+		}
+
+		node_pos1 = 0;
+		subiter = icmap_iter_init("nodelist.node.");
+		while (((iter_key = icmap_iter_next(subiter, NULL, NULL)) != NULL) && (node_pos1 < node_pos)) {
+			res = sscanf(iter_key, "nodelist.node.%u.%s", &node_pos1, tmp_key);
+			if ((res != 2) || (node_pos1 >= node_pos)) {
+				continue;
+			}
+
+			if (strcmp(tmp_key, "ring0_addr") != 0) {
+				continue;
+			}
+
+			snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.nodeid", node_pos1);
+			if (icmap_get_uint32(tmp_key, &nodeid1) != CS_OK) {
+
+				snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.ring0_addr", node_pos1);
+				if (icmap_get_string(tmp_key, &ring0_addr1) != CS_OK) {
+					continue;
+				}
+				nodeid1 = generate_nodeid_for_duplicate_test(totem_config, ring0_addr1);
+				if (nodeid1 == -1) {
+					continue;
+				}
+			}
+
+			if (nodeid == nodeid1) {
+				retval = -1;
+				snprintf (error_string_response, sizeof(error_string_response),
+					  "Nodeid %u%s%s%s appears twice in corosync.conf", nodeid,
+					  autogenerated?"(autogenerated from ":"",
+					  autogenerated?ring0_addr:"",
+					  autogenerated?")":"");
+				log_printf (LOGSYS_LEVEL_ERROR, error_string_response);
+				*error_string = error_string_response;
+				break;
+			}
+		}
+		icmap_iter_finalize(subiter);
+	}
+	icmap_iter_finalize(iter);
+	return retval;
+}
+
+
 static int find_local_node_in_nodelist(struct totem_config *totem_config)
 {
 	icmap_iter_t iter;
@@ -1236,6 +1350,10 @@ int totem_config_validate (
 		return (-1);
 	}
 
+	if (check_for_duplicate_nodeids(totem_config, error_string) == -1) {
+		return (-1);
+	}
+
 	/*
 	 * RRP values validation
 	 */
_______________________________________________
discuss mailing list
discuss@xxxxxxxxxxxx
http://lists.corosync.org/mailman/listinfo/discuss

[Index of Archives]     [Linux Clusters]     [Corosync Project]     [Linux USB Devel]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Linux Kernel]     [Linux SCSI]     [X.Org]

  Powered by Linux