static int send_request(IPC_Channel *chan, struct ha_msg *request, int timeout) { int rc; assert(chan != NULL); assert(request != NULL); /* Send the request message */ if (msg2ipcchan(request, chan) != HA_OK) { stdlib_log(LOG_ERR, "can't send signon message to IPC"); return ST_FAIL; } /* wait for the output to finish */ /* XXX: the time ellapsed should be substracted from timeout * each time the call is resumed. */ do { rc = chan_waitout_timeout(chan, timeout); } while (rc == IPC_INTR); if (rc != IPC_OK) { stdlib_log(LOG_ERR, "waitout failed."); return ST_FAIL; } return ST_OK; }
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"); } }
int stonithd_signoff(void) { struct ha_msg * request; gboolean connected = TRUE; if (chan == NULL || chan->ch_status != IPC_CONNECT) { connected = FALSE; } else if (cbchan == NULL || cbchan->ch_status != IPC_CONNECT) { connected = FALSE; } if (!connected) { stdlib_log(LOG_NOTICE, "Not currently connected."); goto bail; } if ( (request = create_basic_reqmsg_fields(ST_SIGNOFF)) == NULL) { stdlib_log(LOG_ERR, "Couldn't create signoff message!"); goto bail; } /* Send the signoff request message */ if (msg2ipcchan(request, chan) != HA_OK) { ZAPMSG(request); stdlib_log(LOG_ERR, "Control channel dead - can't send signoff message"); goto bail; } /* waiting for the output to finish */ chan_waitout_timeout(chan, DEFAULT_TIMEOUT); ZAPMSG(request); bail: if (NULL != chan) { chan->ops->destroy(chan); chan = NULL; } if (NULL != cbchan) { cbchan->ops->destroy(cbchan); cbchan = NULL; } return ST_OK; }
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; }
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_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 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; }