Ejemplo n.º 1
0
static void
send_to_client(const dopd_client_t *client, const char *rc_string)
{
	IPC_Channel *channel = client->channel;
	HA_Message *msg_out;

	msg_out = ha_msg_new(3);
	ha_msg_add(msg_out, F_TYPE, "outdater_rc");
	ha_msg_add(msg_out, F_ORIG, node_name);
	ha_msg_add(msg_out, F_DOPD_VALUE, rc_string);

	if (msg2ipcchan(msg_out, channel) != HA_OK) {
		cl_log(LOG_ERR, "Could not send message to the client");
	}
}
Ejemplo n.º 2
0
void
cib_replace_notify(crm_data_t *update, enum cib_errors result, crm_data_t *diff) 
{
	const char *origin = NULL;
	HA_Message *replace_msg = NULL;
	
	int add_updates = 0;
	int add_epoch  = 0;
	int add_admin_epoch = 0;

	int del_updates = 0;
	int del_epoch  = 0;
	int del_admin_epoch = 0;

	if(diff == NULL) {
		return;
	}

	cib_diff_version_details(
		diff, &add_admin_epoch, &add_epoch, &add_updates, 
		&del_admin_epoch, &del_epoch, &del_updates);

	origin = crm_element_value(update, F_CRM_ORIGIN);
	
	if(add_updates != del_updates) {
		crm_info("Replaced: %d.%d.%d -> %d.%d.%d from %s",
			 del_admin_epoch, del_epoch, del_updates,
			 add_admin_epoch, add_epoch, add_updates,
			 crm_str(origin));
	} else if(diff != NULL) {
		crm_info("Local-only Replace: %d.%d.%d from %s",
			 add_admin_epoch, add_epoch, add_updates,
			 crm_str(origin));
	}
	
	replace_msg = ha_msg_new(8);
	ha_msg_add(replace_msg, F_TYPE, T_CIB_NOTIFY);
	ha_msg_add(replace_msg, F_SUBTYPE, T_CIB_REPLACE_NOTIFY);
	ha_msg_add(replace_msg, F_CIB_OPERATION, CIB_OP_REPLACE);
	ha_msg_add_int(replace_msg, F_CIB_RC, result);
	attach_cib_generation(replace_msg, "cib-replace-generation", update);

	crm_log_message_adv(LOG_DEBUG_2,"CIB Replaced", replace_msg);
	
	g_hash_table_foreach(client_list, cib_notify_client, replace_msg);
	crm_msg_del(replace_msg);
}
Ejemplo n.º 3
0
static HA_Message *
convert_xml_message_struct(HA_Message * parent, xmlNode * src_node, const char *field)
{
    xmlNode *child = NULL;
    xmlNode *__crm_xml_iter = src_node->children;
    xmlAttrPtr prop_iter = src_node->properties;
    const char *name = NULL;
    const char *value = NULL;

    HA_Message *result = ha_msg_new(3);

    ha_msg_add(result, F_XML_TAGNAME, (const char *)src_node->name);

    while (prop_iter != NULL) {
        name = (const char *)prop_iter->name;
        value = (const char *)xmlGetProp(src_node, prop_iter->name);
        prop_iter = prop_iter->next;
        ha_msg_add(result, name, value);
    }

    while (__crm_xml_iter != NULL) {
        child = __crm_xml_iter;
        __crm_xml_iter = __crm_xml_iter->next;
        convert_xml_message_struct(result, child, NULL);
    }

    if (parent == NULL) {
        return result;
    }

    if (field) {
        HA_Message *holder = ha_msg_new(3);

        CRM_ASSERT(holder != NULL);

        ha_msg_add(holder, F_XML_TAGNAME, field);
        add_ha_nocopy(holder, result, (const char *)src_node->name);

        ha_msg_addstruct_compress(parent, field, holder);
        ha_msg_del(holder);

    } else {
        add_ha_nocopy(parent, result, (const char *)src_node->name);
    }
    return result;
}
Ejemplo n.º 4
0
static gboolean
send_rexmit_request( gpointer data)
{
	struct rexmit_info* ri = (struct rexmit_info*) data;
	seqno_t seq = (seqno_t) ri->seq;
	struct node_info* node = ri->node;
	struct ha_msg*	hmsg;
	
	if ((hmsg = ha_msg_new(6)) == NULL) {
		cl_log(LOG_ERR, "%s: no memory for " T_REXMIT, 
		       __FUNCTION__);
		return FALSE;
	}
	
	
	if (ha_msg_add(hmsg, F_TYPE, T_REXMIT) != HA_OK
	    ||	ha_msg_add(hmsg, F_TO, node->nodename) !=HA_OK
	    ||	ha_msg_add_int(hmsg, F_FIRSTSEQ, seq) != HA_OK
	    ||	ha_msg_add_int(hmsg, F_LASTSEQ, seq) != HA_OK) {
		cl_log(LOG_ERR, "%s: adding fields to msg failed",
		       __FUNCTION__);
		ha_msg_del(hmsg);
		return FALSE;
	}
	
	if (send_cluster_msg(hmsg) != HA_OK) {
		cl_log(LOG_ERR, "%s: cannot send " T_REXMIT
		       " request to %s",__FUNCTION__,  node->nodename);
		ha_msg_del(hmsg);
		return FALSE;
	}
	
	node->track.last_rexmit_req = time_longclock();	
	
	if (!g_hash_table_remove(rexmit_hash_table, ri)){
		cl_log(LOG_ERR, "%s: entry not found in rexmit_hash_table"
		       "for seq/node(%ld %s)", 		       
		       __FUNCTION__, ri->seq, ri->node->nodename);
		return FALSE;
	}
	
	schedule_rexmit_request(node, seq, max_rexmit_delay);
	
	return FALSE;
}
Ejemplo n.º 5
0
void
notify_crmd(crm_graph_t *graph)
{	
	HA_Message *cmd = NULL;
	int log_level = LOG_DEBUG;
	const char *op = CRM_OP_TEABORT;
	int pending_callbacks = num_cib_op_callbacks();
	

	stop_te_timer(transition_timer);
	
	if(pending_callbacks != 0) {
		crm_warn("Delaying completion until all CIB updates complete");
		return;
	}

	CRM_CHECK(graph->complete, graph->complete = TRUE);

	switch(graph->completion_action) {
		case tg_stop:
			op = CRM_OP_TECOMPLETE;
			log_level = LOG_INFO;
			break;

		case tg_abort:
		case tg_restart:
			op = CRM_OP_TEABORT;
			break;

		case tg_shutdown:
			crm_info("Exiting after transition");
			if (mainloop != NULL && g_main_is_running(mainloop)) {
				g_main_quit(mainloop);
				return;
			}
			exit(LSB_EXIT_OK);
	}

	te_log_action(log_level, "Transition %d status: %s - %s",
		      graph->id, op, crm_str(graph->abort_reason));

	print_graph(LOG_DEBUG_3, graph);
	
	cmd = create_request(
		op, NULL, NULL, CRM_SYSTEM_DC, CRM_SYSTEM_TENGINE, NULL);

	if(graph->abort_reason != NULL) {
		ha_msg_add(cmd, "message", graph->abort_reason);
	}

	send_ipc_message(crm_ch, cmd);
	crm_msg_del(cmd);

	graph->abort_reason = NULL;
	graph->completion_action = tg_restart;	

}
Ejemplo n.º 6
0
void
insert_data_pairs(gpointer key, gpointer value, gpointer user_data)
{
	struct ha_msg * msg_tmp = (struct ha_msg *) user_data;
	
	if ( ha_msg_add(msg_tmp, (const char *)key, (const char *)value) 
		!= HA_OK ) {
		stdmsg_log(LOG_ERR, "insert_data_pairs: ha_msg_add failed.");
	}
}
Ejemplo n.º 7
0
/* send_message_to_the_peer()
 * send message with drbd resource to other node.
 */
