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

📄 ccm.c

📁 在LINUX下实现HA的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
static intccm_memcomp_get_maxmembership(ccm_info_t *info, unsigned char **bitmap){	GSList *head;	uint32_t *ptr;	int 	uuid;	memcomp_t *mem_comp = CCM_GET_MEMCOMP(info);	(void)graph_get_maxclique(MEMCOMP_GET_GRAPH(mem_comp), 			bitmap);	head = MEMCOMP_GET_MAXT(mem_comp);	while (head) {		ptr = (uint32_t *)g_slist_nth_data(head, 0);		uuid = ptr[1];		if(bitmap_test(uuid, *bitmap, MAXNODE)) 			return ptr[0];		head = g_slist_next(head);	}	return 0;}/* *//* END OF the membership tracking functions. *//* */static int ccm_am_i_member(ccm_info_t *info, const char *memlist){	unsigned char *bitmap;	int numBytes = ccm_str2bitmap(memlist, &bitmap);	/* what is my node Uuid */	llm_info_t *llm = CCM_GET_LLM(info);	int my_uuid = LLM_GET_MYUUID(llm);	if (bitmap_test(my_uuid, bitmap, numBytes)){		bitmap_delete(bitmap);		return TRUE;	}	bitmap_delete(bitmap);	return FALSE;}/* *//* BEGIN  OF  FUNCTIONS  that  keep track of stablized membership list *//*  *//* These  function  keep track of consensus membership once a instance *//* of the  ccm algorithm terminates and decided on the final consensus  *//* members of the cluster. *//* */static int ccm_memlist_changed(ccm_info_t *info, 		  char *bitmap /* the bitmap string containing bits */){	int nodeCount, i;	llm_info_t *llm;	uint indx, uuid;					/* go through the membership list */	nodeCount = CCM_GET_MEMCOUNT(info);	llm = CCM_GET_LLM(info);	for ( i = 0 ; i < nodeCount; i++ ) {		indx = CCM_GET_MEMINDEX(info, i);		assert(indx >=0 && indx < LLM_GET_NODECOUNT(llm));		uuid = LLM_GET_UUID(llm,indx);		assert(uuid>=0 && uuid < MAXNODE);		if (!bitmap_test(uuid, (unsigned char*)bitmap, MAXNODE))			return TRUE;	}	return FALSE;} static int ccm_fill_memlist(ccm_info_t *info, 	const unsigned char *bitmap){	llm_info_t *llm;	uint i, uuid;	llm = CCM_GET_LLM(info);	CCM_RESET_MEMBERSHIP(info);	for ( i = 0 ; i < LLM_GET_NODECOUNT(llm); i++ ) {		uuid = LLM_GET_UUID(llm,i);		if(bitmap_test(uuid, bitmap, MAXNODE)){			/*update the membership list with this member*/			CCM_ADD_MEMBERSHIP(info, i);		}	}	return FALSE;}static int ccm_fill_memlist_from_str(ccm_info_t *info, 	const unsigned char *memlist){	unsigned char *bitmap;	int ret;	(void)ccm_str2bitmap((const char*)memlist, &bitmap);	ret = ccm_fill_memlist(info, bitmap);	bitmap_delete(bitmap);	return ret;}									static int ccm_fill_memlist_from_bitmap(ccm_info_t *info, 	const unsigned char *bitmap){	return ccm_fill_memlist(info, bitmap);}static intccm_get_membership_index(ccm_info_t *info, const char *node){	int i,indx;	llm_info_t *llm = CCM_GET_LLM(info);	for ( i = 0 ; i < CCM_GET_MEMCOUNT(info) ; i++ ) {		indx =  CCM_GET_MEMINDEX(info, i);		if(strncmp(LLM_GET_NODEID(llm, indx), node, 				LLM_GET_NODEIDSIZE(llm)) == 0)			return i;	}	return -1;}static intccm_get_my_membership_index(ccm_info_t *info){	int i;	llm_info_t *llm = CCM_GET_LLM(info);	for ( i = 0 ; i < CCM_GET_MEMCOUNT(info) ; i++ ) {		if (CCM_GET_MEMINDEX(info, i) == LLM_GET_MYNODE(llm))			return i;	}			assert(0); /* should never reach here */	return -1;}static intccm_am_i_leader(ccm_info_t *info){	if (ccm_get_my_membership_index(info) == CCM_GET_CL(info))		return TRUE;	return FALSE;}static intccm_already_joined(ccm_info_t *info){	if (CCM_GET_JOINED_TRANSITION(info)) {		return TRUE;	}	return FALSE;}/* *//* END  OF  FUNCTIONS  that  keep track of stablized membership list *//* *//*  *//* BEGIN OF FUNCTIONS THAT KEEP TRACK of cluster nodes that have shown *//* interest in joining the cluster. *//* *//* *//* NOTE: when a new node wants to join the cluster, it multicasts a  *//* message asking for the necessary information to send out a  join *//* message. (it needs the current major transistion number, the context *//* string i.e cookie, the protocol number that everybody is operating *//* in). *//* *//* The functions below track these messages sent out by new potential *//* members showing interest in acquiring the initial context. *//* */static void ccm_add_new_joiner(ccm_info_t *info, const char *orig){	/* check if there is already a cached request for the	 * joiner 	 */	int idx = llm_get_index(CCM_GET_LLM(info), orig)+1;	if(!g_slist_find(CCM_GET_JOINERHEAD(info),GINT_TO_POINTER(idx))) {		CCM_SET_JOINERHEAD(info, g_slist_append(CCM_GET_JOINERHEAD(info), 					GINT_TO_POINTER(idx)));	} 	else {		if(global_debug)			cl_log(LOG_DEBUG,"add_joiner %s already done", orig);	}	return;}static intccm_am_i_highest_joiner(ccm_info_t *info){	int   		joiner;	char *		joiner_name;	gpointer	jptr;	char *		hname = ccm_get_my_hostname(info);	GSList *	head = CCM_GET_JOINERHEAD(info);	while ( head ) {		jptr = g_slist_nth_data(head, 0);		joiner = GPOINTER_TO_INT(jptr)-1;		joiner_name = LLM_GET_NODEID(CCM_GET_LLM(info), joiner);		if (strncmp(hname, joiner_name, 			LLM_GET_NODEIDSIZE(CCM_GET_LLM(info))) < 0) {			return FALSE;		}		head = g_slist_next(head);	}	return TRUE;}static void ccm_remove_new_joiner(ccm_info_t *info, const char *orig){	int idx = llm_get_index(CCM_GET_LLM(info), orig)+1;	CCM_SET_JOINERHEAD(info, 			g_slist_remove(CCM_GET_JOINERHEAD(info), 				GINT_TO_POINTER(idx)));	return;}/* *//* END OF FUNCTIONS THAT KEEP TRACK of cluster nodes that have shown *//* interest in joining the cluster. *//* *//*///////////////////////////////////////////////////////////////////////// BEGIN OF FUNCTIONS THAT SEND OUT messages to nodes of the cluster///////////////////////////////////////////////////////////////////////*/static voidccm_delay_random_interval(void){	struct timeval tmp;	/* seed the random with a random value */	gettimeofday(&tmp, NULL);	srandom((unsigned int)tmp.tv_usec); 	usleep(random()%MAXNODE); /*sleep some random microsecond interval*/}/* *//* compute the final membership list from the acquired connectivity *//* information from other nodes. And send out the consolidated *//* members of the cluster information to the all the members of  *//* that have participated in the CCM protocol. *//* *//* NOTE: Called by the cluster leader only. *//* */static voidccm_compute_and_send_final_memlist(ll_cluster_t *hb, ccm_info_t *info){	unsigned char *bitmap;	uint maxtrans;	char *string;	char *cookie = NULL;	int numBytes;	int strsize;	int repeat;	/* get the maxmimum membership list */	maxtrans = ccm_memcomp_get_maxmembership(info, &bitmap);	/* create a string with the membership information */	numBytes = bitmap_size(MAXNODE);	strsize  = ccm_bitmap2str(bitmap, numBytes, &string);	/* check if the membership has changed from that before. If so we	 * have to generate a new cookie.	 */	if(ccm_memlist_changed(info, (char*)bitmap)) {		cookie = ccm_generate_random_cookie();	}	repeat = 0;	while (ccm_send_final_memlist(hb, info, cookie, string, maxtrans+1) 					!= HA_OK) {		if(repeat < REPEAT_TIMES){			cl_log(LOG_ERR,				"ccm_compute_and_send_final_memlist: failure "				"to send finalmemlist");			cl_shortsleep();			repeat++;		}else{			bitmap_delete(bitmap);			g_free(string);			return;		}	}	/* fill my new memlist and update the new cookie if any */	ccm_fill_memlist_from_bitmap(info, bitmap);	bitmap_delete(bitmap);	g_free(string);	/* increment the major transition number and reset the	 * minor transition number	 */	CCM_SET_MAJORTRANS(info, maxtrans+1); 	CCM_RESET_MINORTRANS(info);	/* if cookie has changed update it.	 */	if (cookie) {		cl_log(LOG_INFO, "ccm_compute_and_send_final_list: "				"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 and free all the joiners.	 */	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));	report_mbrs(info);/* call this before update_reset() */	update_reset(CCM_GET_UPDATETABLE(info));	ccm_memcomp_reset(info);	CCM_SET_STATE(info, CCM_STATE_JOINED);	if(!ccm_already_joined(info)) 		CCM_SET_JOINED_TRANSITION(info, CCM_GET_MAJORTRANS(info));	return;}/* *//* send a reply to the potential joiner, containing the neccessary *//* context needed by the joiner, to initiate a new round of a ccm  *//* protocol. *//* NOTE: This function is called by the cluster leader only. *//* */static int ccm_send_joiner_reply(ll_cluster_t *hb, ccm_info_t *info, const char *joiner){	struct ha_msg *m;	char activeproto[3];	char clsize[5];	char majortrans[15]; /* 10 is the maximum number of digits in 				UINT_MAX , adding a buffer of 5 */	char *cookie;	int rc;	/*send the membership information to all the nodes of the cluster*/	if ((m=ha_msg_new(0)) == NULL) {		cl_log(LOG_ERR, "Cannot send CCM version msg");			return(HA_FAIL);	}		snprintf(activeproto, sizeof(activeproto), "%d", 			CCM_GET_ACTIVEPROTO(info));	snprintf(majortrans, sizeof(majortrans), "%d", 				CCM_GET_MAJORTRANS(info));	snprintf(clsize, sizeof(clsize), "%d", 				CCM_GET_MEMCOUNT(info));	cookie = CCM_GET_COOKIE(info);	assert(cookie && *cookie);	if ((ha_msg_add(m, F_TYPE, ccm_type2string(CCM_TYPE_PROTOVERSION_RESP)) 					== HA_FAIL)		||(ha_msg_add(m, CCM_PROTOCOL, activeproto) == HA_FAIL) 		||(ha_msg_add(m, CCM_MAJORTRANS, majortrans) == HA_FAIL)		||(ha_msg_add(m, CCM_CLSIZE, clsize) == HA_FAIL)		||(ha_msg_add(m, CCM_COOKIE, cookie) == HA_FAIL)) {		cl_log(LOG_ERR, "ccm_send_joiner_reply: Cannot create JOIN "				"reply message");			rc = HA_FAIL;		} else {			rc = hb->llc_ops->sendnodemsg(hb, m, joiner);		}	ha_msg_del(m);	return(rc);}/*  *//* browse through the list of interested joiners and reply to each of *//* them. *//*  */static void ccm_send_join_reply(ll_cluster_t *hb, ccm_info_t *info){	int 	joiner;	gpointer	jptr;	const char *joiner_name;	GSList 	*head = CCM_GET_JOINERHEAD(info);	int repeat;		while(head) {		jptr = g_slist_nth_data(head, 0);		joiner = GPOINTER_TO_INT(jptr)-1;		joiner_name = LLM_GET_NODEID(CCM_GET_LLM(info), joiner);		/* send joiner the neccessary information */		repeat = 0;		while (ccm_send_joiner_reply(hb, info, joiner_name)!=HA_OK) {			if(repeat < REPEAT_TIMES){				cl_log(LOG_ERR, "ccm_send_join_reply: failure "					"to send join reply");				cl_shortsleep();				repeat++;			}else{				break;			}		}		head = g_slist_next(head);	}}/* *//* send a final membership list to all the members who have participated *//* in the ccm protocol. *//* NOTE: Called by the cluster leader on. *//* */static intccm_send_final_memlist(ll_cluster_t *hb, 			ccm_info_t *info, 			char *newcookie, 			char *finallist,			uint32_t max_tran){  	struct ha_msg *m;	char activeproto[3];	char majortrans[15]; /* 10 is the maximum number of digits in 				UINT_MAX , adding a buffer of 5 */	char minortrans[15]; /* 10 is the maximum number of digits in 				UINT_MAX , adding a buffer of 5 */	char maxtrans[15]; /* 10 is the maximum number of digits in 				UINT_MAX , adding a buffer of 5 */	char *cookie;	int rc;	/*send the membership information to all the nodes of the cluster*/	if ((m=ha_msg_new(0)) == NULL) {		cl_log(LOG_ERR, "Cannot send CCM version msg");		return(HA_FAIL);	}		snprintf(activeproto, sizeof(activeproto), "%d", 					CCM_GET_ACTIVEPROTO(info));	snprintf(majortrans, sizeof(majortrans), "%d", 					CCM_GET_MAJORTRANS(info));	snprintf(minortrans, sizeof(minortrans), "%d", 					CCM_GET_MINORTRANS(info));	snprintf(maxtrans, sizeof(maxtrans), "%d", max_tran);	cookie = CCM_GET_COOKIE(info);	assert(cookie && *cookie);	assert(finallist);	if ((ha_msg_add(m, F_TYPE, ccm_type2string(CCM_TYPE_FINAL_MEMLIST)) 

⌨️ 快捷键说明

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