/*
	A_DC_JOIN_PROCESS_REQアクション処理(CRM_OP_JOIN_REQUESTをDCノードが受信した時の処理)
*/
void
do_dc_join_filter_offer(long long action,
	       enum crmd_fsa_cause cause,
	       enum crmd_fsa_state cur_state,
	       enum crmd_fsa_input current_input,
	       fsa_data_t *msg_data)
{
	xmlNode *generation = NULL;

	int cmp = 0;
	int join_id = -1;
	gboolean ack_nack_bool = TRUE;
	const char *ack_nack = CRMD_JOINSTATE_MEMBER;
	ha_msg_input_t *join_ack = fsa_typed_data(fsa_dt_ha_msg);

	const char *join_from = crm_element_value(join_ack->msg, F_CRM_HOST_FROM);
	const char *ref       = crm_element_value(join_ack->msg, XML_ATTR_REFERENCE);
	
	crm_node_t *join_node = crm_get_peer(0, join_from);

	crm_debug("Processing req from %s", join_from);
	
	generation = join_ack->xml;
	crm_element_value_int(join_ack->msg, F_CRM_JOIN_ID, &join_id);

	if(max_generation_xml != NULL && generation != NULL) {
	    int lpc = 0;
	    const char *attributes[] = {
		XML_ATTR_GENERATION_ADMIN,
		XML_ATTR_GENERATION,
		XML_ATTR_NUMUPDATES,
	    };
	    
	    for(lpc = 0; cmp == 0 && lpc < DIMOF(attributes); lpc++) {
			cmp = compare_int_fields(max_generation_xml, generation, attributes[lpc]);
	    }
	}
	
	if(join_id != current_join_id) {
		crm_debug("Invalid response from %s: join-%d vs. join-%d",
			  join_from, join_id, current_join_id);
		/* JOIN状態チェックを行う */
		check_join_state(cur_state, __FUNCTION__);
		return;
		
	} else if(join_node == NULL || crm_is_member_active(join_node) == FALSE) {
		crm_err("Node %s is not a member", join_from);
		ack_nack_bool = FALSE;
		
	} else if(generation == NULL) {
		crm_err("Generation was NULL");
		ack_nack_bool = FALSE;

	} else if(max_generation_xml == NULL) {
		max_generation_xml = copy_xml(generation);
		max_generation_from = crm_strdup(join_from);

	} else if(cmp < 0
		  || (cmp == 0 && safe_str_eq(join_from, fsa_our_uname))) {
		crm_debug("%s has a better generation number than"
			  " the current max %s",
			  join_from, max_generation_from);
		if(max_generation_xml) {
			crm_log_xml_debug(max_generation_xml, "Max generation");
		}
		crm_log_xml_debug(generation, "Their generation");
		
		crm_free(max_generation_from);
		free_xml(max_generation_xml);
		
		max_generation_from = crm_strdup(join_from);
		max_generation_xml = copy_xml(join_ack->xml);
	}
	
	if(ack_nack_bool == FALSE) {
		/* NACK this client */
		ack_nack = CRMD_JOINSTATE_NACK;
		crm_err("join-%d: NACK'ing node %s (ref %s)",
			join_id, join_from, ref);
	} else {
		crm_debug("join-%d: Welcoming node %s (ref %s)",
			  join_id, join_from, ref);
	}
	
	/* add them to our list of CRMD_STATE_ACTIVE nodes */
	/* integrated_nodesハッシュテーブルにCRM_OP_JOIN_REQUESTを送信して来たノードを追加する */
	g_hash_table_insert(
		integrated_nodes, crm_strdup(join_from), crm_strdup(ack_nack));

	/* integrated_nodesハッシュテーブルサイズと、CRM_OP_JOIN_REQUESTを送信して来たノードjoin_idをログ出力する */
	crm_debug("%u nodes have been integrated into join-%d",
		    g_hash_table_size(integrated_nodes), join_id);
	
	/* welcomed_nodesハッシュテーブルからCRM_OP_JOIN_REQUESTを送信して来たノードを削除する */
	g_hash_table_remove(welcomed_nodes, join_from);

	/* JOIN状態チェックを行う */
	if(check_join_state(cur_state, __FUNCTION__) == FALSE) {
		/* dont waste time by invoking the PE yet; */
		crm_debug("join-%d: Still waiting on %d outstanding offers",
			  join_id, g_hash_table_size(welcomed_nodes));
	}
}
예제 #2
0
/*	 A_DC_JOIN_PROCESS_REQ	*/
void
do_dc_join_filter_offer(long long action,
                        enum crmd_fsa_cause cause,
                        enum crmd_fsa_state cur_state,
                        enum crmd_fsa_input current_input, fsa_data_t * msg_data)
{
    xmlNode *generation = NULL;