static gboolean
send_message_to_the_peer(const char *drbd_peer, const char *drbd_resource)
{
	HA_Message *msg = NULL;

	cl_log(LOG_INFO, "sending start_outdate message to the other node %s -> %s",
		  node_name, drbd_peer);

	msg = ha_msg_new(3);
	ha_msg_add(msg, F_TYPE, "start_outdate");
	ha_msg_add(msg, F_ORIG, node_name);
	ha_msg_add(msg, F_DOPD_RES, drbd_resource);

	cl_log(LOG_DEBUG, "sending [start_outdate res: %s] to node: %s",
		  drbd_resource, drbd_peer);
	dopd_cluster_conn->llc_ops->sendnodemsg(dopd_cluster_conn, msg, drbd_peer);
	ha_msg_del(msg);

	return TRUE;
}
Ejemplo n.º 8
0
static struct ha_msg * 
create_basic_reqmsg_fields(const char * apitype)
{
	struct ha_msg * msg = NULL;

	if ((msg = ha_msg_new(4)) == NULL) {
		stdlib_log(LOG_ERR, "create_basic_msg_fields:out of memory.");
		return NULL;
	}

	/* important error check client name length */
	if (  (ha_msg_add(msg, F_STONITHD_TYPE, ST_APIREQ ) != HA_OK )
	    ||(	ha_msg_add(msg, F_STONITHD_APIREQ, apitype) != HA_OK) 
	    ||(	ha_msg_add(msg, F_STONITHD_CNAME, CLIENT_NAME) != HA_OK) 
	    ||(	ha_msg_add_int(msg, F_STONITHD_CPID, CLIENT_PID) != HA_OK) 
	   ) {
		stdlib_log(LOG_ERR, "create_basic_msg_fields: "
				"cannot add field to ha_msg.");
		ZAPMSG(msg);
	}

	return msg;
}
Ejemplo n.º 9
0
static void
convert_xml_child(HA_Message * msg, xmlNode * xml)
{
    int orig = 0;
    int rc = BZ_OK;
    unsigned int len = 0;

    char *buffer = NULL;
    char *compressed = NULL;
    const char *name = NULL;

    name = (const char *)xml->name;
    buffer = dump_xml_unformatted(xml);
    orig = strlen(buffer);
    if (orig < CRM_BZ2_THRESHOLD) {
        ha_msg_add(msg, name, buffer);
        goto done;
    }

    len = (orig * 1.1) + 600;   /* recomended size */

    compressed = malloc(len);
    rc = BZ2_bzBuffToBuffCompress(compressed, &len, buffer, orig, CRM_BZ2_BLOCKS, 0, CRM_BZ2_WORK);

    if (rc != BZ_OK) {
        crm_err("Compression failed: %d", rc);
        free(compressed);
        convert_xml_message_struct(msg, xml, name);
        goto done;
    }

    free(buffer);
    buffer = compressed;
    crm_trace("Compression details: %d -> %d", orig, len);
    ha_msg_addbin(msg, name, buffer, len);
  done:
    free(buffer);

#  if 0
    {
        unsigned int used = orig;
        char *uncompressed = NULL;

        crm_debug("Trying to decompress %d bytes", len);
        uncompressed = calloc(1, orig);
        rc = BZ2_bzBuffToBuffDecompress(uncompressed, &used, compressed, len, 1, 0);
        CRM_CHECK(rc == BZ_OK,;
            );
        CRM_CHECK(used == orig,;
            );
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
0
void
cib_pre_notify(
	int options, const char *op, crm_data_t *existing, crm_data_t *update) 
{
	HA_Message *update_msg = NULL;
	const char *type = NULL;
	const char *id = NULL;

	update_msg = ha_msg_new(6);

	if(update != NULL) {
		id = crm_element_value(update, XML_ATTR_ID);
	}
	
	ha_msg_add(update_msg, F_TYPE, T_CIB_NOTIFY);
	ha_msg_add(update_msg, F_SUBTYPE, T_CIB_PRE_NOTIFY);
	ha_msg_add(update_msg, F_CIB_OPERATION, op);

	if(id != NULL) {
		ha_msg_add(update_msg, F_CIB_OBJID, id);
	}

	if(update != NULL) {
		ha_msg_add(update_msg, F_CIB_OBJTYPE, crm_element_name(update));
	} else if(existing != NULL) {
		ha_msg_add(update_msg, F_CIB_OBJTYPE, crm_element_name(existing));
	}

	type = cl_get_string(update_msg, F_CIB_OBJTYPE);	
	attach_cib_generation(update_msg, "cib_generation", the_cib);
	
	if(existing != NULL) {
		add_message_xml(update_msg, F_CIB_EXISTING, existing);
	}
	if(update != NULL) {
		add_message_xml(update_msg, F_CIB_UPDATE, update);
	}

	g_hash_table_foreach(client_list, cib_notify_client, update_msg);
	
	if(update == NULL) {
		crm_debug_2("Performing operation %s (on section=%s)",
			    op, type);

	} else {
		crm_debug_2("Performing %s on <%s%s%s>",
			    op, type, id?" id=":"", id?id:"");
	}
		
	crm_msg_del(update_msg);
}
Ejemplo n.º 12
0
int
stonithd_signon(const char * client_name)
{
	int     rc = ST_FAIL;
	char	path[] = IPC_PATH_ATTR;
	char	sock[] = STONITHD_SOCK;
	char	cbsock[] = STONITHD_CALLBACK_SOCK;
	struct  ha_msg * request;
	struct  ha_msg * reply;
	GHashTable *	 wchanattrs;
	uid_t	my_euid;
	gid_t	my_egid;
	const char * tmpstr;
	int 	rc_tmp;
	gboolean connected = TRUE;
 	cl_uuid_t cookie, *cptr = NULL;

	if (chan == NULL || chan->ch_status != IPC_CONNECT) {
	    connected = FALSE;
	} else if (cbchan == NULL || cbchan->ch_status != IPC_CONNECT) {
	    connected = FALSE;
	}

	if(!connected) {
		/* cleanup */
		if (NULL != chan) {
		    chan->ops->destroy(chan);
		    chan = NULL;
		}
		if (NULL != cbchan) {
		    cbchan->ops->destroy(cbchan);
		    cbchan = NULL;
		}
		stdlib_log(LOG_DEBUG, "stonithd_signon: creating connection");
		wchanattrs = g_hash_table_new(g_str_hash, g_str_equal);
        	g_hash_table_insert(wchanattrs, path, sock);
		/* Connect to the stonith deamon */
		chan = ipc_channel_constructor(IPC_ANYTYPE, wchanattrs);
		g_hash_table_destroy(wchanattrs);
	
		if (chan == NULL) {
			stdlib_log(LOG_ERR, "stonithd_signon: Can't connect "
				   " to stonithd");
			rc = ST_FAIL;
			goto end;
		}

	        if (chan->ops->initiate_connection(chan) != IPC_OK) {
			stdlib_log(LOG_ERR, "stonithd_signon: Can't initiate "
				   "connection to stonithd");
			rc = ST_FAIL;
			goto end;
       		}
	}

	CLIENT_PID = getpid();
	snprintf(CLIENT_PID_STR, sizeof(CLIENT_PID_STR), "%d", CLIENT_PID);
	if ( client_name != NULL ) {
		CLIENT_NAME = client_name;
	} else {
		CLIENT_NAME = CLIENT_PID_STR;
	}

	if ( (request = create_basic_reqmsg_fields(ST_SIGNON)) == NULL) {
		rc = ST_FAIL;
		goto end;
	}

	/* important error check client name length */
	my_euid = geteuid();
	my_egid = getegid();
	if (  (	ha_msg_add_int(request, F_STONITHD_CEUID, my_euid) != HA_OK )
	    ||(	ha_msg_add_int(request, F_STONITHD_CEGID, my_egid) != HA_OK )
	    ||( ha_msg_add(request, F_STONITHD_COOKIE, "") != HA_OK )
	   ) {
		stdlib_log(LOG_ERR, "stonithd_signon: "
			   "cannot add field to ha_msg.");
		ZAPMSG(request);
		rc = ST_FAIL;
		goto end;
	}

	stdlib_log(LOG_DEBUG, "sending out the signon msg.");
	/* Send the registration request message */
	if (msg2ipcchan(request, chan) != HA_OK) {
		ZAPMSG(request);
		stdlib_log(LOG_ERR, "can't send signon message to IPC");
		rc = ST_FAIL;
		goto end;
	}

	/* waiting for the output to finish */
	do { 
		rc_tmp= chan_waitout_timeout(chan, DEFAULT_TIMEOUT);
	} while (rc_tmp == IPC_INTR);

	ZAPMSG(request);
	if (IPC_OK != rc_tmp) {
		stdlib_log(LOG_ERR, "%s:%d: waitout failed."
			   , __FUNCTION__, __LINE__);
		rc = ST_FAIL;
		goto end;
	}

	/* Read the reply... */
        if ( IPC_OK != chan_waitin_timeout(chan, DEFAULT_TIMEOUT) ) {
		stdlib_log(LOG_ERR, "%s:%d: waitin failed."
			   , __FUNCTION__, __LINE__);
		rc = ST_FAIL;
		goto end;
	}

	if ( (reply = msgfromIPC_noauth(chan)) == NULL ) {
		stdlib_log(LOG_ERR, "stonithd_signon: failed to fetch reply.");
		rc = ST_FAIL;
		goto end;
	}
	
	if ( TRUE == is_expected_msg(reply, F_STONITHD_TYPE, ST_APIRPL, 
			     F_STONITHD_APIRPL, ST_RSIGNON, TRUE) ) {
		if ( ((tmpstr=cl_get_string(reply, F_STONITHD_APIRET)) != NULL)
	   	    && (STRNCMP_CONST(tmpstr, ST_APIOK) == 0) ) {
			rc = ST_OK;
			stdlib_log(LOG_DEBUG, "signed on to stonithd.");
			/* get cookie if any */
			if( cl_get_uuid(reply, F_STONITHD_COOKIE, &cookie) == HA_OK ) {
				cptr = &cookie;
			}
		} else {
			stdlib_log(LOG_WARNING, "failed to signon to the "
				   "stonithd.");
		}
	} else {
		stdlib_log(LOG_ERR, "stonithd_signon: "
			   "Got an unexpected message.");
	}
	ZAPMSG(reply);

	if (ST_OK != rc) { /* Something wrong when try to sign on to stonithd */
		goto end;
	}

	/* Connect to the stonith deamon via callback channel */
	wchanattrs = g_hash_table_new(g_str_hash, g_str_equal);
        g_hash_table_insert(wchanattrs, path, cbsock);
	cbchan = ipc_channel_constructor(IPC_ANYTYPE, wchanattrs);
	g_hash_table_destroy(wchanattrs);

	if (cbchan == NULL) {
		stdlib_log(LOG_ERR, "stonithd_signon: Can't construct "
			   "callback channel to stonithd.");
		rc = ST_FAIL;
		goto end;
	}

        if (cbchan->ops->initiate_connection(cbchan) != IPC_OK) {
		stdlib_log(LOG_ERR, "stonithd_signon: Can't initiate "
			   "connection with the callback channel");
		rc = ST_FAIL;
		goto end;
 	}

	if ( (reply = msgfromIPC_noauth(cbchan)) == NULL ) {
		stdlib_log(LOG_ERR, "%s:%d: failed to fetch reply via the "
			   " callback channel"
			   , __FUNCTION__, __LINE__);
		rc = ST_FAIL;
		goto end;
	}
	
	if ( TRUE == is_expected_msg(reply, F_STONITHD_TYPE, ST_APIRPL, 
			     F_STONITHD_APIRPL, ST_RSIGNON, TRUE) ) {
		tmpstr=cl_get_string(reply, F_STONITHD_APIRET);
		if ( !STRNCMP_CONST(tmpstr, ST_APIOK) ) {
			/* 
			 * If the server directly authenticates us (probably 
			 * via pid-auth), go ahead.
			 */
			stdlib_log(LOG_DEBUG, "%s:%d: Got a good signon reply "
				  "via the callback channel."
				   , __FUNCTION__, __LINE__);
		} else if ( !STRNCMP_CONST(tmpstr, ST_COOKIE) ) {
			/*
			 * If the server asks for a cookie to identify myself,
			 * initiate cookie authentication.
			 */
			if (cptr == NULL) {
				stdlib_log(LOG_ERR, "server requested cookie auth on "
					"the callback channel, but it didn't "
					"provide the cookie on the main channel.");
				rc = ST_FAIL;
			} else {
				rc = authenticate_with_cookie(cbchan, cptr);
			}
		} else {
			/* Unknown response. */
			rc = ST_FAIL;
			stdlib_log(LOG_ERR, "%s:%d: Got a bad signon reply "
				  "via the callback channel."
				   , __FUNCTION__, __LINE__);
		}
	} else {
		rc = ST_FAIL;
		stdlib_log(LOG_ERR, "stonithd_signon: "
			   "Got an unexpected message via the callback chan.");
	}
	ZAPMSG(reply);

end:
	if (ST_OK != rc) {
		/* Something wrong when confirm via callback channel */
		stonithd_signoff();
	}

	return rc;
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
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;
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
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__);
	}
}
Ejemplo n.º 17
0
void
do_cib_notify(
	int options, const char *op, crm_data_t *update,
	enum cib_errors result, crm_data_t *result_data, const char *msg_type) 
{
	HA_Message *update_msg = NULL;
	const char *type = NULL;
	const char *id = NULL;

