📄 distnamelib.c
字号:
* ERRNO:* \is* \i S_distNameLib_INVALID_WAIT_TYPE* The wait type should be either NO_WAIT or WAIT_FOREVER .* \ie*/STATUS distNameFindByValueAndType ( void * value, /* value to search for */ DIST_NAME_TYPE type, /* type of object for which to search */ char * name, /* where to return name */ int waitType /* NO_WAIT or WAIT_FOREVER */ ) { DIST_NAME_DB_NODE * pNode; DIST_NAME_MATCH match; if (waitType != NO_WAIT && waitType != WAIT_FOREVER) { errnoSet (S_distNameLib_INVALID_WAIT_TYPE); return (ERROR); /* wait type is invalid */ } match.pMatchValue = value; match.matchType = type;again: pNode = distNameEach ((FUNCPTR) distNameMatchOne, (int) &match); if (!pNode) { if (waitType == WAIT_FOREVER) { /* object not found; we have to wait ... */ distNameLclBlockOnAdd(); goto again; } else return (ERROR); /* object not found */ } strcpy (name, (char *) &(pNode->symName)); return (OK); }/***************************************************************************** distNameMatchOne - helper for distNameFindByValueAndType() (VxFusion option)** This routine is called by distNameFindByValueAndType() to check a database* node for a match.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: TRUE, if a match is found.** NOMANUAL*/LOCAL BOOL distNameMatchOne ( DIST_NAME_DB_NODE * pNode, /* database node to match */ DIST_NAME_MATCH * pMatch /* match data */ ) { DIST_OBJ_NODE * pObjNodeMatch; DIST_OBJ_NODE * pObjNodeDb; MSG_Q_ID msgQId; if (pNode->type == pMatch->matchType) { switch (pNode->type) { case T_DIST_MSG_Q: { pObjNodeDb = MSG_Q_ID_TO_DIST_OBJ_NODE (pNode->value.msgQId); msgQId = *((MSG_Q_ID *) pMatch->pMatchValue); pObjNodeMatch = MSG_Q_ID_TO_DIST_OBJ_NODE (msgQId); /* * Check for equality. For group IDs, the objUniqId * referenced using objNodeId is enough. However, for * normal message queues, we need to check both the objUniqId * (using objNodeId) and objUniqReside (using objNodeReside) * fields. */ if (IS_DIST_MSG_Q_TYPE_GRP ( (DIST_MSG_Q_ID) pObjNodeMatch->objNodeId)) { if (pObjNodeDb->objNodeId == pObjNodeMatch->objNodeId) return (FALSE); /* matched */ } else { if ((pObjNodeDb->objNodeId == pObjNodeMatch->objNodeId) && (pObjNodeDb->objNodeReside == pObjNodeMatch->objNodeReside)) { return (FALSE); } } break; } default: { char *valDb = (char *) &(pNode->value); char *valMatch = (char *) pMatch->pMatchValue; if (! bcmp (valDb, valMatch, pNode->valueLen)) return (FALSE); /* matched */ } } } return (TRUE); /* continue */ }/***************************************************************************** distNameRemove - remove an entry from the distributed name database (VxFusion option)** This routine removes an object, that is bound to <name>, from the* distributed name database. All copies of the distributed name database * get updated.** This routine returns OK, even if some nodes on the system do not* respond to the remove request broadcast. A node that does not acknowledge* a transmission is assumed to have crashed.* You can use the distCtl() routine* in distLib to set a routine to be called in the event that a node crashes.** Removing the name of a distributed object ID (T_DIST_MSG_Q) does not* invalidate the object ID.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: OK, or ERROR if the operation fails.** ERRNO:* \is* \i S_distNameLib_NAME_TOO_LONG* The name to be removed from the database is too long.* \ie** SEE ALSO: distLib*/STATUS distNameRemove ( char * name /* name of object to remove */ ) { DIST_PKT_DNDB_RM pktDndbRm; DIST_IOVEC IOVec[2]; int nameLen;#ifdef DIST_DIAGNOSTIC STATUS status;#endif if ((nameLen = strlen (name)) > DIST_NAME_MAX_LENGTH) { errnoSet (S_distNameLib_NAME_TOO_LONG); return (ERROR); /* name too long */ } if (distNameLclRemove (name, nameLen) == ERROR) return (ERROR); /* name not in database */ pktDndbRm.dndbRmHdr.pktType = DIST_PKT_TYPE_DNDB; pktDndbRm.dndbRmHdr.pktSubType = DIST_PKT_TYPE_DNDB_RM; pktDndbRm.dndbRmNameLen = (UINT8) nameLen; IOVec[0].pIOBuffer = &pktDndbRm; IOVec[0].IOLen = DIST_PKT_HDR_SIZEOF (DIST_PKT_DNDB_RM); IOVec[1].pIOBuffer = name; IOVec[1].IOLen = nameLen;#ifdef DIST_DIAGNOSTIC status = distNetIOVSend (DIST_IF_BROADCAST_ADDR, &IOVec[0], 2, WAIT_FOREVER, DIST_PKT_DNDB_PRIO); if (status == ERROR) { /* Local node has removed binding--one of the remote nodes may not. */ distLog ("distNameRemove: error updating remote name databases\n"); }#else distNetIOVSend (DIST_IF_BROADCAST_ADDR, &IOVec[0], 2, WAIT_FOREVER, DIST_PKT_DNDB_PRIO);#endif return (OK); /* return OK, always */ }/***************************************************************************** distNameInput - called when a DNDB packet arrives (VxFusion option)** This routine processes incoming DNDB packets.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: Status of packet processing.** NOMANUAL*/LOCAL DIST_STATUS distNameInput ( DIST_NODE_ID nodeIdSrc, /* not currently used */ DIST_TBUF_HDR * pTBufHdr /* points to input packet */ ) { DIST_PKT * pPkt; int pktLen; UNUSED_ARG(nodeIdSrc); distStat.dndbInReceived++; if ((pktLen = pTBufHdr->tBufHdrOverall) < sizeof (DIST_PKT)) distPanic ("distNameInput: packet too short\n"); pPkt = (DIST_PKT *) (DIST_TBUF_GET_NEXT (pTBufHdr))->pTBufData; switch (pPkt->pktSubType) { case DIST_PKT_TYPE_DNDB_ADD: { DIST_NAME_TYPE_ALL valNet; DIST_PKT_DNDB_ADD pktAdd; DIST_NAME_DB_NODE * pNode; DIST_NAME_TYPE type; void * pValNet; char name[DIST_NAME_MAX_LENGTH + 1]; int valueLen; int nameLen; if (pktLen < DIST_PKT_HDR_SIZEOF (DIST_PKT_DNDB_ADD)) distPanic ("distNameInput/ADD: packet too short\n"); distTBufCopy (DIST_TBUF_GET_NEXT (pTBufHdr), 0, (char *)&pktAdd, DIST_PKT_HDR_SIZEOF (DIST_PKT_DNDB_ADD)); valueLen = pktAdd.dndbAddValueLen; nameLen = pktAdd.dndbAddNameLen; if (pktLen != DIST_PKT_HDR_SIZEOF (DIST_PKT_DNDB_ADD) + valueLen + nameLen) distPanic ("distNameInput/ADD: packet has wrong length\n"); if (valueLen > DIST_VALUE_MAX_LENGTH) distPanic ("distNameInput/ADD: value too long\n"); if (nameLen > DIST_NAME_MAX_LENGTH) distPanic ("distNameInput/ADD: name too long\n"); distTBufCopy (DIST_TBUF_GET_NEXT (pTBufHdr), (DIST_PKT_HDR_SIZEOF (DIST_PKT_DNDB_ADD) + valueLen), (char *) &name, nameLen); switch ((type = ntohs (pktAdd.dndbAddType))) { case T_DIST_UINT16: { distTBufCopy (DIST_TBUF_GET_NEXT (pTBufHdr), DIST_PKT_HDR_SIZEOF (DIST_PKT_DNDB_ADD), (char *) &(valNet.uint16), valueLen); valNet.uint16 = ntohs (valNet.uint16); pValNet = &(valNet.uint16); break; } case T_DIST_FLOAT: case T_DIST_UINT32: case T_DIST_NODE: { distTBufCopy (DIST_TBUF_GET_NEXT (pTBufHdr), DIST_PKT_HDR_SIZEOF (DIST_PKT_DNDB_ADD), (char *) &(valNet.uint32), valueLen); valNet.uint32 = ntohl (valNet.uint32); pValNet = &(valNet.uint32); break; } case T_DIST_UINT64: case T_DIST_DOUBLE: { distTBufCopy (DIST_TBUF_GET_NEXT (pTBufHdr), DIST_PKT_HDR_SIZEOF (DIST_PKT_DNDB_ADD), (char *) &(valNet.uint64), valueLen); pValNet = distNtoh64((uint32_t *)&(valNet.uint64),type); break; } case T_DIST_MSG_Q: /* complex objects go here */ { DIST_OBJ_UNIQ_ID *pObjUniqId; distTBufCopy (DIST_TBUF_GET_NEXT (pTBufHdr), DIST_PKT_HDR_SIZEOF (DIST_PKT_DNDB_ADD), (char *) &(valNet.objUniqId), valueLen); pObjUniqId = (DIST_OBJ_UNIQ_ID *) &(valNet.objUniqId); pObjUniqId->objUniqReside = ntohl (pObjUniqId->objUniqReside); pObjUniqId->objUniqId = ntohl (pObjUniqId->objUniqId); pValNet = pObjUniqId; break; } default: /* T_DIST_UINT8 and user defined */ { distTBufCopy (DIST_TBUF_GET_NEXT (pTBufHdr), DIST_PKT_HDR_SIZEOF (DIST_PKT_DNDB_ADD), (char *) &(valNet.field), valueLen); pValNet = &valNet.field; } } pNode = distNameLclAddRaw ((char *) &name, nameLen, pValNet, valueLen, type); if (! pNode) distPanic ("distNameInput/ADD: database add failed\n"); return (DIST_NAME_STATUS_OK); } case DIST_PKT_TYPE_DNDB_RM: { DIST_PKT_DNDB_RM pktRm; char name[DIST_NAME_MAX_LENGTH + 1]; int nameLen; if (pktLen < DIST_PKT_HDR_SIZEOF (DIST_PKT_DNDB_RM)) distPanic ("distNameInput/RM: packet too short\n"); distTBufCopy (DIST_TBUF_GET_NEXT (pTBufHdr), 0, (char *) &pktRm, DIST_PKT_HDR_SIZEOF (DIST_PKT_DNDB_RM)); nameLen = pktRm.dndbRmNameLen; if (pktLen != DIST_PKT_HDR_SIZEOF (DIST_PKT_DNDB_RM) + nameLen) distPanic ("distNameInput/RM: packet has wrong length\n"); if (nameLen > DIST_NAME_MAX_LENGTH) distPanic ("distNameInput/RM: name too long\n"); distTBufCopy (DIST_TBUF_GET_NEXT (pTBufHdr), DIST_PKT_HDR_SIZEOF (DIST_PKT_DNDB_RM), (char *) &name, nameLen); if (distNameLclRemove (name, nameLen) == ERROR) distPanic ("distNameInput/RM: not in database\n"); return (DIST_NAME_STATUS_OK); } default:#ifdef DIST_DIAGNOSTIC distLog ("distNameInput: unknown subtype %d\n", pPkt->pktSubType);#endif return (DIST_NAME_STATUS_PROTOCOL_ERROR); } }/***************************************************************************** distNameLclAddRaw - bind name to raw value in local name database (VxFusion option)** Internally used function to bind name in local database.*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -