📄 distnodelib.c
字号:
} return (ERROR); } case DIST_CTL_CRASHED_HOOK: { for (i = 0; i < DIST_NODE_MAX_HOOKS; i++) { if (distNodeCrashedHook[i] == NULL) { distNodeCrashedHook[i] = (FUNCPTR) arg; return (OK); } } return (ERROR); } case DIST_CTL_GET_LOCAL_ID: return (distNodeLocalId); case DIST_CTL_GET_LOCAL_STATE: return (distNodeLocalState); case DIST_CTL_NACK_SUPPORT: if ((BOOL) arg != TRUE && (BOOL) arg != FALSE) return (ERROR); distNodeSupportNACK = (BOOL) arg; return (OK); case DIST_CTL_PGGYBAK_BRDCST_SUPPORT: if ((BOOL) arg != TRUE && (BOOL) arg != FALSE) return (ERROR); distNodeSupportPBB = (BOOL) arg; return (OK); case DIST_CTL_PGGYBAK_UNICST_SUPPORT: if ((BOOL) arg != TRUE && (BOOL) arg != FALSE) return (ERROR); distNodeSupportPBU = (BOOL) arg; return (OK); default: errnoSet (S_distLib_UNKNOWN_REQUEST); return (ERROR); } }/***************************************************************************** distNodeSendBootstrap - send a bootstrap packet (VxFusion option)** This routine sends a bootstrap packet.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: OK, if packet sent.* NOMANUAL*/LOCAL STATUS distNodeSendBootstrap ( DIST_NODE_ID dest, /* destination node */ int type, /* bootstrap type */ int timeout /* xmit timeout */ ) { DIST_TBUF_HDR * pTBufHdr; DIST_PKT_BOOT * pPkt; DIST_TBUF * pTBuf; if ((pTBufHdr = DIST_TBUF_HDR_ALLOC ()) == NULL) return (ERROR); /* out of TBufs */ pTBufHdr->tBufHdrPrio = DIST_BOOTSTRAP_PRIO; pTBufHdr->tBufHdrDest = dest; pTBufHdr->tBufHdrOverall = sizeof (*pPkt); pTBufHdr->tBufHdrTimo = timeout; if ((pTBuf = DIST_TBUF_ALLOC ()) == NULL) { DIST_TBUF_FREEM (pTBufHdr); return (ERROR); /* out of TBufs */ } pTBuf->tBufFlags = DIST_TBUF_FLAG_HDR | DIST_TBUF_FLAG_BROADCAST; pTBuf->tBufType = DIST_TBUF_TTYPE_BOOTSTRAP; pTBuf->tBufSeq = 0; pTBuf->tBufNBytes = sizeof (*pPkt); pPkt = (DIST_PKT_BOOT *) pTBuf->pTBufData; DIST_TBUF_ENQUEUE (pTBufHdr, pTBuf); pPkt->pktBootType = (UINT8) type; return (distNodePktSend (pTBufHdr)); }/***************************************************************************** distNodeBootstrap - broadcast a bootstrap packet (VxFusion option)** This routine broadcasts a bootstrap packet.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: OK, if broadcast succeeds.* NOMANUAL*/STATUS distNodeBootstrap ( int timeout /* xmit timeout */ ) { STATUS status; status = distNodeSendBootstrap (DIST_IF_BROADCAST_ADDR, DIST_BOOTING_REQ, timeout); return (status); }/***************************************************************************** distNodeFindById - find node in node database (VxFusion option)** This routine tries to find the information node with node id <nodeId>* in the node database.** This routine takes <distNodeDbLock>. Usually, it will be called with* the lock already taken, but not always, so the lock is taken here* to be safe.** RETURNS: Pointer to the node entry, or NULL if not found.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** NOMANUAL*/LOCAL DIST_NODE_DB_NODE * distNodeFindById ( DIST_NODE_ID nodeId /* ID of node to find */ ) { DIST_NODE_DB_NODE distNodeMatch; DIST_NODE_DB_NODE * pDistNodeFound; distNodeMatch.nodeId = nodeId; DIST_NODE_DB_LOCK; pDistNodeFound = (DIST_NODE_DB_NODE *) hashTblFind (distNodeDbId, (HASH_NODE *) &distNodeMatch, KEY_CMP_ARG); DIST_NODE_DB_UNLOCK; return (pDistNodeFound); }/***************************************************************************** distNodeCreate - create a new node (VxFusion option)** This routine creates a new node with id <distNodeId>.* distNodeCreate() returns a pointer to the DB entry.** This function takes the DB node database lock before inserting the* node into the database.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: Pointer to node, or NULL.* NOMANUAL*/DIST_NODE_DB_NODE * distNodeCreate ( DIST_NODE_ID nodeId, /* ID for new node */ int state /* state of new node */ ) { DIST_NODE_DB_NODE * pNodeNew; DIST_NODE_BFLD * pBFld; int sz; /* This node is new to the database. */#ifdef DIST_NODE_REPORT distLog("distNodeCreate: Creating node 0x%lx with state %d\n", nodeId, state);#endif /* allocate needed space; quit if we can't get it */ pNodeNew = (DIST_NODE_DB_NODE *) malloc (sizeof (DIST_NODE_DB_NODE)); if (pNodeNew == NULL) { distStat.memShortage++; return (NULL); } sz = DIST_NODE_BFLD_SIZEOF (DIST_IF_RNG_BUF_SZ); pBFld = (DIST_NODE_BFLD *) malloc (4 * sz); if (pBFld == NULL) { free(pNodeNew); /* no memory leaks here */ distStat.memShortage++; return (NULL); } /* now fill in DIST_NODE_DB_NODE info */ bzero ((char *) pNodeNew, sizeof (DIST_NODE_DB_NODE)); pNodeNew->nodeId = nodeId; pNodeNew->nodeBroadcast.commAckLastRecvd = (INT16) winSub (0, 1); pNodeNew->nodeState = state; distNodeNumNodesAll++; if (DIST_NODE_STATE_IS_ALIVE (state)) distNodeNumNodesAlive++; if (state == DIST_NODE_STATE_OPERATIONAL) distNodeNumNodesOperational++; pNodeNew->nodeState = state; bzero ((char *) pBFld, 2 * sz); pNodeNew->nodeUnicast.pCommCompleted = pBFld; pNodeNew->nodeBroadcast.pCommCompleted = ((char *) pBFld) + sz; /* now link the node into the data base */ DIST_NODE_DB_LOCK; hashTblPut (distNodeDbId, (HASH_NODE *)pNodeNew); DIST_NODE_DB_UNLOCK; return (pNodeNew); }/***************************************************************************** distNodeSetState - set state of a node (VxFusion option)** This routine is used to change the state of a node. It is only called* from two places in distNodeReassemble() which takes the node DB lock.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: N/A* NOMANUAL*/LOCAL void distNodeSetState ( DIST_NODE_DB_NODE * pNode, /* node */ int newState /* new state */ ) { int curState = pNode->nodeState; DIST_NODE_ID nodeId = pNode->nodeId; int i;#ifdef DIST_DIAGNOSTIC if (curState != newState) distLog ("distNodeSetState: state of node 0x%lx shifts from %s to %s\n", nodeId, distNodeStateToName (curState), distNodeStateToName (newState));#endif if ((! DIST_NODE_STATE_IS_ALIVE (curState)) && DIST_NODE_STATE_IS_ALIVE (newState)) { distNodeNumNodesAlive++; } if (DIST_NODE_STATE_IS_ALIVE (curState) && (! DIST_NODE_STATE_IS_ALIVE (newState))) { distNodeNumNodesAlive--; } if (curState < DIST_NODE_STATE_OPERATIONAL && newState == DIST_NODE_STATE_OPERATIONAL) { distNodeNumNodesOperational++; for (i = 0; i < DIST_NODE_MAX_HOOKS; i++) { if (distNodeOperationalHook[i] != NULL) (* (distNodeOperationalHook[i])) (nodeId); } pNode->nodeState = newState; return; } if (curState == DIST_NODE_STATE_OPERATIONAL && newState < DIST_NODE_STATE_OPERATIONAL) { distNodeNumNodesOperational--; if (newState == DIST_NODE_STATE_CRASHED) { for (i = 0; i < DIST_NODE_MAX_HOOKS; i++) { if (distNodeCrashedHook[i] != NULL) (* (distNodeCrashedHook[i])) (nodeId); } } pNode->nodeState = newState; return; } pNode->nodeState = newState; }/***************************************************************************** distNodeOperational - sets a node to be alive (VxFusion option)** This routine changes the state of the node with the id <distNodeId>* to OPERATIONAL.** This routine takes <distNodeDbLock>.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: Pointer to node, or NULL.* NOMANUAL*/DIST_NODE_DB_NODE * distNodeOperational ( DIST_NODE_ID distNodeId /* node ID */ ) { DIST_NODE_DB_NODE * pNodeFound; int i; DIST_NODE_DB_LOCK; if ((pNodeFound = distNodeFindById (distNodeId)) != NULL) { /* * This node is already in the node database. If state is already * OPERATIONAL, do nothing - we even have not recognized the absence. */ if (! DIST_NODE_IS_ALIVE (pNodeFound)) distNodeNumNodesAlive++; if (pNodeFound->nodeState < DIST_NODE_STATE_OPERATIONAL) {#ifdef DIST_DIAGNOSTIC distLog ("distNodeOperational: Set node 0x%lx to state OPERATIONAL\n", distNodeId);#endif distNodeNumNodesOperational++; for (i = 0; i < DIST_NODE_MAX_HOOKS; i++) { if (distNodeOperationalHook[i] != NULL) (* (distNodeOperationalHook[i])) (distNodeId); } } pNodeFound->nodeState = DIST_NODE_STATE_OPERATIONAL; } DIST_NODE_DB_UNLOCK; return (pNodeFound); }/***************************************************************************** distNodeCrashed - sets a node to be dead (VxFusion option)** This routine changes the state of the node with the id <distNodeId>* to CRASHED.** This routine takes <distNodeDbLock>.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: Pointer to node, or NULL.* NOMANUAL*/DIST_NODE_DB_NODE * distNodeCrashed ( DIST_NODE_ID distNodeId /* node ID */ ) { DIST_NODE_DB_NODE * pNodeFound; int i; /* you cannot kill the broadcast node */ if (distNodeId == DIST_IF_BROADCAST_ADDR) return (NULL); DIST_NODE_DB_LOCK; /* find the node */ if ((pNodeFound = distNodeFindById (distNodeId)) != NULL) { if (DIST_NODE_IS_ALIVE (pNodeFound)) distNodeNumNodesAlive--; if (pNodeFound->nodeState >= DIST_NODE_STATE_OPERATIONAL) {#ifdef DIST_DIAGNOSTIC distLog ("distNodeCrashed: Set node 0x%lx to state CRASHED\n", distNodeId);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -