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

📄 ccmlib_memapi.c

📁 在LINUX下实现HA的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	return;}static voidmem_callback_done(void *cookie){	cookie_unref(cookie);	return;}/* a sophisticated quorum algorithm has to be introduced here *  currently we are just using the simplest algorithm */static gbooleanmem_quorum(mbr_private_t *private, mbr_track_t *mbr){	/*cl_log(LOG_DEBUG, "n_member=%d, cllm_get_nodecount=%d\n", */	/*	OC_EV_GET_N_MEMBER(mbr), CLLM_GET_NODECOUNT(private->llm)); */	if(OC_EV_GET_N_MEMBER(mbr) <		(CLLM_GET_NODECOUNT(private->llm)/2+1))		return FALSE;	return TRUE;}static voidupdate_bornons(mbr_private_t *private, mbr_track_t *mbr){	uint i,j;	for(i=0; i < OC_EV_GET_N_MEMBER(mbr); i++) {		g_hash_table_insert(private->bornon,			GINT_TO_POINTER(OC_EV_GET_NODEID(mbr,i)),			GINT_TO_POINTER(OC_EV_GET_BORN(mbr,i)+1));	}	j=OC_EV_GET_OUT_IDX(mbr); 	for(i=OC_EV_GET_OUT_IDX(mbr); i<j+OC_EV_GET_N_OUT(mbr); i++){		g_hash_table_insert(private->bornon,			GINT_TO_POINTER(OC_EV_GET_NODEID(mbr,i)),			GINT_TO_POINTER(0));	}}static gbooleanmembership_unchanged(mbr_private_t *private, mbr_track_t *mbr){	uint i;	mbr_track_t *oldmbr = (mbr_track_t *) 				cookie_get_data(private->cookie);	if(!oldmbr) return FALSE;	if(OC_EV_GET_N_MEMBER(mbr) != OC_EV_GET_N_MEMBER(oldmbr)){			return FALSE;	}	for(i=0; i < OC_EV_GET_N_MEMBER(mbr); i++) {		if((OC_EV_GET_NODEID(mbr,i) 				!= OC_EV_GET_NODEID(oldmbr,i)) ||		  OC_EV_GET_BORN(mbr,i) 		  		!= OC_EV_GET_BORN(oldmbr,i)) { 			return FALSE;		}	}	return TRUE;}static gboolean	 mem_handle_event(class_t *class){	struct IPC_MESSAGE *msg;	mbr_private_t *private;	struct IPC_CHANNEL *ch;	mbr_track_t *mbr_track;	int	size;	int	type;	oc_memb_event_t oc_type;	void   *cookie;	int ret;	gboolean quorum;	if(!class_valid(class)) return FALSE;	private = (mbr_private_t *)class->private;	ch 	   = private->channel;	if(init_llmborn(private)){		return FALSE;	}	while(ch->ops->is_message_pending(ch)){		/* receive the message and call the callback*/		ret=ch->ops->recv(ch,&msg);		if(ret == IPC_FAIL) {			return TRUE;		}		if(ret!=IPC_OK){			/* FIXIT. setting it to CCM_EVICTED is not			 * correct. However the draft api says nothing			 * about this case.			 * Proposal:			 * Set something like  CCM_LOST_SERVICE here			 * and return OC_EV_MS_LOST_SERVICE to the			 * client			 */			type = CCM_EVICTED;		} else {			type = ((ccm_meminfo_t *)msg->msg_body)->ev;		}		cookie= mbr_track = NULL;		size=0;		oc_type = OC_EV_MS_INVALID;		switch(type) {		case CCM_NEW_MEMBERSHIP :			size = get_new_membership(private, 				(ccm_meminfo_t *)msg->msg_body, 				msg->msg_len, 				&mbr_track);			/* if ccm daemon informs us that we have quorum			 * by default, we do not have to compute quorum 			 */			if(((ccm_meminfo_t *)(msg->msg_body))->q_overide) {				quorum = TRUE;			} else {				quorum = mem_quorum(private, mbr_track);			}			/* if no quorum, delete the bornon dates for lost 			 * nodes, add  bornon dates for the new nodes and 			 * return			 *			 * however if special behaviour is being asked			 * for report the membership even when this node			 * has no quorum.			 */			if (!private->special && !quorum){				update_bornons(private, mbr_track);				private->client_report = FALSE;				mem_free_func(mbr_track);				break;			}			private->client_report = TRUE;			/* if quorum and old membership is same as the new 			* membership set type to OC_EV_MS_RESTORED , 			* pick the old membership and deliver it. 			* Do not construct a new membership  			*/			if (membership_unchanged(private, mbr_track)){				/* we do not need the new mbr_track, 				*  the old one is the same as the new				*/				mem_free_func(mbr_track);				oc_type = OC_EV_MS_PRIMARY_RESTORED;				cookie = private->cookie;				mbr_track = (mbr_track_t *)					cookie_get_data(cookie);			} else {				oc_type = quorum?					OC_EV_MS_NEW_MEMBERSHIP:					OC_EV_MS_INVALID; 				/* NOTE: OC_EV_MS_INVALID overloaded to				 * mean that the membership has no quorum.				 * This is returned only when special behaviour				 * is asked for. In normal behaviour case 				 * (as per 0.2 version of the api),				 * OC_EV_MS_INVALID is never returned.				 * I agree this is a kludge!!				 */				if(!private->special) {				  assert(oc_type == OC_EV_MS_NEW_MEMBERSHIP);				}				update_bornons(private, mbr_track);				cookie_unref(private->cookie);				cookie = cookie_construct(mem_callback_done, 						mem_free_func, mbr_track);				private->cookie = cookie;			}			size = OC_EV_GET_SIZE(mbr_track);			break;		case CCM_EVICTED:			oc_type = OC_EV_MS_EVICTED;			private->client_report = TRUE;			/* FALL THROUGH */		case CCM_INFLUX:			if(type==CCM_INFLUX)				oc_type = OC_EV_MS_NOT_PRIMARY;			cookie = private->cookie;			if(cookie) {				mbr_track = (mbr_track_t *)					cookie_get_data(cookie);				size=mbr_track? OC_EV_GET_SIZE(mbr_track): 0;			} else {				/* if no cookie exists, create one.				 * This can happen if no membership 				 * has been delivered.				 */				mbr_track=NULL;				size=0;				cookie = private->cookie = 					cookie_construct(mem_callback_done,						NULL,NULL);			}			break;		}		if(private->callback && private->client_report && cookie){			cookie_ref(cookie);			private->callback(oc_type,				(uint *)cookie,				size,				mbr_track?&(mbr_track->m_mem):NULL);		}		if(ret==IPC_OK) {			msg->msg_done(msg);		} else {			return FALSE;		}		if(type == CCM_EVICTED) {			/* clean up the dynamic information in the 			 * private structure 			 */			reset_llm(private);			reset_bornon(private);			cookie_unref(private->cookie);			private->cookie = NULL; 		}	}	return TRUE;}static int	 mem_activate(class_t *class){	mbr_private_t *private;	struct IPC_CHANNEL *ch;	int sockfd;	if(!class_valid(class)) return -1;	/* if already activated */	private = (mbr_private_t *)class->private;	if(private->llm)return -1;	ch 	   = private->channel;	if(!ch || ch->ops->initiate_connection(ch) != IPC_OK) {		return -1;	}	sockfd = ch->ops->get_recv_select_fd(ch);	return sockfd;}static voidmem_unregister(class_t *class){	mbr_private_t  *private;	struct IPC_CHANNEL *ch;	private = (mbr_private_t *)class->private;	ch 	   = private->channel;	/* TOBEDONE	 * call all instances, of message done	 * on channel ch.	 */	ch->ops->destroy(ch);	g_free(private->llm);	g_free(private);}static oc_ev_callback_t *mem_set_callback(class_t *class, oc_ev_callback_t f){	mbr_private_t 	*private;	oc_ev_callback_t *ret_f;	if(!class_valid(class)) return NULL;	private = (mbr_private_t *)class->private;		ret_f = private->callback;	private->callback = f;	return ret_f;}/* this function is a kludge, to accomodate special behaviour not * supported by 0.2 version of the API  */static voidmem_set_special(class_t *class, int type){	mbr_private_t 	*private;	if(!class_valid(class)) return;	private = (mbr_private_t *)class->private;		private->special = 1; /* turn on the special behaviour not supported				 	by 0.2 version of the API */	return;}static gbooleanmem_is_my_nodeid(class_t *class, const oc_node_t *node){	mbr_private_t 	*private;	if(!class_valid(class)) return FALSE;	private = (mbr_private_t *)class->private;	if (node->node_id == CLLM_GET_MYUUID(private->llm))		return TRUE;	return FALSE;}class_t *oc_ev_memb_class(oc_ev_callback_t  *fn){	mbr_private_t 	*private;	class_t *memclass;	struct IPC_CHANNEL *ch;	GHashTable * attrs;	static char 	path[] = IPC_PATH_ATTR;	static char 	ccmfifo[] = CCMFIFO;	memclass = g_malloc(sizeof(class_t));	if (!memclass) return NULL;	private = (mbr_private_t *)g_malloc0(sizeof(mbr_private_t));	if (!private) {		g_free(memclass);		return NULL;	}	memclass->type = OC_EV_MEMB_CLASS;	memclass->set_callback  =  mem_set_callback;	memclass->handle_event  =  mem_handle_event;	memclass->activate = mem_activate;	memclass->unregister = mem_unregister;	memclass->is_my_nodeid = mem_is_my_nodeid;	memclass->special = mem_set_special;	memclass->private = (void *)private;	private->callback = fn;	private->magiccookie = 0xabcdef;	private->client_report = FALSE;	private->special = 0; /* no special behaviour */	attrs = g_hash_table_new(g_str_hash,g_str_equal);	g_hash_table_insert(attrs, path, ccmfifo);	ch = ipc_channel_constructor(IPC_DOMAIN_SOCKET, attrs);	g_hash_table_destroy(attrs);	if(!ch) {		g_free(memclass);		g_free(private);		return NULL;	}	private->channel = ch;	return memclass;}

⌨️ 快捷键说明

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