⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stonithd.c

📁 linux集群服务器软件代码包
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* 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 + -