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; }
/* 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__); } }
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); } );
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; }