Exemple #1
0
gboolean
query_quorum(gpointer data)
{
	int quorum;
	size_t	len;
	char* s = NULL;
	char buf[MAXMSG];
	struct ha_msg* msg = NULL;
	struct ha_msg* ret = NULL;

	if(session != NULL) {
		msg = ha_msg_new(10);
		ha_msg_add(msg, "t","quorum");
		ha_msg_add_int(msg, "nodenum", nodenum);
		ha_msg_add_int(msg, "weight", weight);
	
		s  = msg2wirefmt(msg, &len);
		gnutls_record_send(session, s, len);
		free(s);
		len = gnutls_record_recv(session, buf, MAXMSG);
		if ((ssize_t)len < 0) {
			gnutls_bye (session, GNUTLS_SHUT_WR);
			gnutls_deinit (session);
			close(sock);
			session = NULL;
			cur_quorum = -1;
			ha_msg_del(msg);
			return TRUE;
		}
		ret = wirefmt2msg(buf, len, FALSE);
		ha_msg_value_int(ret, "quorum", &quorum);
			
		ha_msg_del(ret);
		ha_msg_del(msg);
		
		if (cur_quorum!=-1 && cur_quorum!=quorum && callback!=NULL){
			cur_quorum = quorum;
			callback();
		}
		cur_quorum = quorum;
	}
	else {
		connect_quorum_server(NULL);
	}
	return TRUE;
}
Exemple #2
0
/*	 A_CIB_INVOKE, A_CIB_BUMPGEN, A_UPDATE_NODESTATUS	*/
void
do_cib_invoke(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)
{
	HA_Message *answer = NULL;
	ha_msg_input_t *cib_msg = fsa_typed_data(fsa_dt_ha_msg);
	const char *sys_from = cl_get_string(cib_msg->msg, F_CRM_SYS_FROM);

	if(fsa_cib_conn->state == cib_disconnected) {
		if(cur_state != S_STOPPING) {
			crm_err("CIB is disconnected");
			crm_log_message_adv(LOG_WARNING, "CIB Input", cib_msg->msg);
			return;
		}
		crm_info("CIB is disconnected");
		crm_log_message_adv(LOG_DEBUG, "CIB Input", cib_msg->msg);
		return;
		
	}
	
	if(action & A_CIB_INVOKE) {
		if(safe_str_eq(sys_from, CRM_SYSTEM_CRMD)) {
			action = A_CIB_INVOKE_LOCAL;
		} else if(safe_str_eq(sys_from, CRM_SYSTEM_DC)) {
			action = A_CIB_INVOKE_LOCAL;
		}
	}
	

	if(action & A_CIB_INVOKE || action & A_CIB_INVOKE_LOCAL) {
		int call_options = 0;
		enum cib_errors rc  = cib_ok;
		crm_data_t *cib_frag  = NULL;
		
		const char *section  = NULL;
		const char *op   = cl_get_string(cib_msg->msg, F_CRM_TASK);

		section  = cl_get_string(cib_msg->msg, F_CIB_SECTION);
		
		ha_msg_value_int(cib_msg->msg, F_CIB_CALLOPTS, &call_options);

		crm_log_message(LOG_MSG, cib_msg->msg);
		crm_log_xml_debug_3(cib_msg->xml, "[CIB update]");
		if(op == NULL) {
			crm_err("Invalid CIB Message");
			register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
			return;
		}

		cib_frag = NULL;
		rc = fsa_cib_conn->cmds->variant_op(
			fsa_cib_conn, op, NULL, section,
			cib_msg->xml, &cib_frag, call_options);

		if(rc < cib_ok || (action & A_CIB_INVOKE)) {
			answer = create_reply(cib_msg->msg, cib_frag);
			ha_msg_add(answer,XML_ATTR_RESULT,cib_error2string(rc));
		}
		
		if(action & A_CIB_INVOKE) {
			if(relay_message(answer, TRUE) == FALSE) {
				crm_err("Confused what to do with cib result");
				crm_log_message(LOG_ERR, answer);
				crm_msg_del(answer);
				register_fsa_input(C_FSA_INTERNAL, I_ERROR, NULL);
				return;
			}

		} else if(rc < cib_ok) {
			ha_msg_input_t *input = NULL;
			crm_err("Internal CRM/CIB command from %s() failed: %s",
				msg_data->origin, cib_error2string(rc));
			crm_log_message_adv(LOG_WARNING, "CIB Input", cib_msg->msg);
			crm_log_message_adv(LOG_WARNING, "CIB Reply", answer);
			
			input = new_ha_msg_input(answer);
			register_fsa_input(C_FSA_INTERNAL, I_ERROR, input);
			crm_msg_del(answer);
			delete_ha_msg_input(input);
		}

	} else {
		crm_err("Unexpected action %s in %s",
			fsa_action2string(action), __FUNCTION__);
	}
}
Exemple #3
0
void
te_update_diff(const char *event, HA_Message *msg)
{
	int rc = -1;
	const char *op = NULL;
	crm_data_t *diff = NULL;
	crm_data_t *aborted = NULL;
	const char *set_name = NULL;

	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;
	
	if(msg == NULL) {
		crm_err("NULL update");
		return;
	}		

	ha_msg_value_int(msg, F_CIB_RC, &rc);	
	op = cl_get_string(msg, F_CIB_OPERATION);

	if(rc < cib_ok) {
		crm_debug_2("Ignoring failed %s operation: %s",
			    op, cib_error2string(rc));
		return;
	} 	

	diff = get_message_xml(msg, F_CIB_UPDATE_RESULT);

	cib_diff_version_details(
		diff,
		&diff_add_admin_epoch, &diff_add_epoch, &diff_add_updates, 
		&diff_del_admin_epoch, &diff_del_epoch, &diff_del_updates);
	
	crm_debug("Processing diff (%s): %d.%d.%d -> %d.%d.%d", op,
		  diff_del_admin_epoch,diff_del_epoch,diff_del_updates,
		  diff_add_admin_epoch,diff_add_epoch,diff_add_updates);
	log_cib_diff(LOG_DEBUG_2, diff, op);

	set_name = "diff-added";
	if(diff != NULL) {
		crm_data_t *section = NULL;
		crm_data_t *change_set = find_xml_node(diff, set_name, FALSE);
		change_set = find_xml_node(change_set, XML_TAG_CIB, FALSE);

		if(change_set != NULL) {
			crm_debug_2("Checking status changes");
			section=get_object_root(XML_CIB_TAG_STATUS,change_set);
		}
		
		if(section != NULL) {
			extract_event(section);
		}
		crm_debug_2("Checking change set: %s", set_name);
		aborted = need_abort(change_set);
	}
	
	set_name = "diff-removed";
	if(diff != NULL && aborted == NULL) {
		crm_data_t *attrs = NULL;
		crm_data_t *status = NULL;
		crm_data_t *change_set = find_xml_node(diff, set_name, FALSE);
		change_set = find_xml_node(change_set, XML_TAG_CIB, FALSE);

		crm_debug_2("Checking change set: %s", set_name);
		aborted = need_abort(change_set);		

		if(aborted == NULL && change_set != NULL) {
			status = get_object_root(XML_CIB_TAG_STATUS, change_set);
		
			xml_child_iter_filter(
				status, node_state, XML_CIB_TAG_STATE,
				
				attrs = find_xml_node(
					node_state, XML_TAG_TRANSIENT_NODEATTRS, FALSE);
				
				if(attrs != NULL) {
					crm_info("Aborting on "XML_TAG_TRANSIENT_NODEATTRS" deletions");
					abort_transition(INFINITY, tg_restart,
							 XML_TAG_TRANSIENT_NODEATTRS, attrs);
				}
				);
Exemple #4
0
gboolean
connect_quorum_server(gpointer data)
{
	struct sockaddr_in addr;
	struct ha_msg* msg = NULL;
	struct ha_msg* ret = NULL;
	const char* version = "2_0_8";
	struct hostent* hp;
	int quorum;
	size_t	len;
	char* s = NULL;
	char buf[MAXMSG];
	
	cl_log(LOG_DEBUG, "quorum plugin: quorumd, connect_quorum_server");
	/* initialize gnutls */
	initialize_tls_global();

	/* create socket */
	sock=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sock == -1 ) {
		return FALSE;
	}

	/* connect to server*/
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	hp = gethostbyname(quorum_server);
	if (hp == NULL) {
		return FALSE;
	}
	memcpy(&addr.sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
	addr.sin_port = htons(5561);
	if (connect(sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
		return FALSE;
	}
	session = initialize_tls_session(sock);
	if (session == NULL) {
		close(sock);
		session = NULL;
		return FALSE;
	}
	/* send the version */
	gnutls_record_send(session, version, strlen(version)+1);

	/* send initialize msg */
	msg = ha_msg_new(10);
	ha_msg_add(msg, "t","init");
	ha_msg_add(msg, "cl_name", cluster);

	s  = msg2wirefmt(msg, &len);
	gnutls_record_send(session, s, len);
	free(s);
	len = gnutls_record_recv(session, buf, MAXMSG);
	if ((ssize_t)len <=0) {
		close(sock);
		session = NULL;
		return FALSE;
	}
	ret = wirefmt2msg(buf, len, FALSE);
	if (STRNCMP_CONST(ha_msg_value(ret, "result"), "ok") != 0) {
		close(sock);
		session = NULL;
		return FALSE;
	}
	if (ha_msg_value_int(ret, "interval", &interval)!= HA_OK) {
		close(sock);
		session = NULL;
		return FALSE;
	}
	ha_msg_del(ret);
	ha_msg_del(msg);

	/* send quorum query msg */
	msg = ha_msg_new(10);
	ha_msg_add(msg, "t","quorum");
	ha_msg_add_int(msg, "nodenum", nodenum);
	ha_msg_add_int(msg, "weight", weight);

	s  = msg2wirefmt(msg, &len);
	gnutls_record_send(session, s, len);
	free(s);
	len = gnutls_record_recv(session, buf, MAXMSG);
	ret = wirefmt2msg(buf, len, FALSE);
	ha_msg_value_int(ret, "quorum", &quorum);
	LOG(LOG_DEBUG,"quorum:%d\n", quorum);
	cur_quorum = quorum;
	
	ha_msg_del(ret);
	ha_msg_del(msg);

	/* set the repeatly query */
	repeat_timer = g_timeout_add(interval, query_quorum, NULL);
	return FALSE;
}
int
stonithd_virtual_stonithRA_ops( stonithRA_ops_t * op, int * call_id)
{
	int rc = ST_FAIL;
	struct ha_msg * request, * reply;
	const char * tmpstr;

	if (op == NULL) {
		stdlib_log(LOG_ERR, "stonithd_virtual_stonithRA_ops: op==NULL");
		return ST_FAIL;
	}
	
	if (call_id == NULL) {
		stdlib_log(LOG_ERR, "stonithd_stonithd_stonithRA_ops: "
			   "call_id==NULL");
		return ST_FAIL;
	}
	
	if ( !signed_on(chan) ) {
		stdlib_log(LOG_ERR, "not signed on");
		return ST_FAIL;
	}

	if ( (request = create_basic_reqmsg_fields(ST_RAOP)) == NULL) {
		return ST_FAIL;
	}

	if (  (ha_msg_add(request, F_STONITHD_RSCID, op->rsc_id) != HA_OK)
	    ||(ha_msg_add(request, F_STONITHD_RAOPTYPE, op->op_type) != HA_OK)
	    ||(ha_msg_add(request, F_STONITHD_RANAME, op->ra_name) != HA_OK)
	    ||(ha_msg_add_int(request, F_STONITHD_TIMEOUT, op->timeout) != HA_OK)
	    ||(ha_msg_addhash(request, F_STONITHD_PARAMS, op->params) != HA_OK)
	   ) {
		stdlib_log(LOG_ERR, "stonithd_virtual_stonithRA_ops: "
			   "cannot add field to ha_msg.");
		ZAPMSG(request);
		return ST_FAIL;
	}

	/* Send the request message */
	if (msg2ipcchan(request, chan) != HA_OK) {
		ZAPMSG(request);
		stdlib_log(LOG_ERR, "can't send stonithRA message to IPC");
		return ST_FAIL;
	}

	/*  waiting for the output to finish */
	chan_waitout_timeout(chan, DEFAULT_TIMEOUT);
	ZAPMSG(request);
	
	/* Read the reply... */
	stdlib_log(LOG_DEBUG, "waiting for the stonithRA reply msg.");
        if ( IPC_OK != chan_waitin_timeout(chan, DEFAULT_TIMEOUT) ) {
		stdlib_log(LOG_ERR, "%s:%d: waitin failed."
			   , __FUNCTION__, __LINE__);
		return ST_FAIL;
	}

	if ( (reply = msgfromIPC_noauth(chan)) == NULL ) {
		stdlib_log(LOG_ERR, "stonithd_virtual_stonithRA_ops: "
			   "failed to fetch reply");
		return ST_FAIL;
	}
	
	if ( FALSE == is_expected_msg(reply, F_STONITHD_TYPE, ST_APIRPL, 
			     F_STONITHD_APIRPL, ST_RRAOP, TRUE) ) {
		ZAPMSG(reply); /* avoid to zap the msg ? */
		stdlib_log(LOG_WARNING, "stonithd_virtual_stonithRA_ops: "
			   "got an unexpected message");
		return ST_FAIL;
	}

	if ( ((tmpstr = cl_get_string(reply, F_STONITHD_APIRET)) != NULL) 
	   	    && (STRNCMP_CONST(tmpstr, ST_APIOK) == 0) ) {
		int tmpint;

		if ( ha_msg_value_int(reply, F_STONITHD_CALLID, &tmpint)
			== HA_OK ) {
			*call_id = tmpint;
			rc = ST_OK;
			stdlib_log(LOG_DEBUG, "a stonith RA operation queue " \
				   "to run, call_id=%d.", *call_id);
		} else {
			stdlib_log(LOG_ERR, "no return call_id in reply");
			rc = ST_FAIL;
		}
	} else {
		stdlib_log(LOG_WARNING, "failed to do the RA op.");
		rc = ST_FAIL;
		* call_id = -1;		
	}

	ZAPMSG(reply);
	return rc;
}