	update_msg = ha_msg_new(8);

	if(result_data != NULL) {
		id = crm_element_value(result_data, XML_ATTR_ID);
	}
	
	ha_msg_add(update_msg, F_TYPE, T_CIB_NOTIFY);
	ha_msg_add(update_msg, F_SUBTYPE, msg_type);
	ha_msg_add(update_msg, F_CIB_OPERATION, op);
	ha_msg_add_int(update_msg, F_CIB_RC, result);
	
	if(id != NULL) {
		ha_msg_add(update_msg, F_CIB_OBJID, id);
	}

	if(update != NULL) {
		crm_debug_4("Setting type to update->name: %s",
			    crm_element_name(update));
		ha_msg_add(update_msg, F_CIB_OBJTYPE, crm_element_name(update));
		type = crm_element_name(update);

	} else if(result_data != NULL) {
		crm_debug_4("Setting type to new_obj->name: %s",
			    crm_element_name(result_data));
		ha_msg_add(update_msg, F_CIB_OBJTYPE, crm_element_name(result_data));
		type = crm_element_name(result_data);
		
	} else {
		crm_debug_4("Not Setting type");
	}

	attach_cib_generation(update_msg, "cib_generation", the_cib);
	if(update != NULL) {
		add_message_xml(update_msg, F_CIB_UPDATE, update);
	}
	if(result_data != NULL) {
		add_message_xml(update_msg, F_CIB_UPDATE_RESULT, result_data);
	}

