stonithd.c
来自「linux集群服务器软件代码包」· C语言 代码 · 共 2,226 行 · 第 1/5 页
C
2,226 行
||(ha_msg_add(reply, F_STONITHD_APIRPL, ST_RSIGNOFF) != HA_OK ) ||(ha_msg_add(reply, F_STONITHD_APIRET, api_reply) != HA_OK ) ) { ZAPMSG(reply); stonithd_log(LOG_ERR, "on_stonithd_signoff: cannot add field."); return ST_FAIL; } if (msg2ipcchan(reply, ch) != HA_OK) { /* How to deal the error*/ ZAPCHAN(ch); /* ? */ ZAPMSG(reply); stonithd_log(LOG_ERR, "can't send signoff reply message to IPC"); return ST_FAIL; } ZAPMSG(reply); return ST_OK;}static inton_stonithd_node_fence(const struct ha_msg * request, gpointer data){ const char * api_reply = ST_APIOK; IPC_Channel * ch = (IPC_Channel *) data; stonith_ops_t * st_op = NULL; struct ha_msg * reply; int tmpint; const char * tmpstr = NULL; int call_id = 0; stonithd_client_t * client = NULL; stonith_rsc_t * srsc = NULL; stonithd_log(LOG_DEBUG, "stonithd_node_fence: begin."); /* parameter check, maybe redundant */ if ( ch == NULL || request == NULL ) { stonithd_log(LOG_ERR, "stonithd_node_fence: parameter error."); return ST_FAIL; } /* Check if have signoned */ if ((client = get_exist_client_by_chan(client_list, ch)) == NULL ) { stonithd_log(LOG_ERR, "stonithd_node_fence: not signoned yet."); return ST_FAIL; } st_op = g_new(stonith_ops_t, 1); st_op->node_list = NULL; if ( HA_OK == ha_msg_value_int(request, F_STONITHD_OPTYPE, &tmpint)) { st_op->optype = tmpint; } else { stonithd_log(LOG_ERR, "The stonith requirement message contains" " no operation type field."); api_reply = ST_BADREQ; g_free(st_op); goto sendback_reply; } if (HA_OK == ha_msg_value_int(request, F_STONITHD_TIMEOUT, &tmpint)) { st_op->timeout = tmpint; } else { stonithd_log(LOG_ERR, "The stonith requirement message contains" " no timeout field."); api_reply = ST_BADREQ; g_free(st_op); goto sendback_reply; } if ((tmpstr = cl_get_string(request, F_STONITHD_NODE)) != NULL ) { st_op->node_name = g_strdup(tmpstr); } else { stonithd_log(LOG_ERR, "The stonith requirement message contains" " no target node name field."); api_reply = ST_BADREQ; g_free(st_op); goto sendback_reply; } /* If the node is me, should stonith myself. ;-) No, never come here * from this API while the node name is myself. * So just broadcast the requirement to the whole of cluster to do it. */ if ( st_op->optype != QUERY && TEST == FALSE && (srsc = get_local_stonithobj_can_stonith(st_op->node_name, NULL)) != NULL && (call_id=initiate_local_stonithop(st_op, srsc, client->ch)) > 0 ) { api_reply = ST_APIOK; } else { /* including query operation */ /* call_id < 0 is the correct value when require others to do */ if ((call_id = initiate_remote_stonithop(st_op, srsc, client->ch)) < 0 ) { api_reply = ST_APIOK; } else { free_stonith_ops_t(st_op); api_reply = ST_APIFAIL; } } sendback_reply: /* send back the sync result */ reply = ha_msg_new(3); if ( (ha_msg_add(reply, F_STONITHD_TYPE, ST_APIRPL) != HA_OK ) ||(ha_msg_add(reply, F_STONITHD_APIRPL, ST_RSTONITH) != HA_OK ) ||(ha_msg_add(reply, F_STONITHD_APIRET, api_reply) != HA_OK ) ||(ha_msg_add_int(reply, F_STONITHD_CALLID, call_id)) != HA_OK ) { ZAPMSG(reply); stonithd_log(LOG_ERR, "stonithd_node_fence: cannot add field."); return ST_FAIL; } if (msg2ipcchan(reply, ch) != HA_OK) { ZAPCHAN(ch); /* ? */ ZAPMSG(reply); stonithd_log(LOG_ERR, "stonithd_node_fence: cannot send reply " "message to IPC"); return ST_FAIL; } if (ch->ops->waitout(ch) == IPC_OK) { stonithd_log(LOG_DEBUG, "stonithd_node_fence: end and sent " "back a reply."); } else { stonithd_log(LOG_DEBUG, "stonithd_node_fence: end and " "failed to sent back a reply."); return ST_FAIL; } stonithd_log(LOG_DEBUG, "stonithd_node_fence: end"); return ST_OK;}static intinitiate_local_stonithop(stonith_ops_t * st_op, stonith_rsc_t * srsc, IPC_Channel * ch){ int call_id; if (st_op == NULL || srsc == NULL) { stonithd_log(LOG_ERR, "initiate_local_stonithop: " "st_op == NULL or srsc == NULL."); return -1; } if ((call_id = stonith_operate_locally(st_op, srsc)) <= 0) { stonithd_log(LOG_ERR, "stonith_operate_locally failed."); return -1; } else { common_op_t * op; int * tmp_callid; op = g_new(common_op_t, 1); op->scenario = STONITH_INIT; op->data = srsc->rsc_id; op->result_receiver = ch; st_op->call_id = call_id; op->op_union.st_op = st_op; tmp_callid = g_new(int, 1); *tmp_callid = call_id; g_hash_table_insert(executing_queue, tmp_callid, op); tmp_callid = g_new(int, 1); *tmp_callid = call_id; g_timeout_add_full(G_PRIORITY_HIGH_IDLE, st_op->timeout, stonithop_timeout, tmp_callid, NULL); stonithd_log(LOG_DEBUG, "initiate_local_stonithop: inserted " "optype=%d, child_id=%d", st_op->optype, call_id); return call_id; }}static intcontinue_local_stonithop(int old_key){ stonith_rsc_t * srsc = NULL; char * rsc_id = NULL; int * child_pid; common_op_t * op = NULL; int * orignal_key = NULL; if (FALSE == g_hash_table_lookup_extended(executing_queue, &old_key, (gpointer *)&orignal_key, (gpointer *)&op)) { stonithd_log(LOG_ERR, "continue_local_stonithop: No old_key's " "item exist in executing_queue. Strange!"); return ST_FAIL; } if (op->scenario != STONITH_INIT && op->scenario != STONITH_REQ && op->op_union.st_op == NULL) { stonithd_log(LOG_ERR, "continue_local_stonithop: the old_key's " "item isnot a stonith item. Strange!"); return ST_FAIL; } rsc_id = op->data; child_pid = g_new(int, 1); while ((srsc = get_local_stonithobj_can_stonith(op->op_union.st_op->node_name, rsc_id)) != NULL ) { if ((*child_pid=stonith_operate_locally(op->op_union.st_op, srsc)) > 0) { g_hash_table_steal(executing_queue, orignal_key); stonithd_log(LOG_DEBUG, "continue_local_stonithop: " "removed optype=%d, key_id=%d", op->op_union.st_op->optype, *orignal_key); g_free(orignal_key); orignal_key = NULL; /* donnot need to free the old one */ op->data = srsc->rsc_id; g_hash_table_insert(executing_queue, child_pid, op); stonithd_log(LOG_DEBUG, "continue_local_stonithop: " "inserted optype=%d, child_id=%d", op->op_union.st_op->optype, *child_pid); return ST_OK; } else { rsc_id = srsc->rsc_id; } } g_free(child_pid); return ST_FAIL;}static intinitiate_remote_stonithop(stonith_ops_t * st_op, stonith_rsc_t * srsc, IPC_Channel * ch){ GString * gstr_tmp; if (st_op->optype == QUERY) { gstr_tmp = g_string_new(""); if ( NULL != get_local_stonithobj_can_stonith( st_op->node_name, NULL)) { gstr_tmp = g_string_append(gstr_tmp, local_nodename); } st_op->node_list = gstr_tmp; } st_op->call_id = negative_callid_counter; if (ST_OK!=require_others_to_stonith(st_op) && st_op->optype!=QUERY) { stonithd_log(LOG_ERR, "require_others_to_stonith failed."); st_op->call_id = 0; return 1; } else { common_op_t * op; int * tmp_callid; op = g_new(common_op_t, 1); op->scenario = STONITH_INIT; op->result_receiver = ch; op->op_union.st_op = st_op; tmp_callid = g_new(int, 1); *tmp_callid = st_op->call_id; g_hash_table_insert(executing_queue, tmp_callid, op); tmp_callid = g_new(int, 1); *tmp_callid = st_op->call_id; g_timeout_add_full(G_PRIORITY_HIGH_IDLE, st_op->timeout, stonithop_timeout, tmp_callid, NULL); stonithd_log(LOG_DEBUG, "initiate_remote_stonithop: inserted " "optype=%d, key=%d", op->op_union.st_op->optype, *tmp_callid); stonithd_log(LOG_DEBUG, "initiate_remote_stonithop: " "require_others_to_stonith succeed."); return negative_callid_counter--; }}static intchangeto_remote_stonithop(int old_key){ common_op_t * op = NULL; int * orignal_key = NULL; if (FALSE == g_hash_table_lookup_extended(executing_queue, &old_key, (gpointer *)&orignal_key, (gpointer *)&op)) { stonithd_log(LOG_ERR, "changeto_remote_stonithop: no old_key's " "item exist in executing_queue. Strange!"); return ST_FAIL; } if (op->scenario != STONITH_INIT && op->scenario != STONITH_REQ && op->op_union.st_op == NULL) { stonithd_log(LOG_ERR, "changeto_remote_stonithop: the old_key's" " item isnot a stonith item. Strange!"); return ST_FAIL; } if ( ST_OK != require_others_to_stonith(op->op_union.st_op) ) { stonithd_log(LOG_ERR, "require_others_to_stonith failed."); return ST_FAIL; } else { /* donnt need to free op->data */ op->data = NULL; g_hash_table_steal(executing_queue, orignal_key); stonithd_log(LOG_DEBUG, "changeto_remote_stonithop: removed " "optype=%d, key=%d", op->op_union.st_op->optype, *orignal_key); *orignal_key = op->op_union.st_op->call_id; g_hash_table_insert(executing_queue, orignal_key, op); stonithd_log(LOG_DEBUG, "changeto_remote_stonithop: inserted " "optype=%d, key=%d", op->op_union.st_op->optype, *orignal_key); } return ST_OK;}static intsend_stonithop_final_result( common_op_t * op){ if (op == NULL) { stonithd_log(LOG_ERR, "send_stonithop_final_result: " "op == NULL"); return ST_FAIL; } stonithd_log(LOG_DEBUG, "send_stonithop_final_result: begin."); if (op->scenario == STONITH_INIT) { return stonithop_result_to_local_client( op->op_union.st_op, op->result_receiver); } if (op->scenario == STONITH_REQ) { return stonithop_result_to_other_node( op->op_union.st_op, op->result_receiver); } stonithd_log(LOG_DEBUG, "scenario value may be wrong."); return ST_FAIL;}static intstonithop_result_to_local_client( stonith_ops_t * st_op, gpointer data){ struct ha_msg * reply = NULL; IPC_Channel * ch = (IPC_Channel *)data; stonithd_log(LOG_DEBUG, "stonithop_result_to_local_client: begin."); if ( st_op == NULL || data == NULL ) { stonithd_log(LOG_ERR, "stonithop_result_to_local_client: " "parameter error."); return ST_FAIL; } stonithd_log(LOG_DEBUG, "stonith finished: optype=%d, node_name=%s", st_op->optype, st_op->node_name); reply = ha_msg_new(0); if ( st_op->optype == QUERY) { /* QUERY operation */ if (ha_msg_add(reply, F_STONITHD_APPEND, ((GString *)(st_op->node_list))->str) != HA_OK ) { ZAPMSG(reply); stonithd_log(LOG_ERR, "stonithop_result_to_local_client:" " cannot add fields."); return ST_FAIL; } } if ( (ha_msg_add(reply, F_STONITHD_TYPE, ST_APIRPL) != HA_OK ) ||(ha_msg_add(reply, F_STONITHD_APIRPL, ST_STRET) != HA_OK ) ||(ha_msg_add_int(reply, F_STONITHD_OPTYPE, st_op->optype) != HA_OK) ||(ha_msg_add(reply, F_STONITHD_NODE, st_op->node_name) != HA_OK) ||(ha_msg_add_int(reply, F_STONITHD_TIMEOUT, st_op->timeout)!=HA_OK) ||(ha_msg_add_int(reply, F_STONITHD_CALLID, st_op->call_id) !=HA_OK) ||(ha_msg_add_int(reply, F_STONITHD_FRC, st_op->op_result) != HA_OK )) { ZAPMSG(reply); stonithd_log(LOG_ERR, "stonithop_result_to_local_client: " "cannot add fields."); return ST_FAIL; } if ( msg2ipcchan(reply, ch) != HA_OK) { ZAPCHAN(ch); /* ? */ ZAPMSG(reply); stonithd_log(LOG_ERR, "stonithop_result_to_local_client: cannot" " send final result message via IPC"); return ST_FAIL; } else { stonithd_log(LOG_DEBUG, "stonithop_result_to_local_client: " "succeed in sending back final result message."); } ZAPMSG(reply); stonithd_log(LOG_DEBUG, "stonithop_result_to_local_client: end."); return ST_OK;}static intstonithop_result_to_other_node( stonith_ops_t * st_op, gpointer data){ char * node_name = (char *)data; struct ha_msg * reply; if (data == NULL) { stonithd_log(LOG_ERR, "stonithop_result_to_other_node: " "data == NULL"); return ST_FAIL; } if (st_op->op_result != STONITH_SUCCEEDED) { /* Actually donnot need to send */ return ST_OK; } if ((reply = ha_msg_new(3)) == NULL) { stonithd_log(LOG_ERR, "stonithop_result_to_other_node: " "ha_msg_new: out of memory"); return ST_FAIL; } if ( (ha_msg_add(reply, F_TYPE, T_RSTIT) != HA_OK) ||(ha_msg_add(reply, F_ORIG, local_nodename) != HA_OK) ||(ha_msg_add_int(reply, F_STONITHD_FRC, st_op->op_result) != HA_OK) ||(ha_msg_add_int(reply, F_STONITHD_CALLID, st_op->call_id) != HA_OK)) { stonithd_log(LOG_ERR, "stonithop_result_to_other_node: " "ha_msg_add: cannot add field."); ZAPMSG(reply); return ST_FAIL; } if (hb == NULL) { stonithd_log(LOG_ERR, "stonithop_result_to_other_node: " "hb == NULL"); ZAPMSG(reply); return ST_FAIL; } if (HA_OK!=hb->llc_ops->sendnodemsg(hb, reply, node_name)) { stonithd_log(LOG_ERR, "stonithop_result_to_other_node: " "sendnodermsg failed."); return ST_FAIL; } ZAPMSG(reply); stonithd_log(LOG_DEBUG,"stonithop_result_to_other_node: " "send result message successfully."); return ST_OK; }static intstonith_operate_locally( stonith_ops_t * st_op, stonith_rsc_t * srsc){ Stonith * st_obj = NULL; pid_t pid; if (st_op == NULL || srsc == NULL ) { stonithd_log(LOG_ERR, "stonith_operate_locally: " "parameter error."); return -1; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?