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
[email protected]
http://lists.corosync.org/mailman/listinfo/discuss