int set_node_name(int argc, char **argv) { iscsid_set_node_name_req_t req; iscsid_response_t *rsp; uint64_t isid; memset(&req, 0x0, sizeof(req)); if (!cl_get_string('n', (char *)req.InitiatorName, argc, argv)) { arg_missing("Initiator Name"); } cl_get_string('A', (char *)req.InitiatorAlias, argc, argv); isid = cl_get_longlong('i', argc, argv); hton6(req.ISID, isid); check_extra_args(argc, argv); send_request(ISCSID_SET_NODE_NAME, sizeof(req), &req); rsp = get_response(FALSE); if (rsp->status) { status_error(rsp->status); } free_response(rsp); printf("OK\n"); return 0; }
enum cib_errors cib_process_shutdown_req( 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) { enum cib_errors result = cib_ok; const char *host = cl_get_string(input, F_ORIG); *answer = NULL; if(cl_get_string(input, F_CIB_ISREPLY) == NULL) { crm_info("Shutdown REQ from %s", host); return cib_ok; } else if(cib_shutdown_flag) { crm_info("Shutdown ACK from %s", host); terminate_ha_connection(__FUNCTION__); return cib_ok; } else { crm_err("Shutdown ACK from %s - not shutting down",host); result = cib_unknown; } return result; }
int remove_isns_server(int argc, char **argv) { iscsid_sym_id_t req; iscsid_search_list_req_t srch; iscsid_response_t *rsp; if (!cl_get_id('I', &req, argc, argv)) { if (!cl_get_string('a', (char *)srch.strval, argc, argv)) { arg_missing("Server Address"); } check_extra_args(argc, argv); srch.search_kind = FIND_ADDRESS; srch.list_kind = ISNS_LIST; send_request(ISCSID_SEARCH_LIST, sizeof(srch), &srch); rsp = get_response(FALSE); if (rsp->status) { status_error_slist(rsp->status); } GET_SYM_ID(req.id, rsp->parameter); free_response(rsp); } else { check_extra_args(argc, argv); } send_request(ISCSID_REMOVE_ISNS_SERVER, sizeof(req), &req); rsp = get_response(TRUE); if (rsp->status) { status_error(rsp->status); } free_response(rsp); printf("OK\n"); return 0; }
int add_initiator(int argc, char **argv) { iscsid_add_initiator_req_t req; iscsid_add_initiator_rsp_t *res; iscsid_response_t *rsp; memset(&req, 0x0, sizeof(req)); if (!cl_get_string('a', (char *)req.address, argc, argv)) { arg_missing("Interface Address"); } cl_get_symname(req.name, argc, argv); check_extra_args(argc, argv); send_request(ISCSID_ADD_INITIATOR_PORTAL, sizeof(req), &req); rsp = get_response(FALSE); if (rsp->status) { status_error(rsp->status); } res = (iscsid_add_initiator_rsp_t *)(void *)rsp->parameter; printf("Added Initiator Portal %d\n", res->portal_id); free_response(rsp); return 0; }
xmlNode * convert_ha_message(xmlNode * parent, HA_Message * msg, const char *field) { int lpc = 0; xmlNode *child = NULL; const char *tag = NULL; CRM_CHECK(msg != NULL, crm_err("Empty message for %s", field); return parent); tag = cl_get_string(msg, F_XML_TAGNAME); if (tag == NULL) { tag = field; } else if (parent && safe_str_neq(field, tag)) { /* For compatibility with 0.6.x */ crm_debug("Creating intermediate parent %s between %s and %s", field, crm_element_name(parent), tag); parent = create_xml_node(parent, field); } if (parent == NULL) { parent = create_xml_node(NULL, tag); child = parent; } else { child = create_xml_node(parent, tag); } for (lpc = 0; lpc < msg->nfields; lpc++) { convert_ha_field(child, msg, lpc); } return parent; }
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); }
static int authenticate_with_cookie(IPC_Channel *chan, cl_uuid_t *cookie) { struct ha_msg * request; struct ha_msg * reply; assert(chan != NULL); assert(cookie != NULL); if (!(request = create_basic_reqmsg_fields(ST_SIGNON))) { return ST_FAIL; } if (ha_msg_adduuid(request, F_STONITHD_COOKIE, cookie) != HA_OK) { stdlib_log(LOG_ERR, "cannot add field to ha_msg."); ZAPMSG(request); return ST_FAIL; } /* Send request/read response */ if (send_request(chan, request, DEFAULT_TIMEOUT) != ST_OK) { ZAPMSG(request); return ST_FAIL; } ZAPMSG(request); if (!(reply = recv_response(chan, DEFAULT_TIMEOUT))) { return ST_FAIL; } /* Are we signed on this time? */ if ( TRUE == is_expected_msg(reply, F_STONITHD_TYPE, ST_APIRPL, F_STONITHD_APIRPL, ST_RSIGNON, TRUE) ) { if ( !STRNCMP_CONST( cl_get_string(reply,F_STONITHD_APIRET), ST_APIOK) ) { ZAPMSG(reply); return ST_OK; } } ZAPMSG(reply); return ST_FAIL; }
static gboolean cmp_field(const struct ha_msg * msg, const char * field_name, const char * field_content, gboolean mandatory) { const char * tmpstr; tmpstr = cl_get_string(msg, field_name); if ( tmpstr && strncmp(tmpstr, field_content, 80) == 0 ) { return TRUE; } else { stdlib_log(mandatory ? LOG_ERR : LOG_NOTICE , "field <%s> content is " " <%s>, expected content is: <%s>" , field_name , (NULL == tmpstr) ? "NULL" : tmpstr , field_content); return FALSE; } }
static void general_struct_display(int log_level, int seq, char* name, void* value, int vlen, int type) { int slen; int netslen; HA_MSG_ASSERT(name); HA_MSG_ASSERT(value); slen = fieldtypefuncs[type].stringlen(strlen(name), vlen, value); netslen = fieldtypefuncs[type].netstringlen(strlen(name), vlen, value); cl_log(log_level, "MSG[%d] : [(%s)%s=%p(%d %d)]", seq, FT_strings[type], name, value, slen, netslen); if(cl_get_string((struct ha_msg*) value, F_XML_TAGNAME) == NULL) { cl_log_message(log_level, (struct ha_msg*) value); } else { /* use a more friendly output format for nested messages */ struct_display_as_xml(log_level, 0, value, NULL, TRUE); } }
STATIC int do_remove_target(int argc, char **argv, iscsid_list_kind_t kind) { iscsid_list_id_t req; iscsid_search_list_req_t srch; iscsid_response_t *rsp; if (!cl_get_id('I', &req.id, argc, argv)) { if (!cl_get_string('n', (char *)srch.strval, argc, argv)) { arg_missing("Target ID or Name"); } check_extra_args(argc, argv); srch.search_kind = FIND_TARGET_NAME; srch.list_kind = kind; send_request(ISCSID_SEARCH_LIST, sizeof(srch), &srch); rsp = get_response(FALSE); if (rsp->status) { status_error_slist(rsp->status); } GET_SYM_ID(req.id.id, rsp->parameter); free_response(rsp); } else { check_extra_args(argc, argv); } req.list_kind = kind; send_request(ISCSID_REMOVE_TARGET, sizeof(req), &req); rsp = get_response(TRUE); if (rsp->status) { status_error(rsp->status); } free_response(rsp); printf("OK\n"); return 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); } );
void cib_notify_client(gpointer key, gpointer value, gpointer user_data) { IPC_Channel *ipc_client = NULL; HA_Message *update_msg = user_data; cib_client_t *client = value; const char *type = NULL; gboolean is_pre = FALSE; gboolean is_post = FALSE; gboolean is_confirm = FALSE; gboolean is_replace = FALSE; gboolean is_diff = FALSE; gboolean do_send = FALSE; int qlen = 0; int max_qlen = 0; CRM_DEV_ASSERT(client != NULL); CRM_DEV_ASSERT(update_msg != NULL); type = cl_get_string(update_msg, F_SUBTYPE); CRM_DEV_ASSERT(type != NULL); if(client == NULL) { crm_warn("Skipping NULL client"); return; } else if(client->channel == NULL) { crm_warn("Skipping client with NULL channel"); return; } else if(client->name == NULL) { crm_debug_2("Skipping unnammed client / comamnd channel"); return; } if(safe_str_eq(type, T_CIB_PRE_NOTIFY)) { is_pre = TRUE; } else if(safe_str_eq(type, T_CIB_POST_NOTIFY)) { is_post = TRUE; } else if(safe_str_eq(type, T_CIB_UPDATE_CONFIRM)) { is_confirm = TRUE; } else if(safe_str_eq(type, T_CIB_DIFF_NOTIFY)) { is_diff = TRUE; } else if(safe_str_eq(type, T_CIB_REPLACE_NOTIFY)) { is_replace = TRUE; } ipc_client = client->channel; qlen = ipc_client->send_queue->current_qlen; max_qlen = ipc_client->send_queue->max_qlen; #if 1 /* get_chan_status() causes memory to be allocated that isnt free'd * until the message is read (which messes up the memory stats) */ if(ipc_client->ops->get_chan_status(ipc_client) != IPC_CONNECT) { crm_debug_2("Skipping notification to disconnected" " client %s/%s", client->name, client->id); } else if(client->pre_notify && is_pre) { if(qlen < (int)(0.4 * max_qlen)) { do_send = TRUE; } else { crm_warn("Throttling pre-notifications due to" " high load: queue=%d (max=%d)", qlen, max_qlen); } } else if(client->post_notify && is_post) { if(qlen < (int)(0.7 * max_qlen)) { do_send = TRUE; } else { crm_warn("Throttling post-notifications due to" " extreme load: queue=%d (max=%d)", qlen, max_qlen); } /* these are critical */ } else #endif if(client->diffs && is_diff) { do_send = TRUE; } else if(client->confirmations && is_confirm) { do_send = TRUE; } else if(client->replace && is_replace) { do_send = TRUE; } if(do_send) { crm_debug_2("Notifying client %s/%s of %s update (queue=%d)", client->name, client->channel_name, type, qlen); if(ipc_client->send_queue->current_qlen >= ipc_client->send_queue->max_qlen) { /* We never want the CIB to exit because our client is slow */ crm_crit("%s-notification of client %s/%s failed - queue saturated", is_confirm?"Confirmation":is_post?"Post":"Pre", client->name, client->id); } else if(send_ipc_message(ipc_client, update_msg) == FALSE) { crm_warn("Notification of client %s/%s failed", client->name, client->id); } } else { crm_debug_3("Client %s/%s not interested in %s notifications", client->name, client->channel_name, type); } }
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; }
int register_fsa_input_adv( enum crmd_fsa_cause cause, enum crmd_fsa_input input, void *data, long long with_actions, gboolean prepend, const char *raised_from) { unsigned old_len = g_list_length(fsa_message_queue); fsa_data_t *fsa_data = NULL; last_data_id++; CRM_CHECK(raised_from != NULL, raised_from = "<unknown>"); crm_debug("%s %s FSA input %d (%s) (cause=%s) %s data", raised_from, prepend?"prepended":"appended",last_data_id, fsa_input2string(input), fsa_cause2string(cause), data?"with":"without"); if(input == I_WAIT_FOR_EVENT) { do_fsa_stall = TRUE; crm_debug("Stalling the FSA pending further input: cause=%s", fsa_cause2string(cause)); if(old_len > 0) { crm_warn("%s stalled the FSA with pending inputs", raised_from); fsa_dump_queue(LOG_DEBUG); } if(data == NULL) { set_bit_inplace(fsa_actions, with_actions); with_actions = A_NOTHING; return 0; } crm_err("%s stalled the FSA with data - this may be broken", raised_from); } if(old_len == 0) { last_was_vote = FALSE; } if(input == I_NULL && with_actions == A_NOTHING /* && data == NULL */) { /* no point doing anything */ crm_err("Cannot add entry to queue: no input and no action"); return 0; } else if(data == NULL) { last_was_vote = FALSE; #if 0 } else if(last_was_vote && cause == C_HA_MESSAGE && input == I_ROUTER) { const char *op = cl_get_string( ((ha_msg_input_t*)data)->msg, F_CRM_TASK); if(safe_str_eq(op, CRM_OP_VOTE)) { /* It is always safe to treat N successive votes as * a single one * * If all the discarded votes are more "loosing" than * the first then the result is accurate * (win or loose). * * If any of the discarded votes are less "loosing" * than the first then we will cast our vote and the * eventual winner will vote us down again (which * even in the case that N=2, is no worse than if we * had not disarded the vote). */ crm_debug_2("Vote compression: %d", old_len); return 0; } #endif } else if (cause == C_HA_MESSAGE && input == I_ROUTER) { const char *op = cl_get_string( ((ha_msg_input_t*)data)->msg, F_CRM_TASK); if(safe_str_eq(op, CRM_OP_VOTE)) { last_was_vote = TRUE; crm_debug_3("Added vote: %d", old_len); } } else { last_was_vote = FALSE; } crm_malloc0(fsa_data, sizeof(fsa_data_t)); fsa_data->id = last_data_id; fsa_data->fsa_input = input; fsa_data->fsa_cause = cause; fsa_data->origin = raised_from; fsa_data->data = NULL; fsa_data->data_type = fsa_dt_none; fsa_data->actions = with_actions; if(with_actions != A_NOTHING) { crm_debug_3("Adding actions %.16llx to input", with_actions); } if(data != NULL) { switch(cause) { case C_FSA_INTERNAL: case C_CRMD_STATUS_CALLBACK: case C_IPC_MESSAGE: case C_HA_MESSAGE: crm_debug_3("Copying %s data from %s as a HA msg", fsa_cause2string(cause), raised_from); fsa_data->data = copy_ha_msg_input(data); fsa_data->data_type = fsa_dt_ha_msg; break; case C_LRM_OP_CALLBACK: crm_debug_3("Copying %s data from %s as lrm_op_t", fsa_cause2string(cause), raised_from); fsa_data->data = copy_lrm_op((lrm_op_t*)data); fsa_data->data_type = fsa_dt_lrm; break; case C_CCM_CALLBACK: crm_debug_3("Copying %s data from %s as CCM data", fsa_cause2string(cause), raised_from); fsa_data->data = copy_ccm_data(data); fsa_data->data_type = fsa_dt_ccm; break; case C_SUBSYSTEM_CONNECT: case C_LRM_MONITOR_CALLBACK: case C_TIMER_POPPED: case C_SHUTDOWN: case C_HEARTBEAT_FAILED: case C_HA_DISCONNECT: case C_ILLEGAL: case C_UNKNOWN: case C_STARTUP: crm_err("Copying %s data (from %s)" " not yet implemented", fsa_cause2string(cause), raised_from); exit(1); break; } crm_debug_4("%s data copied", fsa_cause2string(fsa_data->fsa_cause)); } /* make sure to free it properly later */ if(prepend) { crm_debug_2("Prepending input"); fsa_message_queue = g_list_prepend(fsa_message_queue, fsa_data); } else { fsa_message_queue = g_list_append(fsa_message_queue, fsa_data); } crm_debug_2("Queue len: %d", g_list_length(fsa_message_queue)); fsa_dump_queue(LOG_DEBUG_2); if(old_len == g_list_length(fsa_message_queue)) { crm_err("Couldnt add message to the queue"); } if(fsa_source) { crm_debug_3("Triggering FSA: %s", __FUNCTION__); G_main_set_trigger(fsa_source); } return last_data_id; }
int stonithd_receive_ops_result(gboolean blocking) { struct ha_msg* reply = NULL; const char *reply_type; int rc = ST_OK; stdlib_log(LOG_DEBUG, "stonithd_receive_ops_result: begin"); /* If there is no msg ready and none blocking mode, then return */ if ((stonithd_op_result_ready() == FALSE) && (blocking == FALSE)) { stdlib_log(LOG_DEBUG, "stonithd_receive_ops_result: " "no result available."); return ST_OK; } if (stonithd_op_result_ready() == FALSE) { /* at that time, blocking must be TRUE */ rc = cbchan->ops->waitin(cbchan); if (IPC_OK != rc) { if (cbchan->ch_status == IPC_DISCONNECT) { stdlib_log(LOG_INFO, "%s:%d: disconnected", __FUNCTION__, __LINE__); } else if (IPC_INTR == rc) { stdlib_log(LOG_INFO, "%s:%d: waitin interrupted", __FUNCTION__, __LINE__); } else { stdlib_log(LOG_WARNING, "%s:%d: waitin failed: %d", __FUNCTION__, __LINE__,rc); } return ST_FAIL; } } reply = msgfromIPC_noauth(cbchan); reply_type = cl_get_string(reply, F_STONITHD_APIRPL); if ( !is_expected_msg(reply, F_STONITHD_TYPE, ST_APIRPL, F_STONITHD_APIRPL, reply_type, TRUE)) { ZAPMSG(reply); stdlib_log(LOG_DEBUG, "%s:%d: " "got an unexpected message", __FUNCTION__, __LINE__); return ST_FAIL; } if( !strcmp(reply_type, ST_STRET) ) { stonith_ops_t *st_op = NULL; /* handle the stonith op result message */ if( !(st_op = g_new(stonith_ops_t, 1)) ) { stdlib_log(LOG_ERR, "out of memory"); return ST_FAIL; } st_op->node_uuid = NULL; st_op->private_data = NULL; st_get_int_value(reply, F_STONITHD_OPTYPE, (int*)&st_op->optype); st_save_string(reply, F_STONITHD_NODE, st_op->node_name); st_save_string(reply, F_STONITHD_NODE_UUID, st_op->node_uuid); st_get_int_value(reply, F_STONITHD_TIMEOUT, &st_op->timeout); st_get_int_value(reply, F_STONITHD_CALLID, &st_op->call_id); st_get_int_value(reply, F_STONITHD_FRC, (int*)&st_op->op_result); st_save_string(reply, F_STONITHD_NLIST, st_op->node_list); st_save_string(reply, F_STONITHD_PDATA, st_op->private_data); if (stonith_ops_cb != NULL) { stonith_ops_cb(st_op); } free_stonith_ops_t(st_op); } else if( !strcmp(reply_type, ST_RAOPRET) ) { stonithRA_ops_t *ra_op = NULL; /* handle the stonithRA op result message */ if( !(ra_op = g_new(stonithRA_ops_t, 1)) ) { stdlib_log(LOG_ERR, "out of memory"); return ST_FAIL; } st_save_string(reply, F_STONITHD_RSCID, ra_op->rsc_id); st_save_string(reply, F_STONITHD_RAOPTYPE, ra_op->op_type); st_save_string(reply, F_STONITHD_RANAME, ra_op->ra_name); st_get_hashtable(reply, F_STONITHD_PARAMS, ra_op->params); st_get_int_value(reply, F_STONITHD_CALLID, &ra_op->call_id); st_get_int_value(reply, F_STONITHD_FRC, &ra_op->op_result); /* if ( rc == ST_OK && stonithRA_ops_cb != NULL) */ if ( stonithRA_ops_cb ) { stonithRA_ops_cb(ra_op, stonithRA_ops_cb_private_data); } free_stonithRA_ops_t(ra_op); } else { stdlib_log(LOG_DEBUG, "%s:%d: " "got an unexpected message", __FUNCTION__, __LINE__); rc = ST_FAIL; } ZAPMSG(reply); return rc; }
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; }
int stonithd_list_stonith_types(GList ** types) { int rc = ST_FAIL; struct ha_msg * request, * reply; const char * tmpstr; if ( !signed_on(chan) ) { stdlib_log(LOG_ERR, "not signed on"); return ST_FAIL; } if ( (request = create_basic_reqmsg_fields(ST_LTYPES)) == NULL) { 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 reply to list stonith types."); if ( IPC_OK != chan_waitin_timeout(chan, DEFAULT_TIMEOUT) ) { stdlib_log(LOG_ERR, "%s:%d: chan_waitin failed." , __FUNCTION__, __LINE__); return ST_FAIL; } if ( (reply = msgfromIPC_noauth(chan)) == NULL ) { stdlib_log(LOG_ERR, "stonithd_list_stonith_types: " "failed to fetch reply."); return ST_FAIL; } *types = NULL; if ( TRUE == is_expected_msg(reply, F_STONITHD_TYPE, ST_APIRPL, F_STONITHD_APIRPL, ST_RLTYPES, TRUE) ) { if ( ((tmpstr = cl_get_string(reply, F_STONITHD_APIRET)) != NULL) && (STRNCMP_CONST(tmpstr, ST_APIOK) == 0) ) { int i; int len=cl_msg_list_length(reply, F_STONITHD_STTYPES); if ( len < 0 ) { stdlib_log(LOG_ERR, "Not field to list stonith " "types."); } else { for (i = 0; i < len; i++) { tmpstr = cl_msg_list_nth_data(reply, F_STONITHD_STTYPES, i); if( tmpstr ) { *types = g_list_append(*types, g_strdup(tmpstr)); } } stdlib_log(LOG_DEBUG, "got stonith types."); rc = ST_OK; } } else { stdlib_log(LOG_DEBUG, "failed to get stonith types."); } } else { stdlib_log(LOG_DEBUG, "stonithd_list_stonith_types: " "Got an unexpected message."); } ZAPMSG(reply); return rc; }
/* 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__); } }
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; }
int struct_display_as_xml( int log_level, int depth, struct ha_msg *data, const char *prefix, gboolean formatted) { int lpc = 0; int printed = 0; gboolean has_children = FALSE; char print_buffer[1000]; char *buffer = print_buffer; const char *name = cl_get_string(data, F_XML_TAGNAME); if(data == NULL) { return 0; } else if(name == NULL) { cl_log(LOG_WARNING, "Struct at depth %d had no name", depth); cl_log_message(log_level, data); return 0; } if(formatted) { printed = struct_display_print_spaces(buffer, depth); update_buffer_head(buffer, printed); } printed = sprintf(buffer, "<%s", name); update_buffer_head(buffer, printed); for (lpc = 0; lpc < data->nfields; lpc++) { const char *prop_name = data->names[lpc]; const char *prop_value = data->values[lpc]; if(data->types[lpc] != FT_STRING) { continue; } else if(prop_name == NULL) { continue; } else if(prop_name[0] == '_' && prop_name[1] == '_') { continue; } printed = sprintf(buffer, " %s=\"%s\"", prop_name, prop_value); update_buffer_head(buffer, printed); } for (lpc = 0; lpc < data->nfields; lpc++) { if(data->types[lpc] == FT_STRUCT) { has_children = TRUE; break; } } printed = sprintf(buffer, "%s>", has_children==0?"/":""); update_buffer_head(buffer, printed); cl_log(log_level, "%s%s", prefix?prefix:"", print_buffer); buffer = print_buffer; if(has_children == FALSE) { return 0; } for (lpc = 0; lpc < data->nfields; lpc++) { if(data->types[lpc] != FT_STRUCT) { continue; } else if(0 > struct_display_as_xml( log_level, depth+1, data->values[lpc], prefix, formatted)) { return -1; } } if(formatted) { printed = struct_display_print_spaces(buffer, depth); update_buffer_head(buffer, printed); } cl_log(log_level, "%s%s</%s>", prefix?prefix:"", print_buffer, name); return 0; }