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

📄 ccm.c

📁 linux集群服务器软件代码包
💻 C
📖 第 1 页 / 共 5 页
字号:
ccm_send_join(ll_cluster_t *hb, ccm_info_t *info){	struct ha_msg *m;	char majortrans[15]; /* 10 is the maximum number of digits in 				UINT_MAX , adding a buffer of 5 */	char minortrans[15]; /*		ditto 	*/	char joinedtrans[15]; /*		ditto 	*/	int  joinedtrans_val;	char *cookie;	int  rc;	if ((m=ha_msg_new(0)) == NULL) {		cl_log(LOG_ERR, "Cannot send CCM version msg");		return(HA_FAIL);	}		snprintf(majortrans, sizeof(majortrans), "%d", 				CCM_GET_MAJORTRANS(info));	snprintf(minortrans, sizeof(minortrans), "%d", 				CCM_GET_MINORTRANS(info));	/* uptime is based on the transition during which a given node	 * officially joined the cluster 	 */	cookie = CCM_GET_COOKIE(info);	assert(cookie && *cookie);	joinedtrans_val = CCM_GET_JOINED_TRANSITION(info);	joinedtrans_val = (joinedtrans_val == -1)? 0: joinedtrans_val;	snprintf(joinedtrans, sizeof(joinedtrans_val), "%d", joinedtrans_val);	if ((ha_msg_add(m, F_TYPE, ccm_type2string(CCM_TYPE_JOIN)) == HA_FAIL)		||(ha_msg_add(m, CCM_COOKIE, cookie) == HA_FAIL)		||(ha_msg_add(m, CCM_MAJORTRANS, majortrans) == HA_FAIL)		||(ha_msg_add(m, CCM_MINORTRANS, minortrans) == HA_FAIL)		||(ha_msg_add(m, CCM_UPTIME, joinedtrans) == HA_FAIL)) {			cl_log(LOG_ERR, "ccm_send_join: Cannot create JOIN "						    "message");		rc = HA_FAIL;	} else {		/*delay by microseconds to avoid message collision */		ccm_delay_random_interval();		rc = hb->llc_ops->sendclustermsg(hb, m);	}	ha_msg_del(m);	return(rc);}/* *//* send out the connectivity information to the cluster leader. *//* */static intccm_send_memlist_res(ll_cluster_t *hb, 			ccm_info_t *info,			const char *nodename, 			char *memlist){	struct ha_msg *m;	char majortrans[15]; /* 10 is the maximum number of digits in 				UINT_MAX , adding a buffer of 5 */	char minortrans[15]; /*		ditto 	*/	char maxtrans[15]; /*		ditto 	*/	char *cookie;	int  rc;	unsigned char *bitmap;	gboolean del_flag=FALSE;		if ((m=ha_msg_new(0)) == NULL) {		cl_log(LOG_ERR, "ccm_send_memlist_res: Cannot allocate "				"memory ");		return(HA_FAIL);	}		snprintf(majortrans, sizeof(majortrans), "%d", 					CCM_GET_MAJORTRANS(info));	snprintf(minortrans, sizeof(minortrans), "%d", 					CCM_GET_MINORTRANS(info));	snprintf(maxtrans, sizeof(maxtrans), "%d", 					CCM_GET_MAXTRANS(info));	cookie = CCM_GET_COOKIE(info);	assert(cookie && *cookie);	if (!memlist) {		int numBytes = bitmap_create(&bitmap, MAXNODE);		(void) ccm_bitmap2str(bitmap, numBytes, &memlist);		bitmap_delete(bitmap);		del_flag = TRUE;	} 	if ((ha_msg_add(m, F_TYPE, ccm_type2string(CCM_TYPE_RES_MEMLIST)) 							== HA_FAIL)		||(ha_msg_add(m, CCM_COOKIE, cookie) == HA_FAIL)		||(ha_msg_add(m, CCM_MAJORTRANS, majortrans) == HA_FAIL)		||(ha_msg_add(m, CCM_MINORTRANS, minortrans) == HA_FAIL)		||(ha_msg_add(m, CCM_MAXTRANS, maxtrans) == HA_FAIL)		||(ha_msg_add(m, CCM_MEMLIST, memlist) == HA_FAIL)) {		cl_log(LOG_ERR, "ccm_send_memlist_res: Cannot create "						"RES_MEMLIST message");		rc = HA_FAIL;	} else {		/*delay by microseconds to avoid message collision */		ccm_delay_random_interval();		rc = hb->llc_ops->sendnodemsg(hb, m, nodename);	}	if(del_flag) {		g_free(memlist);	}		ha_msg_del(m);	return(rc);}/* *//* send out a message to all the members of the cluster, asking for *//* their connectivity information. *//* *//* NOTE: called by the cluster leader only. *//* */static intccm_send_memlist_request(ll_cluster_t *hb, ccm_info_t *info){	struct ha_msg *m;	char majortrans[15]; /* 10 is the maximum number of digits in 					UINT_MAX , adding a buffer of 5 */	char minortrans[15]; /*		ditto 	*/	char *cookie;	int  rc;	if ((m=ha_msg_new(0)) == NULL) {		cl_log(LOG_ERR, "ccm_send_memlist_request: Cannot allocate "				"memory");		return(HA_FAIL);	}		snprintf(majortrans, sizeof(majortrans), "%d", 					CCM_GET_MAJORTRANS(info));	snprintf(minortrans, sizeof(minortrans), "%d", 					CCM_GET_MINORTRANS(info));	cookie = CCM_GET_COOKIE(info);	assert(cookie && *cookie);	if ((ha_msg_add(m, F_TYPE, ccm_type2string(CCM_TYPE_REQ_MEMLIST)) 						== HA_FAIL)		||(ha_msg_add(m, CCM_COOKIE, cookie) == HA_FAIL)		||(ha_msg_add(m, CCM_MAJORTRANS, majortrans) == HA_FAIL)		||(ha_msg_add(m, CCM_MINORTRANS, minortrans) == HA_FAIL)) {			cl_log(LOG_ERR, "ccm_send_memlist_request: Cannot "				"create REQ_MEMLIST message");		rc = HA_FAIL;	} else {		rc = hb->llc_ops->sendclustermsg(hb, m);	}	ha_msg_del(m);	return(rc);}/* *//* Browse through the list of all the connectivity request messages *//* from cluster leaders. Send out the connectivity information only *//* to the node which we believe is the cluster leader. To everybody  *//* else send out a null message. *//* */static intccm_send_cl_reply(ll_cluster_t *hb, ccm_info_t *info){	int ret=FALSE, bitmap_strlen;	char *memlist, *cl, *cl_tmp;	void *cltrack;	uint  trans;	int repeat;	/*        * Get the name of the cluster leader	*/	cl = update_get_cl_name(CCM_GET_UPDATETABLE(info), 				CCM_GET_LLM(info));	/* search through the update list and find if any Cluster	 * leader has sent a memlist request. For each, check if	 * that node is the one which we believe is the leader.	 * if it is the leader, send it our membership list.	 * if not send it an NULL membership reply.	 */	cltrack = update_initlink(CCM_GET_UPDATETABLE(info));	while((cl_tmp = update_next_link(CCM_GET_UPDATETABLE(info), 				CCM_GET_LLM(info), cltrack, &trans)) != NULL) {		if(strncmp(cl, cl_tmp, 			LLM_GET_NODEIDSIZE(CCM_GET_LLM(info))) == 0) {			if(ccm_already_joined(info) && 				CCM_GET_MAJORTRANS(info) != trans){				cl_log(LOG_INFO, "evicted");				ccm_reset(info);				return FALSE;			}			ret = TRUE;			bitmap_strlen = update_strcreate(				CCM_GET_UPDATETABLE(info), 				&memlist, CCM_GET_LLM(info));			/* send Cluster Leader our memlist only if we are 			 * operating in the same transition as that of 			 * the leader, provided we have been a cluster member 			 * in the past 			 */			repeat = 0;			while (ccm_send_memlist_res(hb, info, cl, memlist)						!=HA_OK) {				if(repeat < REPEAT_TIMES){					cl_log(LOG_ERR,						"ccm_state_version_request: "						"failure to send join");					cl_shortsleep();					repeat++;				}else{					break;				}			}			update_strdelete(memlist);		} else {			/* I dont trust this Cluster Leader.			Send NULL memlist message */			repeat = 0;			while (ccm_send_memlist_res(hb, info, cl_tmp, NULL)					!= HA_OK) {				if(repeat < REPEAT_TIMES){					cl_log(LOG_ERR, 					"ccm_state_version_request: failure "						"to send join");					cl_shortsleep();					repeat++;				}else{					break;				}			}		}	}	update_freelink(CCM_GET_UPDATETABLE(info), cltrack);	update_free_memlist_request(CCM_GET_UPDATETABLE(info)); 	return ret;}/*///////////////////////////////////////////////////////////////////////// END OF FUNCTIONS THAT SEND OUT messages to nodes of the cluster///////////////////////////////////////////////////////////////////////*//* *//* Fake up a leave message. *//* This is generally done when heartbeat informs ccm of the crash of *//* a cluster member. *//* */static struct ha_msg *ccm_create_leave_msg(ccm_info_t *info, int uuid){	struct ha_msg *m;	char majortrans[15]; /* 10 is the maximum number of digits in 				UINT_MAX , adding a buffer of 5 */	char minortrans[15]; /*		ditto 	*/	llm_info_t *llm;	char *nodename, *cookie;		/* find the name of the node at index */	llm = CCM_GET_LLM(info);	nodename = llm_get_nodeid_from_uuid(llm, uuid);    	if ((m=ha_msg_new(0)) == NULL) {		cl_log(LOG_ERR, "ccm_send_memlist_request: "				"Cannot allocate memory");		return(HA_FAIL);	}		snprintf(majortrans, sizeof(majortrans), "%d", 				CCM_GET_MAJORTRANS(info));	snprintf(minortrans, sizeof(minortrans), "%d", 				CCM_GET_MINORTRANS(info));	cookie = CCM_GET_COOKIE(info);	assert(cookie && *cookie);	if ((ha_msg_add(m, F_TYPE, ccm_type2string(CCM_TYPE_LEAVE)) 							== HA_FAIL)		||(ha_msg_add(m, F_ORIG, nodename) == HA_FAIL) 		||(ha_msg_add(m, CCM_MAJORTRANS, majortrans) == HA_FAIL)		||(ha_msg_add(m, CCM_COOKIE, cookie) == HA_FAIL)		||(ha_msg_add(m, CCM_MINORTRANS, minortrans) == HA_FAIL)) {		cl_log(LOG_ERR, "ccm_create_leave_msg: Cannot create REQ_LEAVE "						    "message");		return NULL;	} 	return(m);}/* *//* Watch out for new messages. As and when they arrive, return the *//* message. *//* */static struct ha_msg *ccm_readmsg(ccm_info_t *info, ll_cluster_t *hb){	int 	uuid;	assert(hb);	/* check if there are any leave events to be delivered */	if ((uuid=leave_get_next()) != -1) {		/* create a leave message and return it */		return ccm_create_leave_msg(info, uuid);	}		return hb->llc_ops->readmsg(hb, 0);}/* *//* Move the state of this ccm node, from joining state directly to *//* the joined state. *//* *//* NOTE: this is generally called when a joining nodes determines *//* that it is the only node in the cluster, and everybody else are *//* dead. *//* */static voidccm_joining_to_joined(ll_cluster_t *hb, ccm_info_t *info){	unsigned char *bitmap;	char *cookie = NULL;	/* create a bitmap with the membership information */	(void) bitmap_create(&bitmap, MAXNODE);	bitmap_mark(LLM_GET_MYUUID(CCM_GET_LLM(info)), bitmap, MAXNODE);	/* 	 * I am the only around! Lets discard any cookie that we	 * got from others, and create a new cookie.	 * This bug was noticed: when testing with partitioned	 * clusters.	 */	cookie = ccm_generate_random_cookie();	/* fill my new memlist and update the new cookie if any */	ccm_fill_memlist_from_bitmap(info, bitmap);	bitmap_delete(bitmap);	/* increment the major transition number and reset the	 * minor transition number	 */	CCM_INCREMENT_MAJORTRANS(info); 	CCM_RESET_MINORTRANS(info);	/* if cookie has changed update it.	 */	if (cookie) {		cl_log(LOG_INFO, "ccm_joining_to_joined: "				"cookie changed ");		CCM_SET_COOKIE(info, cookie); 		ccm_free_random_cookie(cookie);	}	/* check if any joiner is waiting for a response from us. 	 * If so respond 	 */	ccm_send_join_reply(hb, info);	g_slist_free(CCM_GET_JOINERHEAD(info));	CCM_SET_JOINERHEAD(info, NULL);		CCM_SET_CL(info, ccm_get_my_membership_index(info));	update_reset(CCM_GET_UPDATETABLE(info));	CCM_SET_STATE(info, CCM_STATE_JOINED);	report_mbrs(info);	if(!ccm_already_joined(info)) {		CCM_SET_JOINED_TRANSITION(info, 1);	}	return;}/* *//* Move the state of this ccm node, from init state directly to *//* the joined state. *//* *//* NOTE: this is generally called when a node when it  determines *//* that it is all alone in the cluster. *//* */static voidccm_init_to_joined(ccm_info_t *info){	int numBytes;	unsigned char *bitlist;	char *cookie;	numBytes = bitmap_create(&bitlist, MAXNODE);	bitmap_mark(LLM_GET_MYUUID(CCM_GET_LLM(info)), bitlist,MAXNODE);	ccm_fill_memlist_from_bitmap(info, bitlist);	bitmap_delete(bitlist);	CCM_SET_MAJORTRANS(info, 1);	CCM_SET_MINORTRANS(info, 0);	cookie = ccm_generate_random_cookie();	CCM_SET_COOKIE(info, cookie);	ccm_free_random_cookie(cookie);	CCM_SET_CL(info, ccm_get_my_membership_index(info));	CCM_SET_STATE(info, CCM_STATE_JOINED);	CCM_SET_JOINED_TRANSITION(info, 1);	report_mbrs(info);	return;}/* *//* The state machine that processes message when it is *//*	the CCM_STATE_VERSION_REQUEST state *//* */static voidccm_state_version_request(enum ccm_type ccm_msg_type,			struct ha_msg *reply,			ll_cluster_t *hb, 			ccm_info_t *info){	const char *orig, *proto, *cookie, *trans, *clsize;	uint trans_val;	int  proto_val, clsize_val;	int try;	int repeat;		/* who sent this message */	if ((orig = ha_msg_value(reply, F_ORIG)) == NULL) {		cl_log(LOG_WARNING, "ccm_state_version_request: "			"received message from unknown");		return;	}	if(!llm_is_valid_node(CCM_GET_LLM(info), orig)) { 		cl_log(LOG_WARNING, "ccm_state_version_request: "			"received message from unknown host %s", orig);		return;	}	switch (ccm_msg_type)  {	case CCM_TYPE_PROTOVERSION_RESP:		/* get the protocol version */		if ((proto = ha_msg_value(reply, CCM_PROTOCOL)) == NULL) {			cl_log(LOG_WARNING, "ccm_state_version_request: "					"no protocol information");			return;		}		proto_val = atoi(proto); /*TOBEDONE*/		if (proto_val >= CCM_VER_LAST) {			cl_log(LOG_WARNING, "ccm_state_version_request: "					"unknown protocol value");			ccm_reset(info);			return;		}		/* if this reply has come from a node which is a member		 * of a larger cluster, we will try to join that cluster		 * else we will wait for some time, by dropping this		 * response.		 */		if(resp_can_i_drop()) {			if ((clsize = ha_msg_value(reply, CCM_CLSIZE)) == NULL){				cl_log(LOG_WARNING, "ccm_state_version_request: "						" no cookie information");				return;			}			clsize_val = atoi(clsize);			if((clsize_val+1) <=			   ((llm_get_active_nodecount(CCM_GET_LLM(info))+1)/2)) {				/* drop the response. We will wait for 			  	 * a response from a bigger group 				 */				resp_dropped();				cl_shortsleep(); /* sleep for a while */				/* send a fresh version request message */				version_reset(CCM_GET_VERSION(info));				CCM_SET_STATE(info, CCM_STATE_NONE);				/* free all the joiners that we accumulated */				g_slist_free(CCM_GET_JOINERHEAD(info));				CCM_SET_JOINERHEAD(info, NULL);				break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -