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

📄 ccm.c

📁 在LINUX下实现HA的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
							== 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_COOKIE, cookie) == HA_FAIL)		||(ha_msg_add(m, CCM_MEMLIST, finallist) == HA_FAIL)		||(!newcookie? FALSE: (ha_msg_add(m, CCM_NEWCOOKIE, newcookie)							==HA_FAIL))) {		cl_log(LOG_ERR, "ccm_send_final_memlist: Cannot create "					"FINAL_MEMLIST message");		rc = HA_FAIL;	} else {		rc = hb->llc_ops->sendclustermsg(hb, m);	}	ha_msg_del(m);	return(rc);}/* *//* send out a message to the cluster asking for the context *//* NOTE: this context is used to intiate a new instance of  *//* 	a CCM protocol. *//* */static intccm_send_protoversion(ll_cluster_t *hb, ccm_info_t *info){	struct ha_msg *m;	char version[3]; /* in the life time of ccm, do not expect protocol					    versions running to 100! */	int  rc;		if ((m=ha_msg_new(0)) == NULL) {		cl_log(LOG_ERR, "Cannot send CCM version msg");		return(HA_FAIL);	}		snprintf(version, sizeof(version), "%d",  CCM_GET_HIPROTO(info));	if ((ha_msg_add(m, F_TYPE, ccm_type2string(CCM_TYPE_PROTOVERSION)) 							== HA_FAIL)) {		cl_log(LOG_ERR, "ccm_send_join: Cannot create PROTOVERSION "						    "message");		rc = HA_FAIL;	} else {				rc = hb->llc_ops->sendclustermsg(hb, m);	}	ha_msg_del(m);	return(rc);}/* *//* send out a abort message to whoever has initiated a new instance *//* of ccm protocol. *//* */static intccm_send_abort(ll_cluster_t *hb, ccm_info_t *info, 		const char *dest, 		const int major, 		const int minor){	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, "Cannot send CCM version msg");		return(HA_FAIL);	}		snprintf(majortrans, sizeof(majortrans), "%d", major);	snprintf(minortrans, sizeof(minortrans), "%d", minor);	cookie = CCM_GET_COOKIE(info);	if ((ha_msg_add(m, F_TYPE, ccm_type2string(CCM_TYPE_ABORT)) == 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_abort: Cannot create ABORT "						    "message");		rc = HA_FAIL;	} else {		rc = hb->llc_ops->sendnodemsg(hb, m, dest);	}	ha_msg_del(m);	return(rc);}/* *//* send out a leave message to indicate to everybody that it is leaving *//* the cluster. *//* */static intccm_send_leave(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, "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));	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, 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_leave: Cannot create leave "						    "message");		rc = HA_FAIL;	} else {		rc = hb->llc_ops->sendclustermsg(hb, m);	}	ha_msg_del(m);	return(rc);}/* *//* send out a join message. THis message will initiate a new instance of *//* the ccm protocol. *//* */static intccm_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 */	while((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.

⌨️ 快捷键说明

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