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 + -
显示快捷键?