📄 stonithd.c
字号:
/* Don't handle the message about stonithing myself */ if ( strncmp(target, local_nodename, strlen(local_nodename)) == 0) { stonithd_log(LOG_DEBUG, "received a T_STIT message to require " "to stonith myself."); return; } if ( HA_OK != ha_msg_value_int(msg, F_STONITHD_OPTYPE, &optype)) { stonithd_log(LOG_ERR, "handle_msg_tstit: no F_STONITHD_OPTYPE " "field."); return; } if ( HA_OK != ha_msg_value_int(msg, F_STONITHD_CALLID, &call_id)) { stonithd_log(LOG_ERR, "handle_msg_tstit: no F_STONITHD_CALLID " "field."); return; } if ( HA_OK != ha_msg_value_int(msg, F_STONITHD_TIMEOUT, &timeout)) { stonithd_log(LOG_ERR, "handle_msg_tstit: no F_STONITHD_TIMEOUT " "field."); return; } if ((srsc = get_local_stonithobj_can_stonith(target, NULL)) != NULL ) { st_op = g_new(stonith_ops_t, 1); st_op->node_name = g_strdup(target); st_op->optype = optype; st_op->call_id = call_id; st_op->timeout = timeout; st_op->node_list = NULL; if (ST_OK != require_local_stonithop(st_op, srsc, from)) { free_stonith_ops_t(st_op); st_op = NULL; } }}static intrequire_local_stonithop(stonith_ops_t * st_op, stonith_rsc_t * srsc, const char * asker){ int * child_id; child_id = g_new(int, 1); if ((*child_id = stonith_operate_locally(st_op, srsc)) <= 0) { stonithd_log(LOG_ERR, "require_local_stonithop: " "stonith_operate_locally failed."); ZAPGDOBJ(child_id); return ST_FAIL; } else { common_op_t * op; int * tmp_callid; op = g_new(common_op_t, 1); op->scenario = STONITH_REQ; op->result_receiver = g_strdup(asker); op->data = NULL; op->op_union.st_op = st_op; g_hash_table_insert(executing_queue, child_id, op); tmp_callid = g_new(int, 1); *tmp_callid = *child_id; g_timeout_add_full(G_PRIORITY_HIGH_IDLE, st_op->timeout, stonithop_timeout, tmp_callid, NULL); stonithd_log(LOG_DEBUG, "require_local_stonithop: inserted " "optype=%d, child_id=%d", st_op->optype, *child_id); return ST_OK; }}static voidhandle_msg_trstit(const struct ha_msg* msg, void* private_data){ const char * from = NULL; int call_id; int op_result; int * orig_key = NULL; common_op_t * op = NULL; stonithd_log(LOG_DEBUG, "handle_msg_trstit: got T_RSTIT msg."); if ( (from = cl_get_string(msg, F_ORIG)) == NULL) { stonithd_log(LOG_ERR, "handle_msg_trstit: no F_ORIG field."); return; } /* Don't handle the message sent by myself */ if ( TEST == FALSE && strncmp(from, local_nodename, strlen(local_nodename)) == 0) { stonithd_log(LOG_DEBUG, "received a T_RSTIT msg from myself."); return; } if ( HA_OK != ha_msg_value_int(msg, F_STONITHD_CALLID, &call_id)) { stonithd_log(LOG_ERR, "handle_msg_trstit: no F_STONITHD_CALLID " "field."); return; } if ( HA_OK != ha_msg_value_int(msg, F_STONITHD_FRC, &op_result)) { stonithd_log(LOG_ERR, "handle_msg_trstit: no F_STONITHD_FRC " "field."); return; } my_hash_table_find(executing_queue, (gpointer *)&orig_key, (gpointer *)&op, &call_id); if ( op != NULL && (op->scenario == STONITH_INIT || op->scenario == STONITH_REQ)) { op->op_union.st_op->op_result = op_result; send_stonithop_final_result(op); stonithd_log(LOG_DEBUG, "handle_msg_trstit: clean the " "executing queue."); g_hash_table_remove(executing_queue, orig_key); } else { stonithd_log(LOG_DEBUG, "handle_msg_trstit: the stonith " "operation (call_id==%d) has finished before " "receiving this message", call_id); } stonithd_log(LOG_DEBUG, "handle_msg_trstit: end"); }static int init_client_API_handler(void){ GHashTable* chanattrs; IPC_WaitConnection* apichan = NULL; char path[] = IPC_PATH_ATTR; char sock[] = STONITHD_SOCK; GWCSource* api_source; stonithd_log(LOG_DEBUG, "init_client_API_handler: begin"); chanattrs = g_hash_table_new(g_str_hash, g_str_equal); g_hash_table_insert(chanattrs, path, sock); apichan = ipc_wait_conn_constructor(IPC_DOMAIN_SOCKET, chanattrs); if (apichan == NULL) { stonithd_log(LOG_ERR, "Cannot open stonithd's api socket: %s", sock); return LSB_EXIT_EPERM; } /* Need to destroy the chanattrs? */ /* When to destroy the api_source */ api_source = G_main_add_IPC_WaitConnection(G_PRIORITY_HIGH, apichan, NULL, FALSE, accept_client_dispatch, NULL, NULL); if (api_source == NULL) { cl_log(LOG_DEBUG, "Cannot create API listening source of " "server side from IPC"); return LSB_EXIT_GENERIC; } return 0;}static gbooleanaccept_client_dispatch(IPC_Channel * ch, gpointer user){ if (ch == NULL) { stonithd_log(LOG_ERR, "IPC accepting a connection failed."); return FALSE; } stonithd_log(LOG_DEBUG, "IPC accepted a connection."); G_main_add_IPC_Channel(G_PRIORITY_HIGH, ch, FALSE, stonithd_client_dispatch, (gpointer)ch, stonithd_IPC_destroy_notify); return TRUE;}static gbooleanstonithd_client_dispatch(IPC_Channel * ch, gpointer user_data){ struct ha_msg * msg = NULL; stonithd_log(LOG_DEBUG, "stonithd_client_dispatch: begin"); if (ch == NULL) { stonithd_log(LOG_ERR, "stonithd_client_dispatch: ch==NULL."); return TRUE; } while ( ch->ops->is_message_pending(ch)) { if (ch->ch_status == IPC_DISCONNECT) { stonithd_log(LOG_INFO, "IPC disconneted with a client.");#if 0 /* For verify the API use */ if ((msg = msgfromIPC_noauth(ch)) == NULL ) { /* Must be here */ stonithd_log(LOG_ERR, "2. Failed when receiving IPC messages."); return FALSE; }#endif stonithd_log(LOG_DEBUG, "stonithd_client_dispatch: " "delete a client due to IPC_DISCONNECT."); delete_client_by_chan(&client_list, ch); /* ??? */ return FALSE; } /* Authority issue ? */ if ((msg = msgfromIPC_noauth(ch)) == NULL ) { stonithd_log(LOG_ERR, "Failed when receiving IPC messages."); return FALSE; } else { stonithd_process_client_msg(msg, (gpointer)ch); } } return TRUE;}static voidstonithd_IPC_destroy_notify(gpointer data){ IPC_Channel * ch = (IPC_Channel *) data; /* deal with client disconnection event */ stonithd_log(LOG_DEBUG, "An IPC is destroyed."); if (ch == NULL) { stonithd_log(LOG_DEBUG, "IPC_destroy_notify: ch==NULL"); return; } if ( ST_OK == delete_client_by_chan(&client_list, ch) ) { stonithd_log(LOG_INFO, "Delete a client from client_list " "in stonithd_IPC_destroy_notify."); }}static gbooleanstonithd_process_client_msg(struct ha_msg * msg, gpointer data){ const char * msg_type = NULL; const char * api_type = NULL; IPC_Channel * ch = (IPC_Channel *) data; int i, rc; if ( ((msg_type = cl_get_string(msg, F_STONITHD_TYPE)) != NULL) && (strncmp(msg_type, ST_APIREQ, strlen(ST_APIREQ)) == 0) ) { stonithd_log(LOG_DEBUG, "received an API request msg."); } else { stonithd_log(LOG_ERR, "received a msg of none-API request."); ZAPMSG(msg); return TRUE; } if ( (api_type = cl_get_string(msg, F_STONITHD_APIREQ)) == NULL) { stonithd_log(LOG_ERR, "got an incorrect api request msg."); ZAPMSG(msg); return TRUE; } stonithd_log(LOG_DEBUG, "begin to dealing with a api msg %s from " "a client.", api_type); for (i=0; i<DIMOF(api_msg_to_handlers); i++) { if ( strncmp(api_type, api_msg_to_handlers[i].msg_type, MAXLEN_SMTYPE) == 0 ) { /*call the handler of the message*/ rc = api_msg_to_handlers[i].handler(msg, ch); if (rc != ST_OK) { stonithd_log(LOG_ERR, "handling msg %s failed." , api_type); } break; } } if (i == DIMOF(api_msg_to_handlers)) { stonithd_log(LOG_ERR, "received an unknown api msg," "and just abandon it."); } ZAPMSG(msg); stonithd_log(LOG_DEBUG, "stonithd_process_client_msg: end."); return TRUE;}static inton_stonithd_signon(const struct ha_msg * request, gpointer data){ stonithd_client_t * client = NULL; struct ha_msg * reply; const char * api_reply = ST_APIOK; const char * tmpstr = NULL; int tmpint; IPC_Channel * ch = (IPC_Channel *) data; stonithd_log(LOG_DEBUG, "on_stonithd_signon: begin."); /* parameter check, maybe redundant */ if ( ch == NULL || request == NULL ) { stonithd_log(LOG_ERR, "parameter error, signon failed."); return ST_FAIL; } if (HA_OK != ha_msg_value_int(request, F_STONITHD_CPID, &tmpint)) { stonithd_log(LOG_ERR, "signon msg contains no or incorrect " "PID field."); api_reply = ST_BADREQ; goto send_back_reply; } /* Deal with the redundant signon by error */ /* Is the IPC channel value not repeatable for our conditon? Likely */ if ( (client = get_exist_client_by_chan(client_list, ch)) != NULL ) { if (client->pid == tmpint) { stonithd_log(LOG_NOTICE, "The client pid=%d re-signon " "unnecessarily.", client->pid); } else { stonithd_log(LOG_INFO, "The client's channel isnot " "correspond to the former pid(%d). It " "seems a child is using its parent's " "IPC channel.", client->pid); } goto send_back_reply; } /* initialize client data here */ client = g_new(stonithd_client_t, 1); client->pid = tmpint; client->ch = ch; client->removereason = NULL; if (HA_OK == ha_msg_value_int(request, F_STONITHD_CEUID, &tmpint)) { client->uid = tmpint; } else { stonithd_log(LOG_ERR, "signon msg contains no or incorrect " "UID field."); api_reply = ST_BADREQ; free_client(client); client = NULL; goto send_back_reply; } if (HA_OK == ha_msg_value_int(request, F_STONITHD_CEGID, &tmpint)) { client->gid = tmpint; } else { stonithd_log(LOG_ERR, "signon msg contains no or incorrect " "GID field."); api_reply = ST_BADREQ; free_client(client); client = NULL; goto send_back_reply; } if ((tmpstr = cl_get_string(request, F_STONITHD_CNAME)) != NULL) { client->name = g_strdup(tmpstr); stonithd_log(LOG_DEBUG, "client->name=%s.", client->name); } else { stonithd_log(LOG_ERR, "signon msg contains no name field."); api_reply = ST_BADREQ; free_client(client); client = NULL; goto send_back_reply; } /* lack the authority check from uid&gid */ /* add the client to client list */ if ( strncmp(api_reply, ST_APIOK, strlen(ST_APIOK)) == 0 ) { client_list = g_list_append(client_list, client); stonithd_log(LOG_DEBUG,"client %s (pid=%d) succeeded to " "signon to stonithd.", client->name, client->pid); } else { stonithd_log(LOG_ERR, "signon failed."); free_client(client); client = NULL; } send_back_reply: reply = ha_msg_new(1); if ( (ha_msg_add(reply, F_STONITHD_TYPE, ST_APIRPL) != HA_OK ) ||(ha_msg_add(reply, F_STONITHD_APIRPL, ST_RSIGNON) != HA_OK ) ||(ha_msg_add(reply, F_STONITHD_APIRET, api_reply) != HA_OK ) ) { ZAPMSG(reply); stonithd_log(LOG_ERR, "on_stonithd_signon: 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 signon reply message to IPC"); return ST_FAIL; } ZAPMSG(reply); return ST_OK;}static inton_stonithd_signoff(const struct ha_msg * request, gpointer data){ struct ha_msg * reply; const char * api_reply = ST_APIOK; stonithd_client_t * client = NULL; IPC_Channel * ch = (IPC_Channel *) data; int tmpint; stonithd_log(LOG_DEBUG, "on_stonithd_signoff: begin."); /* parameter check, maybe redundant */ if ( ch == NULL || request == NULL ) { stonithd_log(LOG_ERR, "parameter error, signoff failed."); return ST_FAIL; } if ( HA_OK != ha_msg_value_int(request, F_STONITHD_CPID, &tmpint) ) { stonithd_log(LOG_ERR, "signoff msg contains no or incorrect " "PID field."); api_reply = ST_BADREQ; goto send_back_reply; } if ( (client = get_exist_client_by_chan(client_list, ch)) != NULL ) { if (client->pid == tmpint) { stonithd_log(LOG_INFO, "have the client %s (pid=%d) " "sign off.", client->name, client->pid); delete_client_by_chan(&client_list, ch); client = NULL; } else { stonithd_log(LOG_INFO, "The client's channel isnot " "correspond to the former pid(%d). It " "seems a child is using its parent's " "IPC channel.", client->pid); } } else { stonithd_log(LOG_NOTICE, "The client pid=%d seems already " "signed off ", tmpint); } if ( strncmp(api_reply, ST_APIOK, strlen(ST_APIOK)) == 0 ) { stonithd_log(LOG_INFO,"client pid=%d has sign off stonithd " "succeedly.", tmpint); } else { stonithd_log(LOG_INFO,"client pid=%d failed to sign off " "stonithd ", tmpint); }send_back_reply: reply = ha_msg_new(3); if ( (ha_msg_add(reply, F_STONITHD_TYPE, ST_APIRPL) != HA_OK )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -