📄 stonithd.c
字号:
if (st_op->optype == QUERY) { stonithd_log(LOG_DEBUG, "query operation."); return -1; } st_obj = srsc->stonith_obj; if (st_obj == NULL ) { stonithd_log(LOG_ERR, "stonith_operate: " "srsc->stonith_obj == NULL."); return -1; } /* stonith it by myself in child */ if ((pid = fork()) < 0) { stonithd_log(LOG_ERR, "stonith_operate_locally: fork failed."); return -1; } else if (pid > 0) { /* in the parent process */ return pid; } /* now in child process */ /* this operation may be on block status */ exit(stonith_req_reset(st_obj, st_op->optype, g_strdup(st_op->node_name)));}static intrequire_others_to_stonith(stonith_ops_t * st_op){ struct ha_msg * msg; if ((msg = ha_msg_new(1)) == NULL) { stonithd_log(LOG_ERR, "require_others_to_stonith: " "out of memory"); return ST_FAIL; } stonithd_log(LOG_DEBUG, "require_others_to_stonith: begin."); if ( (ha_msg_add(msg, F_TYPE, (st_op->optype == QUERY) ? T_WHOCANST : T_STIT) != HA_OK) ||(ha_msg_add(msg, F_ORIG, local_nodename) != HA_OK) ||(ha_msg_add(msg, F_STONITHD_NODE, st_op->node_name) != HA_OK) ||(ha_msg_add_int(msg, F_STONITHD_OPTYPE, st_op->optype) != HA_OK) ||(ha_msg_add_int(msg, F_STONITHD_TIMEOUT, st_op->timeout) != HA_OK) ||(ha_msg_add_int(msg, F_STONITHD_CALLID, st_op->call_id) != HA_OK) ) { stonithd_log(LOG_ERR, "require_others_to_stonith: " "cannot add field."); ZAPMSG(msg); return ST_FAIL; } if (hb == NULL) { stonithd_log(LOG_ERR, "require_others_to_stonith: hb==NULL"); ZAPMSG(msg); return ST_FAIL; } if (HA_OK != hb->llc_ops->sendclustermsg(hb, msg) ) { stonithd_log(LOG_ERR,"require_others_to_stonith: " "sendclustermsg failed."); ZAPMSG(msg); return ST_FAIL; } ZAPMSG(msg); stonithd_log(LOG_DEBUG,"require_others_to_stonith: end."); return ST_OK; }static stonith_rsc_t *get_local_stonithobj_can_stonith( const char * node_name, const char * begin_rsc_id ){ GList * tmplist = NULL; GList * begin_search_list = NULL; stonith_rsc_t * tmp_srsc = NULL; if (local_started_stonith_rsc == NULL) { stonithd_log(LOG_ERR, "get_local_stonithobj_can_stonith: " "local_started_stonith_rsc == NULL"); return NULL; } if ( node_name == NULL ) { stonithd_log(LOG_ERR, "get_local_stonithobj_can_stonith: " "node_name == NULL"); return NULL; } if (begin_rsc_id == NULL) { begin_search_list = g_list_first(local_started_stonith_rsc); } else { for ( tmplist = g_list_first(local_started_stonith_rsc); tmplist != NULL; tmplist = g_list_next(tmplist)) { tmp_srsc = (stonith_rsc_t *)tmplist->data; if ( tmp_srsc != NULL && strncmp(tmp_srsc->rsc_id, begin_rsc_id, strlen(begin_rsc_id)) == 0) { begin_search_list = g_list_next(tmplist); } } } if (begin_search_list == NULL) { stonithd_log(LOG_ERR, "get_local_stonithobj_can_stonith: " "begin_rsc_id donnot exist"); } else { begin_search_list = g_list_first(local_started_stonith_rsc); } for ( tmplist = begin_search_list; tmplist != NULL; tmplist = g_list_next(tmplist)) { tmp_srsc = (stonith_rsc_t *)tmplist->data; if ( tmp_srsc != NULL && tmp_srsc->node_list != NULL ) { char ** this; for(this=tmp_srsc->node_list; *this; ++this) { if ( strncmp(node_name, *this, strlen(node_name)) == 0 ) { return tmp_srsc; } } } } return NULL;}static gbooleanstonithop_timeout(gpointer data){ int * call_id = (int *) data; int * orig_key = NULL; common_op_t * op = NULL; if (data == NULL) { stonithd_log(LOG_ERR, "stonithop_timeout: user_data == NULL."); return FALSE; } stonithd_log(LOG_DEBUG, "stonithop_timeout: begin."); /* since g_hash_table_find donnot exist in early version of glib-2.0 */ my_hash_table_find(executing_queue, (gpointer *)&orig_key, (gpointer *)&op, call_id); if ( op != NULL && (op->scenario == STONITH_INIT || op->scenario == STONITH_REQ)) { if (op->op_union.st_op->optype != QUERY) { op->op_union.st_op->op_result = STONITH_TIMEOUT; } else { op->op_union.st_op->op_result = STONITH_SUCCEEDED; } send_stonithop_final_result(op); /* Pay attention to not free over */ g_hash_table_remove(executing_queue, orig_key); } else { stonithd_log(LOG_DEBUG, "stonithop_timeout: the stonith operation" "(call_id==%d) has finished.", *call_id); } /* Kill the possible child process forked for this operation */ if (orig_key!=NULL && *orig_key > 0 && CL_PID_EXISTS(*orig_key)) { CL_KILL(*orig_key, 9); } return FALSE;}typedef struct { gpointer * key; gpointer * value; gpointer user_data;} lookup_data_t;static voidmy_hash_table_find(GHashTable * htable, gpointer * orig_key, gpointer * value, gpointer user_data){ lookup_data_t tmp_data; tmp_data.key = orig_key; tmp_data.value = value; tmp_data.user_data = user_data; g_hash_table_foreach(htable, has_this_callid, (gpointer)&tmp_data);}static voidhas_this_callid(gpointer key, gpointer value, gpointer user_data){ int callid; common_op_t * op; lookup_data_t * tmp_data = user_data; if (user_data == NULL) { stonithd_log(LOG_ERR, "has_this_callid: user_data == NULL."); return; } else { callid = *(int *)tmp_data->user_data; } if ( value == NULL ) { stonithd_log(LOG_ERR, "has_this_callid: value == NULL."); return; } else { op = (common_op_t *)value; } if (op->scenario != STONITH_INIT && op->scenario != STONITH_REQ ) { stonithd_log(LOG_ERR, "has_this_callid: scenario value error."); return; } if (op->op_union.st_op != NULL && op->op_union.st_op->call_id == callid ) { *(tmp_data->key) = key; *(tmp_data->value) = value; }}static inton_stonithd_virtual_stonithRA_ops(const struct ha_msg * request, gpointer data){ const char * api_reply = ST_APIOK; IPC_Channel * ch = (IPC_Channel *) data; struct ha_msg * reply; const char * tmpstr = NULL; stonithRA_ops_t * ra_op; int * child_pid = NULL; stonithd_client_t * client = NULL; stonithd_log(LOG_DEBUG, "on_stonithd_stonithRA_ops: begin."); /* parameter check, maybe redundant */ if ( ch == NULL || request == NULL ) { stonithd_log(LOG_ERR, "on_virtual_stonithRA_ops: " "parameter error."); return ST_FAIL; } /* Check if have signoned */ if ((client = get_exist_client_by_chan(client_list, ch)) == NULL ) { stonithd_log(LOG_ERR, "on_stonithd_virtual_stonithRA_ops: " "not signoned yet."); return ST_FAIL; } /* handle the RA operations such as 'start' 'stop', 'monitor' and etc */ ra_op = g_new(stonithRA_ops_t, 1); if ((tmpstr = cl_get_string(request, F_STONITHD_RSCID)) != NULL) { ra_op->rsc_id = g_strdup(tmpstr); stonithd_log(LOG_DEBUG, "ra_op->rsc_id=%s.", ra_op->rsc_id); } else { stonithd_log(LOG_ERR, "on_stonithd_virtual_stonithRA_ops: " "the request message contains no rsc_id field."); api_reply = ST_BADREQ; goto send_back_reply; } if ((tmpstr = cl_get_string(request, F_STONITHD_RAOPTYPE)) != NULL) { ra_op->op_type = g_strdup(tmpstr); stonithd_log(LOG_DEBUG, "ra_op->op_type=%s.", ra_op->op_type); } else { stonithd_log(LOG_ERR, "on_stonithd_virtual_stonithRA_ops: the " "request message contains no op_type field."); api_reply = ST_BADREQ; goto send_back_reply; } if ((tmpstr = cl_get_string(request, F_STONITHD_RANAME)) != NULL) { ra_op->ra_name = g_strdup(tmpstr); stonithd_log(LOG_DEBUG, "ra_op->ra_name=%s.", ra_op->ra_name); } else { stonithd_log(LOG_ERR, "on_stonithd_virtual_stonithRA_ops: the " "request message contains no ra_name field."); api_reply = ST_BADREQ; goto send_back_reply; } ra_op->params = NULL; if ((ra_op->params = cl_get_hashtable(request, F_STONITHD_PARAMS)) != NULL) { stonithd_log(LOG_DEBUG, "ra_op->params address:=%p.", ra_op->params); } else { stonithd_log(LOG_ERR, "on_stonithd_virtual_stonithRA_ops: the " "request msg contains no parameter field."); api_reply = ST_BADREQ; goto send_back_reply; } /* execute stonith plugin : begin */ /* When in parent process then be back here */ child_pid = g_new(int,1); if ((*child_pid = stonithRA_operate(ra_op, NULL)) <= 0) { api_reply = ST_APIFAIL; } else { common_op_t * op; int * key_tmp; op = g_new(common_op_t, 1); op->scenario = STONITH_RA_OP; op->result_receiver = client->ch; op->op_union.ra_op = ra_op; key_tmp = g_new(int, 1); *key_tmp = *child_pid; g_hash_table_insert(executing_queue, key_tmp, op); stonithd_log(LOG_DEBUG, "on_stonithd_virtual_stonithRA_ops: " "insert child_pid=%d to table", *key_tmp); } /* execute stonith plugin : end */ /* send back the sync result at once */send_back_reply: 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_RRAOP) != HA_OK ) ||(ha_msg_add(reply, F_STONITHD_APIRET, api_reply) != HA_OK ) ||(ha_msg_add_int(reply, F_STONITHD_CALLID, *child_pid) != HA_OK ) ) { ZAPMSG(reply); stonithd_log(LOG_ERR, "on_stonithd_virtual_stonithRA_ops: " "cannot add message field."); g_free(child_pid); return ST_FAIL; } g_free(child_pid); if (msg2ipcchan(reply, ch) != HA_OK) { /* How to deal the error*/ ZAPCHAN(ch); /* ? */ ZAPMSG(reply); stonithd_log(LOG_ERR, "on_stonithd_virtual_stonithRA_ops: " "cannot send reply message to IPC"); return ST_FAIL; } if (ch->ops->waitout(ch) == IPC_OK) { stonithd_log(LOG_DEBUG, "on_stonithd_virtual_stonithRA_ops: " "sent back a synchonrous result."); return ST_OK; } else { stonithd_log(LOG_ERR, "on_stonithd_virtaul_stonithRA_ops: " "failed to send back a synchonrous result."); return ST_FAIL; } stonithd_log(LOG_DEBUG, "on_stonithd_virtaul_stonithRA_ops: end");}static intsend_stonithRAop_final_result( stonithRA_ops_t * ra_op, gpointer data){ struct ha_msg * reply = NULL; IPC_Channel * ch = (IPC_Channel *)data; stonithd_log(LOG_DEBUG, "send_stonithRAop_final_result: begin."); if ( ra_op == NULL || data == NULL ) { stonithd_log(LOG_ERR, "send_stonithRAop_final_result: " "parameter error."); return ST_FAIL; } stonithd_log(LOG_DEBUG, "RA %s's op %s finished.", ra_op->ra_name, ra_op->op_type); reply = ha_msg_new(0); stonithd_log(LOG_DEBUG, "ra_op->op_type=%s, ra_op->ra_name=%s", ra_op->op_type, ra_op->ra_name); /* can be deleted*/ if ( (ha_msg_add(reply, F_STONITHD_TYPE, ST_APIRPL) != HA_OK ) ||(ha_msg_add(reply, F_STONITHD_APIRPL, ST_RAOPRET) != HA_OK ) ||(ha_msg_add(reply, F_STONITHD_RAOPTYPE, ra_op->op_type) != HA_OK) ||(ha_msg_add(reply, F_STONITHD_RANAME, ra_op->ra_name) != HA_OK) ||(ha_msg_add(reply, F_STONITHD_RSCID, ra_op->rsc_id) != HA_OK) ||(ha_msg_addhash(reply, F_STONITHD_PARAMS, ra_op->params) != HA_OK) ||(ha_msg_add_int(reply, F_STONITHD_CALLID, ra_op->call_id)!= HA_OK) ||(ha_msg_add_int(reply, F_STONITHD_FRC, ra_op->op_result) != HA_OK )) { ZAPMSG(reply); stonithd_log(LOG_ERR, "send_stonithRAop_final_result: cannot " "add message fields."); return ST_FAIL; } if ( msg2ipcchan(reply, ch) != HA_OK) { ZAPCHAN(ch); /* ? */ ZAPMSG(reply); stonithd_log(LOG_ERR, "send_stonithRAop_final_result: cannot " "send final result message via IPC"); return ST_FAIL; } else { stonithd_log(LOG_DEBUG, "send_stonithRAop_final_result: " "succeed in sending back final result message."); } ZAPMSG(reply); return ST_OK;}static intpost_handle_raop(stonithRA_ops_t * ra_op){ int i; for (i = 0; i < DIMOF(raop_handler); i++) { if ( strncmp(ra_op->op_type, raop_handler[i].op_type, strlen(ra_op->op_type)) == 0 ) { /* call the handler of the operation */ if (raop_handler[i].post_handler != NULL) { return raop_handler[i].post_handler(ra_op, NULL); } } } if (i == DIMOF(raop_handler)) { stonithd_log(LOG_NOTICE, "received an unknown RA op," "and now just ignore it."); return ST_FAIL; } return ST_OK;}static inton_stonithd_list_stonith_types(const struct ha_msg * request, gpointer data){ const char * api_reply = ST_APIOK; IPC_Channel * ch = (IPC_Channel *) data; struct ha_msg * reply; char ** typelist; /* Need to check whether signon? */ reply = ha_msg_new(0); typelist = stonith_types(); if (typelist == NULL) { stonithd_log(LOG_ERR, "Could not list Stonith types."); api_reply = ST_APIFAIL; } else { char ** this; for(this = typelist; *this; ++this) { stonithd_log(LOG_DEBUG,"stonith type: %s\n", *this); if ( HA_OK != cl_msg_list_add_string(reply, F_STONITHD_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -