Exemplo n.º 1
0
/*
 * Update shared with a new cache.
 * This function checks
 *     if new cache has a newer timestamp than the shared cache and updates,
 * 		   then the updateTS of the shared cache before it starts to update the cached data.
 * 		   else return.
 * 	   except when the processType is RULE_ENGINE_INIT_CACHE, which means that the share caches has not been initialized.
 * 		   or when the processType is RULE_ENGINE_REFRESH_CACHE, which means that we want to refresh the cache with the new cache.
 * It prepares the data in the new cache for copying into the shared cache.
 * It checks the timestamp again and does the actually copying.
 */
int updateCache( const char* _inst_name, size_t size, Cache *cache ) {
        unsigned char *buf = ( unsigned char * ) malloc( size );
        if ( buf != NULL ) {
            int ret;
            unsigned char *cacheBuf = buf;
            Cache *cacheCopy = copyCache( &cacheBuf, size, cache );
            if ( cacheCopy != NULL ) {
#ifdef DEBUG
                printf( "Buffer usage: %fM\n", ( ( double )( cacheCopy->dataSize ) ) / ( 1024 * 1024 ) );
#endif
                size_t pointersSize = ( cacheCopy->address + cacheCopy->cacheSize ) - cacheCopy->pointers;
                mutex_type *mutex;
                lockWriteMutex(_inst_name, &mutex);
                unsigned char *shared = prepareServerSharedMemory( _inst_name );
                if (shared == NULL) {
                    ret = -1;
                } else {
                    long diff = shared - cacheCopy->address;
                    unsigned char *pointers = cacheCopy->pointers;

                    applyDiff( pointers, pointersSize, diff, 0 );
                    applyDiffToPointers( pointers, pointersSize, diff );

                    memset( shared, 0, SHMMAX );
                    /* copy data */
                    memcpy( shared, buf, cacheCopy->dataSize );
                    /* copy pointers */
                    memcpy( cacheCopy->pointers, pointers, pointersSize );
                    ret = 0;
                    detachSharedMemory( _inst_name );
                }
                unlockWriteMutex(_inst_name, &mutex);
            }
            else {
                rodsLog( LOG_ERROR, "Error updating cache." );
                ret = -1;
            }
            free( buf );
            return ret;
        }
        else {
            rodsLog( LOG_ERROR, "Cannot update cache because of out of memory error, let some other process update it later when memory is available." );
            return -1;
        }

}
Exemplo n.º 2
0
int loadRuleFromCacheOrFile( int processType, char *irbSet, ruleStruct_t *inRuleStruct ) {
    char r1[NAME_LEN], r2[RULE_SET_DEF_LENGTH], r3[RULE_SET_DEF_LENGTH];
    snprintf( r2, sizeof( r2 ), "%s", irbSet );
    int res = 0;

#ifdef DEBUG
    /*Cache *cache;*/
#endif

    /* get max timestamp */
    char fn[MAX_NAME_LEN];
    time_type timestamp = time_type_initializer, mtim;
    while ( strlen( r2 ) > 0 ) {
        rSplitStr( r2, r1, NAME_LEN, r3, RULE_SET_DEF_LENGTH, ',' );
        getRuleBasePath( r1, fn );
        if ( ( res = getModifiedTime( fn, &mtim ) ) != 0 ) {
            return res;
        }
        if ( time_type_gt( mtim, timestamp ) ) {
            time_type_set( timestamp, mtim );
        }
        snprintf( r2, sizeof( r2 ), "%s", r3 );
    }
    snprintf( r2, sizeof( r2 ), "%s", irbSet );

#ifdef CACHE_ENABLE

    int update = 0;
    unsigned char *buf = NULL;
    /* try to find shared memory cache */
    if ( processType == RULE_ENGINE_TRY_CACHE && inRuleStruct == &coreRuleStrct ) {
        buf = prepareNonServerSharedMemory();
        if ( buf != NULL ) {
            Cache * cache = restoreCache( buf );
            detachSharedMemory();

            if ( cache == NULL ) {
                rodsLog( LOG_ERROR, "Failed to restore cache." );
            }
            else {
                int diffIrbSet = strcmp( cache->ruleBase, irbSet ) != 0;
                if ( diffIrbSet ) {
                    rodsLog( LOG_DEBUG, "Rule base set changed, old value is %s", cache->ruleBase );
                }

                if ( diffIrbSet || time_type_gt( timestamp, cache->timestamp ) ) {
                    update = 1;
                    free( cache->address );
                    rodsLog( LOG_DEBUG, "Rule base set or rule files modified, force refresh." );
                }
                else {

                    cache->cacheStatus = INITIALIZED;
                    ruleEngineConfig = *cache;
                    /* generate extRuleSet */
                    generateRegions();
                    generateRuleSets();
                    generateFunctionDescriptionTables();
                    if ( inRuleStruct == &coreRuleStrct && ruleEngineConfig.ruleEngineStatus == UNINITIALIZED ) {
                        getSystemFunctions( ruleEngineConfig.sysFuncDescIndex->current, ruleEngineConfig.sysRegion );
                    }
                    /* ruleEngineConfig.extRuleSetStatus = LOCAL;
                    ruleEngineConfig.extFuncDescIndexStatus = LOCAL; */
                    /* createRuleIndex(inRuleStruct); */
                    ruleEngineConfig.ruleEngineStatus = INITIALIZED;
                    //free( cache );
                    return res;
                }
            }
            //free( cache );
        }
        else {
            rodsLog( LOG_DEBUG, "Cannot open shared memory." );
        }
    }
#endif

    if ( ruleEngineConfig.ruleEngineStatus == INITIALIZED ) {
        /* Reloading rule set, clear previously generated rule set */
        unlinkFuncDescIndex();
        clearRuleIndex( inRuleStruct );
    }

    generateRegions();
    generateRuleSets();
    generateFunctionDescriptionTables();
    if ( inRuleStruct == &coreRuleStrct && ruleEngineConfig.ruleEngineStatus == UNINITIALIZED ) {
        getSystemFunctions( ruleEngineConfig.sysFuncDescIndex->current, ruleEngineConfig.sysRegion );
    }
    /*ruleEngineConfig.extRuleSetStatus = LOCAL;
    ruleEngineConfig.extFuncDescIndexStatus = LOCAL;*/
    while ( strlen( r2 ) > 0 ) {
        int i = rSplitStr( r2, r1, NAME_LEN, r3, RULE_SET_DEF_LENGTH, ',' );
        if ( i == 0 ) {
            i = readRuleStructAndRuleSetFromFile( r1, inRuleStruct );
        }
#ifdef DEBUG
        printf( "%d rules in core rule set\n", ruleEngineConfig.coreRuleSet->len );
#endif
        if ( i != 0 ) {
            res = i;
            ruleEngineConfig.ruleEngineStatus = INITIALIZED;
            return res;
        }
        snprintf( r2, sizeof( r2 ), "%s", r3 );
    }

    createRuleIndex( inRuleStruct );
    /* set max timestamp */
    time_type_set( ruleEngineConfig.timestamp, timestamp );
    snprintf( ruleEngineConfig.ruleBase, sizeof( ruleEngineConfig.ruleBase ), "%s", irbSet );

#ifdef CACHE_ENABLE
    if ( ( processType == RULE_ENGINE_INIT_CACHE || update ) && inRuleStruct == &coreRuleStrct ) {
        unsigned char *shared = prepareServerSharedMemory();

        if ( shared != NULL ) {
            int ret = updateCache( shared, SHMMAX, &ruleEngineConfig, processType );
            detachSharedMemory();
            if ( ret != 0 ) {
                removeSharedMemory();
            }
        }
        else {
            rodsLog( LOG_ERROR, "Cannot open shared memory." );
        }
    }
#endif

    ruleEngineConfig.ruleEngineStatus = INITIALIZED;

    return res;
}
Exemplo n.º 3
0
/*
 * Restore a Cache struct from buf into a malloc'd buffer.
 * This function returns NULL if failed to acquire or release the mutex.
 * It first create a local copy of buf's data section and pointer pointers section. This part needs synchronization.
 * Then it works on its local copy, which does not need synchronization.
 */
Cache *restoreCache( const char* _inst_name ) {
    mutex_type *mutex;
    lockReadMutex(_inst_name, &mutex);
    unsigned char *buf = prepareNonServerSharedMemory( _inst_name );
    if (buf == NULL) {
        return NULL;
    }
    Cache *cache = ( Cache * ) buf;
    unsigned char *bufCopy;
    unsigned char *pointers;
    size_t pointersSize;
    unsigned char *bufMapped;

    unsigned char *pointersCopy;
    unsigned char *pointersMapped;
    size_t dataSize;
    dataSize = cache->dataSize;
    bufCopy = ( unsigned char * )malloc( dataSize );
    if ( bufCopy == NULL ) {
        rodsLog( LOG_ERROR, "Cannot allocate object buffer of size %lld" , dataSize);
        unlockReadMutex(_inst_name, &mutex);
        return NULL;
    }
    memcpy( bufCopy, buf, cache->dataSize );
    Cache *cacheCopy = ( Cache * ) bufCopy;
    pointersMapped = cacheCopy->pointers;
    bufMapped = cacheCopy->address;
    pointersSize = bufMapped + SHMMAX - pointersMapped;
    pointersCopy = ( unsigned char * )malloc( pointersSize );
    if ( pointersCopy == NULL ) {
        free( bufCopy );
        rodsLog( LOG_ERROR, "Cannot allocate pointer pointer buffer of size %lld", pointersSize);
        detachSharedMemory( _inst_name );
        unlockReadMutex(_inst_name, &mutex);
        return NULL;
    }
    memcpy( pointersCopy, pointersMapped + ( buf - bufMapped ), pointersSize );
    detachSharedMemory( _inst_name );
    unlockReadMutex(_inst_name, &mutex);
    pointers = pointersCopy;
    /*    bufCopy = (unsigned char *)malloc(cache->dataSize);

        if(bufCopy == NULL) {
            return NULL;
        }
        memcpy(bufCopy, buf, cache->dataSize);

        bufMapped = cache->address;

        long diffBuf = buf - bufMapped;
        pointers = cache->pointers + diffBuf;
        pointersSize = pointers - buf; */
    long diff = bufCopy - bufMapped;
    long pointerDiff = diff;
    applyDiff( pointers, pointersSize, diff, pointerDiff );
    free( pointersCopy );

#ifdef RE_CACHE_CHECK
    Hashtable *objectMap = newHashTable( 100 );
    cacheChkEnv( cacheCopy->coreFuncDescIndex, cacheCopy, ( CacheChkFuncType * ) cacheChkNode, objectMap );
    cacheChkRuleSet( cacheCopy->coreRuleSet, cacheCopy, objectMap );
#endif
    return cacheCopy;
}