void saNameConcat(SaNameT* nameOut, const SaNameT *prefix, const char* separator, const SaNameT *suffix) { unsigned int curpos = 0; if (prefix) { memcpy(nameOut->value, prefix->value, prefix->length); curpos += prefix->length; } if (separator) { int amt2Copy = CL_MIN((CL_MAX_NAME_LENGTH-1) - curpos,strlen(separator)); if (amt2Copy) memcpy(&nameOut->value[curpos], separator, amt2Copy); curpos += amt2Copy; } if (suffix) { int amt2Copy = CL_MIN((CL_MAX_NAME_LENGTH-1) - curpos,suffix->length); if (amt2Copy) memcpy(&nameOut->value[curpos], suffix->value, amt2Copy); curpos += amt2Copy; } assert(curpos < CL_MAX_NAME_LENGTH); nameOut->value[curpos]=0; nameOut->length=curpos; }
/* * Delete a chunk from the last section matching a data chunk of dataSize */ ClRcT clCacheEntryDataDelete(ClCachedCkptSvcInfoT *serviceInfo, ClPtrT data, ClUint32T dataSize) { if (!serviceInfo->cache) return CL_ERR_NOT_INITIALIZED; ClUint32T *numberOfSections = (ClUint32T*)serviceInfo->cache; ClUint32T *sizeOfCache = (ClUint32T*)(numberOfSections + 1); ClCachedCkptDataT *ckptData = (ClCachedCkptDataT*)(sizeOfCache + 1); ClUint32T hdrSize = (ClUint8T*)ckptData - serviceInfo->cache; ClUint32T offset = 0; ClRcT rc = CL_OK; if(!data || !dataSize) return CL_ERR_INVALID_PARAMETER; if(!numberOfSections || !*numberOfSections) return CL_ERR_INVALID_STATE; if(dataSize > *sizeOfCache + hdrSize) return CL_ERR_NO_SPACE; for(ClUint32T i = 0; i < *numberOfSections; ++i) { ckptData = (ClCachedCkptDataT*) ( (ClUint8T*)ckptData + offset ); offset += sizeof(*ckptData) + ckptData->dataSize; } if(!ckptData->data || dataSize > ckptData->dataSize) return CL_ERR_NO_SPACE; ClUint32T dataChunks = ckptData->dataSize/dataSize; ClUint32T chunkSize = 0; offset = 0; for(ClUint32T i = 0; i < dataChunks; ++i) { chunkSize = CL_MIN(ckptData->dataSize - offset, dataSize); if(chunkSize != dataSize) break; if(!memcmp(ckptData->data + offset, data, chunkSize)) { ckptData->dataSize -= chunkSize; *sizeOfCache -= chunkSize; if(offset < ckptData->dataSize) { memmove(ckptData->data + offset, ckptData->data + offset + chunkSize, ckptData->dataSize - offset); } rc = CL_OK; goto found; } offset += chunkSize; } rc = CL_ERR_NOT_EXIST; found: return rc; }
void clEvtUtilsNameCpy(SaNameT *pNameDst, const SaNameT *pNameSrc) { CL_FUNC_ENTER(); pNameDst->length = pNameSrc->length; memcpy(pNameDst->value, pNameSrc->value, CL_MIN((pNameSrc->length + 1), (ClInt32T)sizeof(pNameDst->value))); CL_FUNC_EXIT(); return; }
static ClRcT clPoolShrinkList( ClPoolHeaderT *pPoolHeader, ClExtendedListT *pList, const ClPoolShrinkOptionsT *pShrinkOptions) { ClExtendedPoolHeaderT *pExtendedPoolHeader = NULL; ClExtendedPoolHeaderT *pNext = NULL; ClUint32T numExtendedFreePools = 0; ClUint32T i; ClRcT rc = CL_OK; numExtendedFreePools = CL_POOL_EXTENDED_LIST_COUNT (pList); switch(pShrinkOptions->shrinkFlags) { case CL_POOL_SHRINK_DEFAULT: /*50 % of the free list*/ numExtendedFreePools /= 2; break; case CL_POOL_SHRINK_ONE: numExtendedFreePools = CL_MIN (1, numExtendedFreePools); break; default: case CL_POOL_SHRINK_ALL: ; break; } if (numExtendedFreePools == 0) { CL_DEBUG_PRINT (CL_DEBUG_WARN, ("No free list to shrink\n")); goto out; } for(i = 0, pExtendedPoolHeader = pList->pHeadExtendedList; i < numExtendedFreePools && pExtendedPoolHeader; ++i) { pNext = pExtendedPoolHeader->pNext; CL_POOL_EXTENDED_LIST_DEQUEUE(pList, pExtendedPoolHeader); rc = clExtendedPoolDestroy (pPoolHeader, pExtendedPoolHeader); if(rc != CL_OK) { CL_DEBUG_PRINT (CL_DEBUG_ERROR, ("Error in destroying extended pool\n")); goto out; } pExtendedPoolHeader = pNext; } out: return rc; }
ClRcT clLogInitDataDump(ClHandleDatabaseHandleT hDb, ClLogHandleT hLog, ClPtrT pCookie) { ClRcT rc = CL_OK; ClUint32T bitmapLen = 0; ClUint32T i = 0; ClLogClntEoDataT *pClntEoEntry = NULL; ClLogInitHandleDataT *pData = NULL; ClCharT ret[MAX_DEBUG_DISPLAY]; ClCharT p[MAX_DEBUG_DISPLAY]; ClCharT **ppRet = (ClCharT**) pCookie; CL_LOG_DEBUG_TRACE(("Enter")); rc = clLogClntEoEntryGet(&pClntEoEntry); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clLogClntEoEntryGet(): rc[0x %x]", rc)); return rc; } rc = clHandleCheckout(pClntEoEntry->hClntHandleDB, hLog, (void **) (&pData)); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clHandleCheckout(): rc[0x %x]", rc)); return rc; } memset(ret, '\0', MAX_DEBUG_DISPLAY); memset(p, '\0', MAX_DEBUG_DISPLAY); if( CL_LOG_INIT_HANDLE == pData->type ) { snprintf(ret, MAX_DEBUG_DISPLAY, "Init handle: %#llX\nCallbacks: %p\nBitmap:%p\n", hLog, (void *) pData->pCallbacks, (void *) pData->hStreamBitmap); bitmapLen = clBitmapLen(pData->hStreamBitmap); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clBitmapLen(): rc[0x %x]", rc)); return rc; } snprintf(p, MAX_DEBUG_DISPLAY, "hStreamBitmap:\n"); strncat(ret, p, CL_MIN(strlen(p), (MAX_DEBUG_DISPLAY-strlen(ret)-1))); for( i = 0; i < bitmapLen; i++ ) { if( clBitmapIsBitSet(pData->hStreamBitmap, i, &rc) ) { snprintf(p, MAX_DEBUG_DISPLAY, "%d ", 1); strncat(ret, p, CL_MIN(strlen(p), (MAX_DEBUG_DISPLAY-strlen(ret)-1))); } else { snprintf(p, MAX_DEBUG_DISPLAY, "%d ", 0); strncat(ret, p, CL_MIN(strlen(p), (MAX_DEBUG_DISPLAY-strlen(ret)-1))); } } bitmapLen = clBitmapLen(pData->hFileBitmap); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clBitmapLen(): rc[0x %x]", rc)); return rc; } snprintf(p, MAX_DEBUG_DISPLAY, "\nhFileBitmap:\n"); strncat(ret, p, CL_MIN(strlen(p), (MAX_DEBUG_DISPLAY-strlen(ret)-1))); for( i = 0; i < bitmapLen; i++ ) { if( clBitmapIsBitSet(pData->hFileBitmap, i, &rc) ) { snprintf(p, MAX_DEBUG_DISPLAY, "%d ", 1); strncat(ret, p, CL_MIN(strlen(p), (MAX_DEBUG_DISPLAY-strlen(ret)-1))); } else { snprintf(p, MAX_DEBUG_DISPLAY, "%d ", 0); strncat(ret, p, CL_MIN(strlen(p), (MAX_DEBUG_DISPLAY-strlen(ret)-1))); } } } rc = clHandleCheckin(pClntEoEntry->hClntHandleDB, hLog); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clHandleCheckin(): rc[0x %x]", rc)); return rc; } *ppRet = (ClCharT*) clHeapAllocate(strlen(ret) + 1); if( NULL == *ppRet ) { CL_LOG_DEBUG_ERROR(("clHeapAllocate(): rc[0x %x]", rc)); return rc; } snprintf(*ppRet, strlen(ret)+1, ret); CL_LOG_DEBUG_TRACE(("Exit")); return rc; }
ClRcT clLogStreamDataDump(ClHandleDatabaseHandleT hDb, ClLogStreamHandleT hStream, ClPtrT pCookie) { ClRcT rc = CL_OK; ClLogStreamHandleDataT *pData = NULL; ClLogClntStreamDataT *pStreamInfo = NULL; ClLogClntEoDataT *pClntEoEntry = NULL; ClCharT **ppRet = (ClCharT**) pCookie; ClCharT ret[MAX_DEBUG_DISPLAY]; ClCharT p[MAX_DEBUG_DISPLAY]; CL_LOG_DEBUG_TRACE(("Enter")); rc = clLogClntEoEntryGet(&pClntEoEntry); if( CL_OK != rc ) { return rc; } rc = clHandleCheckout(hDb, hStream, (void **) (&pData)); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clHandleCheckout(): rc[0x %x]", rc)); return rc; } memset(ret, '\0', MAX_DEBUG_DISPLAY); memset(p, '\0', MAX_DEBUG_DISPLAY); if( CL_LOG_STREAM_HANDLE == pData->type ) { snprintf(ret, MAX_DEBUG_DISPLAY, "Stream handle: %#llX\nStreamNode: %p\n", hStream, (ClPtrT) pData->hClntStreamNode); rc = clCntNodeUserDataGet(pClntEoEntry->hClntStreamTable, pData->hClntStreamNode, (ClCntDataHandleT *) &pStreamInfo); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clCntNodeUserDataGet(): rc[0x %x]", rc)); return rc; } snprintf(p,MAX_DEBUG_DISPLAY, "Stream Header: %p\n", (ClCharT *) pStreamInfo->pStreamHeader); strncat(ret, p, CL_MIN(strlen(p), (MAX_DEBUG_DISPLAY-strlen(ret)-1))); snprintf(p,MAX_DEBUG_DISPLAY, "Shm Name: %.*s", pStreamInfo->shmName.length, pStreamInfo->shmName.pValue); strncat(ret, p, CL_MIN(strlen(p), (MAX_DEBUG_DISPLAY-strlen(ret)-1))); rc = clHandleCheckin(hDb, hStream); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clHandleCheckin(): rc[0x %x]", rc)); return rc; } *ppRet = (ClCharT*) clHeapAllocate(strlen(ret) + 1); if( NULL == *ppRet ) { CL_LOG_DEBUG_ERROR(("clHeapAllocate(): rc[0x %x]", rc)); return rc; } snprintf(*ppRet, strlen(ret)+1, ret); } CL_LOG_DEBUG_TRACE(("Exit")); return rc; }
ClRcT clLogClntStreamWriteWithHeader(ClLogClntEoDataT *pClntEoEntry, ClLogSeverityT severity, ClUint16T serviceId, ClUint16T msgId, const ClCharT *pMsgHeader, va_list args, ClCntNodeHandleT hClntStreamNode) { ClRcT rc = CL_OK; ClLogClntStreamDataT *pClntData = NULL; ClLogStreamHeaderT *pStreamHeader = NULL; ClUint8T *pStreamRecords = NULL; ClUint32T nUnAcked = 0; ClUint32T nDroppedRecords = 0; ClUint8T *pBuffer = NULL; ClUint32T recordSize = 0; CL_LOG_DEBUG_TRACE(("Enter")); CL_LOG_DEBUG_VERBOSE(("Severity: %d ServiceId: %hu MsgId: %hu CompId: %u", severity, serviceId, msgId, pClntEoEntry->compId)); rc = clCntNodeUserDataGet(pClntEoEntry->hClntStreamTable, hClntStreamNode, (ClCntDataHandleT *) &pClntData); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clCntNodeUserDataGet(): rc[0x %x]", rc)); return rc; } pStreamHeader = pClntData->pStreamHeader; pStreamRecords = pClntData->pStreamRecords; #ifdef NO_SAF ClLogStreamKeyT *pUserKey = NULL; rc = clCntNodeUserKeyGet(pClntEoEntry->hClntStreamTable, hClntStreamNode, (ClCntKeyHandleT *) &pUserKey); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clCntNodeUserKeyGet(): rc[0x %x]", rc)); return rc; } ClInt32T recSize= pClntData->recSize; #define __UPDATE_RECORD_SIZE do { \ if(recSize < nbytes ) \ recSize = nbytes; \ recSize -= nbytes; \ if(!recSize) \ return CL_OK; \ }while(0) ClUint16T streamId = 10; ClUint64T sequenceNum = pUserKey->sequenceNum; ClUint32T clientId = pClntEoEntry->clientId; ClUint8T* pRecord=clHeapAllocate(recSize); ClTimeT timeStamp = 0; ClUint8T *pRecStart = pRecord; ClUint16T tmp = 1; ClUint8T endian = *(ClUint8T *) &tmp; memset(pRecord, 0, recSize); if( CL_LOG_MSGID_PRINTF_FMT == msgId ) { ClInt32T nbytes = 0; if(recSize < LOG_ASCII_MIN_REC_SIZE ) /* just a minimum record size taking care of the headers*/ { printf("LOG record size has to be minimum [%d] bytes. Got [%d] bytes\n", LOG_ASCII_MIN_REC_SIZE, recSize); return CL_LOG_RC(CL_ERR_INVALID_PARAMETER); } /* * In ASCII logging, we dont need header, so just keeping only the * required fields */ nbytes = snprintf((ClCharT *)pRecord, recSize, LOG_ASCII_HDR_FMT, endian, severity & 0x1f); pRecord += nbytes; __UPDATE_RECORD_SIZE; { ClCharT *pSeverity = (ClCharT *)clLogSeverityStrGet(severity); ClCharT c = 0; ClInt32T hdrLen = 0; ClInt32T len = 0; va_list argsCopy; ClCharT *pFmtStr ; va_copy(argsCopy, args); pFmtStr = va_arg(argsCopy, ClCharT *); if(pMsgHeader && pMsgHeader[0]) { hdrLen = snprintf(&c, 1, "%s.%05lld : %6s) ", pMsgHeader, sequenceNum, pSeverity ? pSeverity : "DEBUG"); if(hdrLen < 0) hdrLen = 0; } len = vsnprintf(&c, 1, pFmtStr, argsCopy); va_end(argsCopy); if(len < 0) len = 0; hdrLen = CL_MIN(hdrLen, recSize - LOG_ASCII_HDR_LEN - LOG_ASCII_DATA_LEN - 1); len = CL_MIN(len, recSize - LOG_ASCII_HDR_LEN - LOG_ASCII_DATA_LEN - hdrLen - 1); nbytes = snprintf((ClCharT*)pRecord, recSize - 1, LOG_ASCII_HDR_LEN_FMT, hdrLen); pRecord += nbytes; __UPDATE_RECORD_SIZE; nbytes = snprintf((ClCharT*)pRecord, recSize - 1, LOG_ASCII_DATA_LEN_DELIMITER_FMT, len); pRecord += nbytes; __UPDATE_RECORD_SIZE; if(pMsgHeader && pMsgHeader[0]) { nbytes = snprintf((ClCharT*)pRecord, recSize - 1, "%s.%05lld : %6s) ", pMsgHeader, sequenceNum, pSeverity ? pSeverity : "DEBUG"); if(nbytes < 0) nbytes = 0; pRecord += nbytes; __UPDATE_RECORD_SIZE; } pFmtStr = va_arg(args, ClCharT *); nbytes = vsnprintf((ClCharT*)pRecord, recSize - 1, pFmtStr, args); if(nbytes < 0) nbytes = 0; } }
static ClUint32T __differenceVectorGet(ClDifferenceBlockT *block, ClUint8T *data, ClOffsetT offset, ClSizeT dataSize, ClDifferenceVectorT *differenceVector) { ClUint32T i; ClMD5T *md5CurList = block->md5List; ClMD5T *md5List ; ClUint32T md5CurBlocks = block->md5Blocks; ClUint32T md5Blocks = 0; ClUint32T dataBlocks, sectionBlocks ; ClSizeT sectionSize; ClSizeT vectorSize = 0; ClSizeT lastDataSize = dataSize; ClUint8T *pLastData = NULL; ClInt32T lastMatch = -1; ClBoolT doMD5 = CL_FALSE; ClUint32T startBlock, endBlock; ClOffsetT startOffset, nonZeroOffset = 0; sectionSize = offset + dataSize; /* * First align to md5 block size */ dataBlocks = ((dataSize + CL_MD5_BLOCK_MASK) & ~CL_MD5_BLOCK_MASK) >> CL_MD5_BLOCK_SHIFT; sectionBlocks = ((sectionSize + CL_MD5_BLOCK_MASK) & ~CL_MD5_BLOCK_MASK) >> CL_MD5_BLOCK_SHIFT; startOffset = offset & CL_MD5_BLOCK_MASK; startBlock = ( offset & ~CL_MD5_BLOCK_MASK ) >> CL_MD5_BLOCK_SHIFT; /* align the start block*/ endBlock = sectionBlocks; md5Blocks = CL_MAX(sectionBlocks, md5CurBlocks); md5List = (ClMD5T *) clHeapCalloc(md5Blocks, sizeof(*md5List)); CL_ASSERT(md5List != NULL); if(md5CurList) memcpy(md5List, md5CurList, md5CurBlocks); else { md5CurList = md5List; md5CurBlocks = md5Blocks; } /* * If the specified vector blocks don't match the data blocks. * refill. Reset the md5 for offsetted writes considering its cheaper to * just recompute the md5 for this block on a subsequent write to this block */ if(differenceVector && differenceVector->md5Blocks && differenceVector->md5Blocks == dataBlocks) { memcpy(md5List + startBlock, differenceVector->md5List, sizeof(*md5List) * differenceVector->md5Blocks); /* *If data vector already specified, then just update the md5 list and exit. */ if(differenceVector->numDataVectors) { clLogTrace("DIFF", "MD5", "Difference vector already specified with md5 list of size [%d] " "with [%d] difference data vectors", dataBlocks, differenceVector->numDataVectors); goto out_set; } } else doMD5 = CL_TRUE; data += offset; pLastData = data; /* * If we are going to allocate datavectors, free the existing set to be overridden * with a fresh set. */ if(differenceVector && differenceVector->dataVectors) { clHeapFree(differenceVector->dataVectors); differenceVector->dataVectors = NULL; differenceVector->numDataVectors = 0; } nonZeroOffset |= startOffset; for(i = startBlock; i < endBlock; ++i) { ClSizeT c = CL_MIN(CL_MD5_BLOCK_SIZE - startOffset, dataSize); nonZeroOffset &= startOffset; if(doMD5) { if(!startOffset) clMD5Compute(data, c, md5List[i].md5sum); else memset(&md5List[i], 0, sizeof(md5List[i])); } dataSize -= c; data += c; if(startOffset) startOffset = 0; /* * Just gather the new md5 list if there is no vector to be accumulated */ if(!differenceVector) continue; /* * Just gather md5s if we hit the limit for the current data size or if * we didnt have an md5 to start with */ if(md5List == md5CurList) { if(lastMatch < 0) lastMatch = i; continue; } if(i < md5CurBlocks) { /* * Always store offsetted blocks in the difference vector. whose md5 wasnt computed. */ if(!nonZeroOffset && memcmp(md5List[i].md5sum, md5CurList[i].md5sum, sizeof(md5List[i].md5sum)) == 0) { /* * Blocks are the same. Skip the add for this block. */ clLogTrace("DIFF", "MD5", "Skipping copying block [%d] to replica", i); continue; } } else { if(lastMatch < 0) { lastMatch = i; pLastData = data - c; lastDataSize = dataSize + c; } continue; } clLogTrace("DIFF", "MD5", "Copying block [%d] to replica of size [%lld]", i, c); if(!(differenceVector->numDataVectors & 7 ) ) { differenceVector->dataVectors = (ClDataVectorT*) clHeapRealloc(differenceVector->dataVectors, sizeof(*differenceVector->dataVectors) * (differenceVector->numDataVectors + 8)); CL_ASSERT(differenceVector->dataVectors != NULL); memset(differenceVector->dataVectors + differenceVector->numDataVectors, 0, sizeof(*differenceVector->dataVectors) * 8); } differenceVector->dataVectors[differenceVector->numDataVectors].dataBlock = i; /* block mismatched */ differenceVector->dataVectors[differenceVector->numDataVectors].dataBase = data - c; differenceVector->dataVectors[differenceVector->numDataVectors].dataSize = c; ++differenceVector->numDataVectors; vectorSize += c; } CL_ASSERT(dataSize == 0); if(lastMatch >= 0 && differenceVector) /* impossible but coverity killer : Who knows! */ { if(!(differenceVector->numDataVectors & 7)) { differenceVector->dataVectors = (ClDataVectorT*) clHeapRealloc(differenceVector->dataVectors, sizeof(*differenceVector->dataVectors) * (differenceVector->numDataVectors + 8)); CL_ASSERT(differenceVector->dataVectors != NULL); memset(differenceVector->dataVectors + differenceVector->numDataVectors, 0, sizeof(*differenceVector->dataVectors) * 8); } clLogTrace("DIFF", "MD5", "Copying block [%d] to replica of size [%lld]", lastMatch, lastDataSize); differenceVector->dataVectors[differenceVector->numDataVectors].dataBlock = lastMatch; differenceVector->dataVectors[differenceVector->numDataVectors].dataBase = pLastData; differenceVector->dataVectors[differenceVector->numDataVectors].dataSize = lastDataSize; ++differenceVector->numDataVectors; vectorSize += lastDataSize; } if(differenceVector) { clLogTrace("DIFF", "MD5", "Vector has [%lld] bytes to be written. Skipped [%lld] bytes.", vectorSize, sectionSize - vectorSize); } out_set: block->md5List = md5List; block->md5Blocks = md5Blocks; if(doMD5 && differenceVector) { clLogTrace("DIFF", "MD5", "Copying md5 list preloaded with [%d] blocks to the difference vector " "with [%d] data difference vectors", dataBlocks, differenceVector->numDataVectors); if(differenceVector->md5List) clHeapFree(differenceVector->md5List); differenceVector->md5List = (ClMD5T*) clHeapCalloc(dataBlocks, sizeof(*differenceVector->md5List)); CL_ASSERT(differenceVector->md5List != NULL); memcpy(differenceVector->md5List, md5List + startBlock, sizeof(*differenceVector->md5List) * dataBlocks); differenceVector->md5Blocks = dataBlocks; } if(md5CurList != md5List) clHeapFree(md5CurList); return sectionBlocks; }
ClRcT clBackingStorageReadWalkFile(ClBackingStorageHandleT handle, ClBackingStorageCallbackT pCallback, ClPtrT pArg, ClUint32T readSize, ClPtrT pPrivateData) { ClBackingStorageAttributesFileT *pAttr = (ClBackingStorageAttributesFileT *) pPrivateData; ClCharT data[0xffff+1]; ClSizeT size = 0; ClOffsetT curOffset = 0; struct stat st = {0}; ClRcT rc = CL_BACKING_STORAGE_RC(CL_ERR_LIBRARY); if(fstat(pAttr->fd, &st) < 0) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READW_FILE, "stat error [%s]", strerror(errno)); goto out; } if(!st.st_size) { rc = CL_OK; clLogWarning(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READW_FILE, "File [%s] size is empty", pAttr->baseAttr.location); goto out; } curOffset = lseek(pAttr->fd, 0, SEEK_CUR); if(curOffset < 0) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READW_FILE, "lseek error [%s]", strerror(errno)); goto out; } if(lseek(pAttr->fd, 0, SEEK_SET) < 0) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READW_FILE, "lseek error [%s]", strerror(errno)); goto out; } size = st.st_size; while(size > 0) { ClInt32T err = 0; ClCharT *pData = data; ClInt32T chunkSize = CL_MIN((ClInt32T)sizeof(data), size); ClUint32T bytes = 0; if(readSize) { if(size < readSize) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READW_FILE, "Read walk error. Chunksize doesnt match readsize [%d]", chunkSize); goto out_restore; } chunkSize = readSize; pData = (ClCharT*) clHeapAllocate(chunkSize); if(!pData) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READW_FILE, "No memory"); goto out_restore; } } while(chunkSize > 0) { err = read(pAttr->fd, pData+bytes, chunkSize); if(err < 0) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READW_FILE, "read error [%s]", strerror(errno)); if(pData != data) { clHeapFree(pData); } goto out_restore; } bytes += err; chunkSize -= err; } rc = pCallback(handle, (ClPtrT)pData, bytes, pArg); if(rc != CL_OK) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READW_FILE, "readwalk callback error [%#x]", rc); if(pData != data) { clHeapFree(pData); } goto out_restore; } size -= bytes; } rc = CL_OK; out_restore: lseek(pAttr->fd, curOffset, SEEK_SET); out: return rc; }
ClRcT clBackingStorageReadVectorFile(ClBackingStorageHandleT handle, struct iovec **ppIOVec, ClUint32T *pNumVectors, ClOffsetT offset, ClUint32T readSize, ClPtrT pPrivateData) { ClBackingStorageAttributesFileT *pAttr = (ClBackingStorageAttributesFileT *) pPrivateData; ClRcT rc = CL_BACKING_STORAGE_RC(CL_ERR_LIBRARY); struct iovec *pIOVec = NULL; ClUint32T numVectors = 0; ClSizeT size = 0, n = 0; ClInt32T err =0 , i = 0; struct stat st; ClCharT **ppDataBlocks = NULL; ClOffsetT curOffset = 0; ClInt32T whence = SEEK_SET; ClInt32T lastBatchStart = 0; *ppIOVec = NULL; *pNumVectors = 0; if(readSize > 0x7fff) { rc = CL_BACKING_STORAGE_RC(CL_ERR_INVALID_PARAMETER); clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READV_FILE, "Invalid readSize [%d]", readSize); goto out; } if(fstat(pAttr->fd, &st)) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READV_FILE, "stat error [%s]", strerror(errno)); goto out; } size = st.st_size; if(!size) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READV_FILE, "File [%s] empty", pAttr->baseAttr.location); goto out; } if(offset != (ClOffsetT)-1) { curOffset = lseek(pAttr->fd, 0, SEEK_CUR); if(curOffset < 0) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READV_FILE, "lseek save error [%s]", strerror(errno)); goto out; } if(offset < 0 ) { size = -offset; whence = SEEK_END; } else { size -= offset; } if(lseek(pAttr->fd, offset, whence) < 0) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READV_FILE, "lseek error [%s]", strerror(errno)); goto out; } } if(readSize && (size % readSize)) { rc = CL_BACKING_STORAGE_RC(CL_ERR_INVALID_PARAMETER); clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READV_FILE, "File size [%lld] not a multiple of readsize [%d]", size, readSize); goto out_restore; } if(!readSize) { readSize = 0x3fff+1; } rc = CL_BACKING_STORAGE_RC(CL_ERR_NO_MEMORY); numVectors = size/readSize; if(( size % readSize)) ++numVectors; pIOVec = (struct iovec*) clHeapCalloc(numVectors, sizeof(*pIOVec)); if(!pIOVec) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READV_FILE, "No memory"); goto out_restore; } ppDataBlocks = (ClCharT**) clHeapCalloc(numVectors, sizeof(*ppDataBlocks)); if(!ppDataBlocks) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READV_FILE, "No memory"); goto out_restore; } for(i = 0; (i < (ClInt32T) numVectors) && (size > 0);++i) { ClUint32T bytes = CL_MIN(readSize, size); ppDataBlocks[i] = (ClCharT*) clHeapAllocate(bytes); if(!ppDataBlocks[i]) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READV_FILE, "No memory"); goto out_free; } pIOVec[i].iov_base = ppDataBlocks[i]; pIOVec[i].iov_len = bytes; size -= readSize; n += readSize; if((i+1 >= (ClInt32T)numVectors) || (readSize >= 0x3fff) || (n >= 0x3fff) ) { if(n >= 0x3fff) { n = 0; } err = readv(pAttr->fd, &pIOVec[lastBatchStart], i-lastBatchStart+1); if(err < 0) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READV_FILE, "readv error [%s]", strerror(errno)); goto out_restore; } lastBatchStart = i+1; } } *ppIOVec = pIOVec; *pNumVectors = numVectors; rc = CL_OK; goto out; out_restore: if(offset != (ClOffsetT)-1) { if(lseek(pAttr->fd, curOffset, SEEK_SET) < 0) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READV_FILE, "lseek error restoring back [%s]", strerror(errno)); } } out_free: { ClInt32T j; for(j = 0; j < i; ++j) clHeapFree(ppDataBlocks[j]); } if(pIOVec) clHeapFree(pIOVec); if(ppDataBlocks) clHeapFree(ppDataBlocks); out: return rc; }
ClRcT clBackingStorageWriteFile(ClBackingStorageHandleT handle, ClPtrT pData, ClUint32T size, ClOffsetT offset, ClPtrT pPrivateData) { ClBackingStorageAttributesFileT *pAttr = (ClBackingStorageAttributesFileT *) pPrivateData; ClRcT rc = CL_OK; ClInt32T err = 0; ClOffsetT curOffset = 0; ClInt32T whence = SEEK_SET; rc = CL_BACKING_STORAGE_RC(CL_ERR_LIBRARY); if( offset != (ClOffsetT)-1) { curOffset = lseek(pAttr->fd, 0, SEEK_CUR); if(curOffset < 0 ) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_WRITE_FILE, "File lseek save error [%s]", strerror(errno)); goto out; } if(offset < 0) { whence = SEEK_END; size = -offset; } else { size -= offset; } if(lseek(pAttr->fd, offset, whence) < 0) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_WRITE_FILE, "File lseek error [%s]", strerror(errno)); goto out; } } while(size > 0 ) { ClInt32T n = CL_MIN(size, 32768); err = write(pAttr->fd, pData, n); if(err < 0 ) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_WRITE_FILE, "Write error [%s]", strerror(errno)); if(offset != (ClOffsetT)-1) { if(lseek(pAttr->fd, curOffset, SEEK_SET) < 0) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_WRITE_FILE, "lseek error [%s] restoring back offset", strerror(errno)); } } goto out; } if(err != n) { clLogWarning(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_WRITE_FILE, "Write wrote [%d] bytes. Expected [%d] bytes", err, n); } size -= err; pData = (ClPtrT)((ClUint8T*)pData + err); } rc = CL_OK; out: return rc; }
static ClRcT clEoClientNotification(ClIocNotificationT *notification) { ClUint32T i; ClIocNotificationIdT event; ClIocNodeAddressT node; ClIocPortT port; ClEoCallbackRecT *pMatchedRecords = NULL; ClUint32T numMatchedRecs = 0; ClUint32T numRecs = 0; ClIocAddressT address = {{0}}; if(!notification) return CL_EO_RC(CL_ERR_INVALID_PARAMETER); event = ntohl(notification->id); node = ntohl(notification->nodeAddress.iocPhyAddress.nodeAddress); port = ntohl(notification->nodeAddress.iocPhyAddress.portId); if(event == CL_IOC_NODE_ARRIVAL_NOTIFICATION || event == CL_IOC_NODE_LINK_UP_NOTIFICATION || event == CL_IOC_NODE_LEAVE_NOTIFICATION || event == CL_IOC_NODE_LINK_DOWN_NOTIFICATION) { port = 0; } address.iocPhyAddress.nodeAddress = node; address.iocPhyAddress.portId = port; /* * db numRecs could change behind our back. Hence pre-fetching it * to have temp db allocations without the lock. */ clOsalMutexLock(&gpCallbackDb.lock); numRecs = gpCallbackDb.numRecs; clOsalMutexUnlock(&gpCallbackDb.lock); /* * Better to allocate without the lock. to reduce lock * granularity and give scope for further client registrations * in this window. */ pMatchedRecords = clHeapAllocate(sizeof(*pMatchedRecords) * numRecs); if(!pMatchedRecords) { CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Memory allocation error\n")); return CL_EO_RC(CL_ERR_NO_MEMORY); } clOsalMutexLock(&gpCallbackDb.lock); numRecs = CL_MIN(gpCallbackDb.numRecs, numRecs); for(i = 0; i < numRecs; i++) { if(gpCallbackDb.pDb[i] != NULL && (gpCallbackDb.pDb[i]->node == node || gpCallbackDb.pDb[i]->node == CL_IOC_BROADCAST_ADDRESS) && (!port || gpCallbackDb.pDb[i]->port == port || !gpCallbackDb.pDb[i]->port) ) { memcpy(&pMatchedRecords[numMatchedRecs++], gpCallbackDb.pDb[i], sizeof(*pMatchedRecords)); } } clOsalMutexUnlock(&gpCallbackDb.lock); for(i = 0; i < numMatchedRecs; ++i) { pMatchedRecords[i].pFunc(event, pMatchedRecords[i].pArg, &address); } clHeapFree(pMatchedRecords); return CL_OK; }
ClRcT clNodeCacheUpdate(ClIocNodeAddressT nodeAddress, ClUint32T version, ClUint32T capability, SaNameT *nodeName) { ClRcT rc = CL_OK; ClNodeCacheEntryT *entry; if(nodeAddress >= CL_IOC_MAX_NODES) return CL_ERR_INVALID_PARAMETER; rc = clOsalSemLock(gClNodeCacheSem); if (rc != CL_OK) { clLogError("CACHE", "SET", "Cannot update node cache; error taking lock"); return rc; } if(!gpClNodeCache) { clOsalSemUnlock(gClNodeCacheSem); clLogError("CACHE", "SET", "Cannot update node cache; not initialized"); return CL_ERR_NOT_INITIALIZED; } if(!CL_NODE_MAP_TEST(CL_NODE_CACHE_HEADER_BASE(gpClNodeCache)->nodeMap, nodeAddress)) { CL_NODE_MAP_SET(CL_NODE_CACHE_HEADER_BASE(gpClNodeCache)->nodeMap, nodeAddress); CL_NODE_CACHE_HEADER_BASE(gpClNodeCache)->currentNodes += 1; } entry = &CL_NODE_CACHE_ENTRY_BASE(gpClNodeCache)[nodeAddress]; if(version) entry->version = version; if(capability) entry->capability = capability; if(nodeName) { entry->nodeName[0] = 0; strncat(entry->nodeName, (const ClCharT*)nodeName->value, CL_MIN(nodeName->length, sizeof(entry->nodeName)-1)); } /* * Update node min version/address. */ if(version && (!CL_NODE_CACHE_HEADER_BASE(gpClNodeCache)->minVersion || version < CL_NODE_CACHE_HEADER_BASE(gpClNodeCache)->minVersion)) { CL_NODE_CACHE_HEADER_BASE(gpClNodeCache)->minVersion = version; CL_NODE_CACHE_HEADER_BASE(gpClNodeCache)->minVersionNode = nodeAddress; gClMinVersion = version; gClMinVersionNode = nodeAddress; } if (1) { ClNodeCacheEntryT temp; memcpy(&temp,entry,sizeof(ClNodeCacheEntryT)); clOsalSemUnlock(gClNodeCacheSem); /* I do not want to log inside the node cache sem lock because logging can block, esp if its going to stdout */ clLogInfo("CACHE", "SET", "Updating node cache entry for node [%d: %s] with version [%#x], capability [%#x] (%s,%s,%s)", nodeAddress, temp.nodeName, temp.version, temp.capability, CL_NODE_CACHE_LEADER_CAPABILITY(temp.capability) ? "LEADER":"_", CL_NODE_CACHE_SC_CAPABILITY(temp.capability) ? "Controller" : "_", CL_NODE_CACHE_SC_PROMOTE_CAPABILITY(temp.capability) ? "Controller-promotable" : "_" ); } return CL_OK; }