	crm_debug_3("Notifying clients");
	g_hash_table_foreach(client_list, cib_notify_client, update_msg);
	crm_msg_del(update_msg);

	if(update == NULL) {
		if(result == cib_ok) {
			crm_debug_2("Operation %s (on section=%s) completed",
				    op, crm_str(type));
			
		} else {
			crm_warn("Operation %s (on section=%s) FAILED: (%d) %s",
				 op, crm_str(type), result,
				 cib_error2string(result));
		}
		
	} else {
		if(result == cib_ok) {
			crm_debug_2("Completed %s of <%s %s%s>",
				    op, crm_str(type), id?"id=":"", id?id:"");
			
		} else {
			crm_warn("%s of <%s %s%s> FAILED: %s", op,crm_str(type),
				 id?"id=":"", id?id:"", cib_error2string(result));
		}
	}

	crm_debug_3("Notify complete");
}
Ejemplo n.º 18
0
int 
stonithd_node_fence(stonith_ops_t * op)
{
	int rc = ST_FAIL;
	struct ha_msg *request, *reply;

	if (op == NULL) {
		stdlib_log(LOG_ERR, "stonithd_node_fence: op==NULL");
		goto out;
	}
	
	if (!signed_on(chan)) {
		stdlib_log(LOG_NOTICE, "not signed on");
		goto out;
	}

	if (!(request = create_basic_reqmsg_fields(ST_STONITH))) {
		stdlib_log(LOG_ERR, "stonithd_node_fence: "
			   "message creation failed.");
		goto out;
	}

	if (ha_msg_add_int(request, F_STONITHD_OPTYPE, op->optype) != HA_OK) {
		stdlib_log(LOG_ERR, "stonithd_node_fence: "
			   "cannot add optype field to ha_msg.");
		goto out;
	}
	if (ha_msg_add(request, F_STONITHD_NODE, op->node_name ) != HA_OK) {
		stdlib_log(LOG_ERR, "stonithd_node_fence: "
			   "cannot add node_name field to ha_msg.");
		goto out;
	}
	if (op->node_uuid == NULL || (ha_msg_add(request, F_STONITHD_NODE_UUID, 
					op->node_uuid) != HA_OK)) {
		stdlib_log(LOG_ERR, "stonithd_node_fence: "
			   "cannot add node_uuid field to ha_msg.");
		goto out;
	}
	if (ha_msg_add_int(request, F_STONITHD_TIMEOUT, op->timeout) != HA_OK) {
		stdlib_log(LOG_ERR, "stonithd_node_fence: "
			   "cannot add timeout field to ha_msg.");
		goto out;
	}
	if  (op->private_data == NULL || (ha_msg_add(request, F_STONITHD_PDATA, 
					op->private_data) != HA_OK)) {
		stdlib_log(LOG_ERR, "stonithd_node_fence: "
		   "cannot add private_data field to ha_msg.");
		goto out;
	}

	/* Send the stonith request message */
	if (msg2ipcchan(request, chan) != HA_OK) {
		stdlib_log(LOG_ERR
			   , "failed to send stonith request to stonithd");
		goto out;
	}

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

	if ( (reply = msgfromIPC_noauth(chan)) == NULL ) {
		stdlib_log(LOG_ERR, "stonithd_node_fence: fail to fetch reply");
		goto out;
	}
	
	if ( TRUE == is_expected_msg(reply, F_STONITHD_TYPE, ST_APIRPL, 
			     F_STONITHD_APIRPL, ST_RSTONITH, TRUE) ) {
		if( !STRNCMP_CONST(
			cl_get_string(reply,F_STONITHD_APIRET), ST_APIOK) ) {
			rc = ST_OK;
			stdlib_log(LOG_DEBUG, "%s:%d: %s"
				 , __FUNCTION__, __LINE__
				 , "stonithd's synchronous answer is ST_APIOK");
		} else {
			stdlib_log(LOG_ERR, "%s:%d: %s"
			       , __FUNCTION__, __LINE__
			       , "stonithd's synchronous answer is ST_APIFAIL");
		}
	} else {
		stdlib_log(LOG_ERR, "stonithd_node_fence: "
			   "Got an unexpected message.");
		/* Need to handle in other way? */
	}

out:
	ZAPMSG(reply);
	ZAPMSG(request);
	return rc;
}