Esempio n. 1
0
gboolean
send_cluster_message(crm_node_t * node, enum crm_ais_msg_types service, xmlNode * data,
                     gboolean ordered)
{

#if SUPPORT_COROSYNC
    if (is_openais_cluster()) {
        return send_cluster_message_cs(data, FALSE, node, service);
    }
#endif
#if SUPPORT_HEARTBEAT
    if (is_heartbeat_cluster()) {
        return send_ha_message(heartbeat_cluster, data, node ? node->uname : NULL, ordered);
    }
#endif
    return FALSE;
}
Esempio n. 2
0
enum cib_errors 
cib_process_diff(
	const char *op, int options, const char *section, crm_data_t *input,
	crm_data_t *existing_cib, crm_data_t **result_cib, crm_data_t **answer)
{
	unsigned int log_level = LOG_DEBUG;
	const char *value = NULL;
	const char *reason = NULL;
	gboolean apply_diff = TRUE;
	gboolean do_resync = FALSE;
	enum cib_errors result = cib_ok;

	int this_updates = 0;
	int this_epoch  = 0;
	int this_admin_epoch = 0;

	int diff_add_updates = 0;
	int diff_add_epoch  = 0;
	int diff_add_admin_epoch = 0;

	int diff_del_updates = 0;
	int diff_del_epoch  = 0;
	int diff_del_admin_epoch = 0;

	crm_debug_2("Processing \"%s\" event", op);

	if(cib_is_master) {
		/* the master is never waiting for a resync */
		sync_in_progress = 0;
	}
	
	cib_diff_version_details(
		input,
		&diff_add_admin_epoch, &diff_add_epoch, &diff_add_updates, 
		&diff_del_admin_epoch, &diff_del_epoch, &diff_del_updates);

	if(sync_in_progress > MAX_DIFF_RETRY) {
		/* request another full-sync,
		 * the last request may have been lost
		 */
		sync_in_progress = 0;
	} 
	if(sync_in_progress) {
		sync_in_progress++;
		crm_warn("Not applying diff %d.%d.%d -> %d.%d.%d (sync in progress)",
			diff_del_admin_epoch,diff_del_epoch,diff_del_updates,
			diff_add_admin_epoch,diff_add_epoch,diff_add_updates);
		return cib_diff_resync;
	}
	
	value = crm_element_value(existing_cib, XML_ATTR_GENERATION);
	this_epoch = atoi(value?value:"0");
	
	value = crm_element_value(existing_cib, XML_ATTR_NUMUPDATES);
	this_updates = atoi(value?value:"0");
	
	value = crm_element_value(existing_cib, XML_ATTR_GENERATION_ADMIN);
	this_admin_epoch = atoi(value?value:"0");
	
	if(diff_del_admin_epoch == diff_add_admin_epoch
	   && diff_del_epoch == diff_add_epoch
	   && diff_del_updates == diff_add_updates) {
		if(diff_add_admin_epoch == -1 && diff_add_epoch == -1 && diff_add_updates == -1) {
			diff_add_epoch = this_epoch;
			diff_add_updates = this_updates + 1;
			diff_add_admin_epoch = this_admin_epoch;
			diff_del_epoch = this_epoch;
			diff_del_updates = this_updates;
			diff_del_admin_epoch = this_admin_epoch;
		} else {
			apply_diff = FALSE;
			log_level = LOG_ERR;
			reason = "+ and - versions in the diff did not change";
			log_cib_diff(LOG_ERR, input, __FUNCTION__);
		}
	}

	if(apply_diff && diff_del_admin_epoch > this_admin_epoch) {
		do_resync = TRUE;
		apply_diff = FALSE;
		log_level = LOG_INFO;
		reason = "current \""XML_ATTR_GENERATION_ADMIN"\" is less than required";
		
	} else if(apply_diff && diff_del_admin_epoch < this_admin_epoch) {
		apply_diff = FALSE;
		log_level = LOG_WARNING;
		reason = "current \""XML_ATTR_GENERATION_ADMIN"\" is greater than required";
	}

	if(apply_diff && diff_del_epoch > this_epoch) {
		do_resync = TRUE;
		apply_diff = FALSE;
		log_level = LOG_INFO;
		reason = "current \""XML_ATTR_GENERATION"\" is less than required";
		
	} else if(apply_diff && diff_del_epoch < this_epoch) {
		apply_diff = FALSE;
		log_level = LOG_WARNING;
		reason = "current \""XML_ATTR_GENERATION"\" is greater than required";
	}

	if(apply_diff && diff_del_updates > this_updates) {
		do_resync = TRUE;
		apply_diff = FALSE;
		log_level = LOG_INFO;
		reason = "current \""XML_ATTR_NUMUPDATES"\" is less than required";
		
	} else if(apply_diff && diff_del_updates < this_updates) {
		apply_diff = FALSE;
		log_level = LOG_WARNING;
		reason = "current \""XML_ATTR_NUMUPDATES"\" is greater than required";
	}

	if(apply_diff) {
		free_xml(*result_cib);
		*result_cib = NULL;
		if(apply_xml_diff(existing_cib, input, result_cib) == FALSE) {
			log_level = LOG_WARNING;
			reason = "Failed application of an update diff";

			if(options & cib_force_diff) {
			    if(cib_is_master == FALSE) {
				log_level = LOG_INFO;
				reason = "Failed application of a global update."
					 "  Requesting full refresh.";
				do_resync = TRUE;

			    } else {
				reason = "Failed application of a global update."
					 "  Not requesting full refresh.";
			    }
			}
			
		} else if((options & cib_force_diff) && !validate_with_dtd(
			      *result_cib, FALSE, HA_NOARCHDATAHBDIR"/crm.dtd")) {

		    if(cib_is_master == FALSE) {
			log_level = LOG_INFO;
			reason = "Failed DTD validation of a global update."
				 "  Requesting full refresh.";
			do_resync = TRUE;
		    } else {
			log_level = LOG_WARNING;
			reason = "Failed DTD validation of a global update."
				 "  Not requesting full refresh.";
		    }
		}
	}
	
	if(reason != NULL) {
		do_crm_log(
			log_level,
			"Diff %d.%d.%d -> %d.%d.%d not applied to %d.%d.%d: %s",
			diff_del_admin_epoch,diff_del_epoch,diff_del_updates,
			diff_add_admin_epoch,diff_add_epoch,diff_add_updates,
			this_admin_epoch,this_epoch,this_updates, reason);
		
		result = cib_diff_failed;

	} else if(apply_diff) {
		crm_debug_2("Diff %d.%d.%d -> %d.%d.%d was applied",
			    diff_del_admin_epoch,diff_del_epoch,diff_del_updates,
			    diff_add_admin_epoch,diff_add_epoch,diff_add_updates);
	}

	if(do_resync && cib_is_master == FALSE) {
		HA_Message *sync_me = ha_msg_new(3);
		free_xml(*result_cib);
		*result_cib = NULL;
		result = cib_diff_resync;
		crm_info("Requesting re-sync from peer: %s", reason);
		sync_in_progress++;
		
		ha_msg_add(sync_me, F_TYPE, "cib");
		ha_msg_add(sync_me, F_CIB_OPERATION, CIB_OP_SYNC_ONE);
		ha_msg_add(sync_me, F_CIB_DELEGATED, cib_our_uname);

		if(send_ha_message(hb_conn, sync_me, NULL, FALSE) == FALSE) {
			result = cib_not_connected;
		}
		ha_msg_del(sync_me);
		
	} else if(do_resync) {
		crm_err("Not resyncing in master mode");
	}
	
	
	return result;
}