    int cmp = 0;
    int join_id = -1;
    gboolean ack_nack_bool = TRUE;
    const char *ack_nack = CRMD_JOINSTATE_MEMBER;
    ha_msg_input_t *join_ack = fsa_typed_data(fsa_dt_ha_msg);

    const char *join_from = crm_element_value(join_ack->msg, F_CRM_HOST_FROM);
    const char *ref = crm_element_value(join_ack->msg, F_CRM_REFERENCE);

    crm_node_t *join_node = crm_get_peer(0, join_from);

    crm_debug("Processing req from %s", join_from);

    generation = join_ack->xml;
    crm_element_value_int(join_ack->msg, F_CRM_JOIN_ID, &join_id);

    if (max_generation_xml != NULL && generation != NULL) {
        int lpc = 0;

        const char *attributes[] = {
            XML_ATTR_GENERATION_ADMIN,
            XML_ATTR_GENERATION,
            XML_ATTR_NUMUPDATES,
        };

        for (lpc = 0; cmp == 0 && lpc < DIMOF(attributes); lpc++) {
            cmp = compare_int_fields(max_generation_xml, generation, attributes[lpc]);
        }
    }

    if (join_id != current_join_id) {
        crm_debug("Invalid response from %s: join-%d vs. join-%d",
                  join_from, join_id, current_join_id);
        check_join_state(cur_state, __FUNCTION__);
        return;

    } else if (join_node == NULL || crm_is_peer_active(join_node) == FALSE) {
        crm_err("Node %s is not a member", join_from);
        ack_nack_bool = FALSE;

    } else if (generation == NULL) {
        crm_err("Generation was NULL");
        ack_nack_bool = FALSE;

    } else if (max_generation_xml == NULL) {
        max_generation_xml = copy_xml(generation);
        max_generation_from = strdup(join_from);

    } else if (cmp < 0 || (cmp == 0 && safe_str_eq(join_from, fsa_our_uname))) {
        crm_debug("%s has a better generation number than"
                  " the current max %s", join_from, max_generation_from);
        if (max_generation_xml) {
            crm_log_xml_debug(max_generation_xml, "Max generation");
        }
        crm_log_xml_debug(generation, "Their generation");

        free(max_generation_from);
        free_xml(max_generation_xml);

        max_generation_from = strdup(join_from);
        max_generation_xml = copy_xml(join_ack->xml);
    }

    if (ack_nack_bool == FALSE) {
        /* NACK this client */
        ack_nack = CRMD_JOINSTATE_NACK;
        crm_update_peer_join(__FUNCTION__, join_node, crm_join_nack);
        crm_err("Rejecting cluster join request from %s " CRM_XS
                " NACK join-%d ref=%s", join_from, join_id, ref);

    } else {
        crm_debug("join-%d: Welcoming node %s (ref %s)", join_id, join_from, ref);
        crm_update_peer_join(__FUNCTION__, join_node, crm_join_integrated);
    }

    crm_update_peer_expected(__FUNCTION__, join_node, ack_nack);

    crm_debug("%u nodes have been integrated into join-%d",
              crmd_join_phase_count(crm_join_integrated), join_id);


    if (check_join_state(cur_state, __FUNCTION__) == FALSE) {
        /* don't waste time by invoking the PE yet; */
        crm_debug("join-%d: Still waiting on %d outstanding offers",
                  join_id, crmd_join_phase_count(crm_join_welcomed));
    }
}