📄 ccm.c
字号:
== 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 + -