diff options
author | Ingo Huerner <ingo.huerner@xse.de> | 2014-11-29 04:10:45 +0100 |
---|---|---|
committer | Ingo Huerner <ingo.huerner@xse.de> | 2014-11-29 04:10:45 +0100 |
commit | 6309873db051fb8003ff07e1a54f5fc780544b62 (patch) | |
tree | dca5b62da5e534499efda5cb6a0460f9b5a8b52d | |
parent | c49dcb4cec30da626a31e35d17727c1038c10d92 (diff) | |
download | persistence-client-library-6309873db051fb8003ff07e1a54f5fc780544b62.tar.gz |
Implemented write configurable default data for files
-rw-r--r-- | src/persistence_client_library_file.c | 357 | ||||
-rw-r--r-- | src/persistence_client_library_handle.c | 27 | ||||
-rw-r--r-- | src/persistence_client_library_handle.h | 23 | ||||
-rw-r--r-- | test/persistence_client_library_test.c | 35 |
4 files changed, 280 insertions, 162 deletions
diff --git a/src/persistence_client_library_file.c b/src/persistence_client_library_file.c index 1776f99..c2c1417 100644 --- a/src/persistence_client_library_file.c +++ b/src/persistence_client_library_file.c @@ -43,10 +43,15 @@ #include <sys/sendfile.h> // local function prototype -int pclFileGetDefaultData(int handle, const char* resource_id, int policy); +static int pclFileGetDefaultData(int handle, const char* resource_id, int policy); +static int pclFileOpenDefaultData(PersistenceInfo_s* dbContext, const char* resource_id); +static int pclFileOpenRegular(PersistenceInfo_s* dbContext, const char* resource_id, + char* dbKey, char* dbPath, int shared_DB, unsigned int user_no, unsigned int seat_no); + extern int doAppcheck(void); + char* get_raw_string(char* dbKey) { char* keyPtr = NULL; @@ -69,6 +74,7 @@ char* get_raw_string(char* dbKey) } + int pclFileClose(int fd) { int rval = EPERS_NOT_INITIALIZED; @@ -188,182 +194,231 @@ void* pclFileMapData(void* addr, long size, long offset, int fd) } -int pclFileOpen(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no) + +int pclFileOpenRegular(PersistenceInfo_s* dbContext, const char* resource_id, char* dbKey, char* dbPath, int shared_DB, unsigned int user_no, unsigned int seat_no) { - int handle = EPERS_NOT_INITIALIZED; + int handle = -1; + int length = 0; - if(__sync_add_and_fetch(&gPclInitCounter, 0) > 0) + int wantBackup = 1; + int cacheStatus = -1; + + char fileSubPath[DbPathMaxLen] = {0}; + + char backupPath[DbPathMaxLen] = {0}; // backup file + char csumPath[DbPathMaxLen] = {0}; // checksum file + + if(dbContext->configKey.policy == PersistencePolicy_wc) { - int shared_DB = 0; - int wantBackup = 1; - int cacheStatus = -1; - PersistenceInfo_s dbContext; + length = gCPathPrefixSize; + } + else + { + length = gWTPathPrefixSize; + } - char dbKey[DbKeyMaxLen] = {0}; // database key - char dbPath[DbPathMaxLen] = {0}; // database location - char backupPath[DbPathMaxLen] = {0}; // backup file - char csumPath[DbPathMaxLen] = {0}; // checksum file + strncpy(fileSubPath, dbPath+length, DbPathMaxLen); + snprintf(backupPath, DbPathMaxLen-1, "%s%s%s", gBackupPrefix, fileSubPath, gBackupPostfix); + snprintf(csumPath, DbPathMaxLen-1, "%s%s%s", gBackupPrefix, fileSubPath, gBackupCsPostfix); - //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclFileOpen: "), DLT_INT(ldbid), DLT_STRING(resource_id) ); + // + // check valid database context + // + if(shared_DB >= 0) + { + int flags = pclGetPosixPermission(dbContext->configKey.permission); - dbContext.context.ldbid = ldbid; - dbContext.context.seat_no = seat_no; - dbContext.context.user_no = user_no; + // file will be opened writable, so check about data consistency + if( (dbContext->configKey.permission != PersistencePermission_ReadOnly) + && (pclBackupNeeded(get_raw_string(dbKey)) == CREATE_BACKUP)) + { + wantBackup = 0; + if((handle = pclVerifyConsistency(dbPath, backupPath, csumPath, flags)) == -1) + { + DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclFileOpen - file inconsistent, recovery N O T possible!")); + return -1; + } + } + else + { + if(dbContext->configKey.permission == PersistencePermission_ReadOnly) + DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclFileOpen: No Backup - file is READ ONLY!"), DLT_STRING(dbKey)); + else + DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclFileOpen: No Backup - file is in backup blacklist!"), DLT_STRING(dbKey)); + } - // get database context: database path and database key - shared_DB = get_db_context(&dbContext, resource_id, ResIsFile, dbKey, dbPath); +#if USE_FILECACHE + if(handle > 0) // when the file is open, close it and do a new open unde PFC control + { + close(handle); + } + if(strstr(dbPath, WTPREFIX) != NULL) + { + // if it's a write through resource, add the O_SYNC and O_DIRECT flag to prevent caching + handle = open(dbPath, flags); + cacheStatus = 0; + } + else + { + handle = pfcOpenFile(dbPath, DontCreateFile); + cacheStatus = 1; + } + +#else + if(handle <= 0) // check if open is needed or already done in verifyConsistency + { + handle = open(dbPath, flags); + + if(strstr(dbPath, WTPREFIX) != NULL) + { + cacheStatus = 0; + } + else + { + cacheStatus = 1; + } + } +#endif // - // check if the resource is marked as a file resource + // file does not exist, create it and get default data // - if(dbContext.configKey.type == PersistenceResourceType_file) + if(handle == -1 && errno == ENOENT) { - // create backup path - int length = 0; - char fileSubPath[DbPathMaxLen] = {0}; - - if(dbContext.configKey.policy == PersistencePolicy_wc) + if((handle = pclCreateFile(dbPath, cacheStatus)) == -1) { - length = gCPathPrefixSize; + DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclFileOpen - failed to create file: "), DLT_STRING(dbPath)); } else { - length = gWTPathPrefixSize; + if(pclFileGetDefaultData(handle, resource_id, dbContext->configKey.policy) == -1) // try to get default data + { + DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("pclFileOpen - no default data available: "), DLT_STRING(resource_id)); + } } - strncpy(fileSubPath, dbPath+length, DbPathMaxLen); - snprintf(backupPath, DbPathMaxLen-1, "%s%s%s", gBackupPrefix, fileSubPath, gBackupPostfix); - snprintf(csumPath, DbPathMaxLen-1, "%s%s%s", gBackupPrefix, fileSubPath, gBackupCsPostfix); + set_file_cache_status(handle, cacheStatus); + } - // - // check valid database context - // - if(shared_DB >= 0) + if(dbContext->configKey.permission != PersistencePermission_ReadOnly) + { + if(set_file_handle_data(handle, dbContext->configKey.permission, backupPath, csumPath, NULL) != -1) { - int flags = pclGetPosixPermission(dbContext.configKey.permission); + set_file_backup_status(handle, wantBackup); + __sync_fetch_and_add(&gOpenFdArray[handle], FileOpen); // set open flag + } + else + { + close(handle); + handle = EPERS_MAXHANDLE; + } + } + else + { + if(set_file_handle_data(handle, dbContext->configKey.permission, backupPath, csumPath, NULL) == -1) + { + close(handle); + handle = EPERS_MAXHANDLE; + } + } + } + // + // requested resource is not in the RCT, so create resource as local/cached. + // + else + { + // assemble file string for local cached location + snprintf(dbPath, DbPathMaxLen, gLocalCacheFilePath, gAppId, user_no, seat_no, resource_id); + handle = pclCreateFile(dbPath, 1); + set_file_cache_status(handle, 1); - // file will be opened writable, so check about data consistency - if( (dbContext.configKey.permission != PersistencePermission_ReadOnly) - && (pclBackupNeeded(get_raw_string(dbKey)) == CREATE_BACKUP)) - { - wantBackup = 0; - if((handle = pclVerifyConsistency(dbPath, backupPath, csumPath, flags)) == -1) - { - DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclFileOpen - file inconsistent, recovery N O T possible!")); - return -1; - } - } - else - { - if(dbContext.configKey.permission == PersistencePermission_ReadOnly) - DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclFileOpen: No Backup - file is READ ONLY!"), DLT_STRING(dbKey)); - else - DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclFileOpen: No Backup - file is in backup blacklist!"), DLT_STRING(dbKey)); + if(handle != -1) + { + if(set_file_handle_data(handle, PersistencePermission_ReadWrite, backupPath, csumPath, NULL) != -1) + { + set_file_backup_status(handle, 1); + __sync_fetch_and_add(&gOpenFdArray[handle], FileOpen); // set open flag + } + else + { +#if USE_FILECACHE + pfcCloseFile(handle); +#else + close(handle); +#endif + handle = EPERS_MAXHANDLE; + } + } + } - } + return handle; +} -#if USE_FILECACHE - if(handle > 0) // when the file is open, close it and do a new open unde PFC control - { - close(handle); - } - if(strstr(dbPath, WTPREFIX) != NULL) - { - // if it's a write through resource, add the O_SYNC and O_DIRECT flag to prevent caching - handle = open(dbPath, flags); - cacheStatus = 0; - } - else - { - handle = pfcOpenFile(dbPath, DontCreateFile); - cacheStatus = 1; - } -#else - if(handle <= 0) // check if open is needed or already done in verifyConsistency - { - handle = open(dbPath, flags); +int pclFileOpenDefaultData(PersistenceInfo_s* dbContext, const char* resource_id) +{ + int flags = pclGetPosixPermission(dbContext->configKey.permission); - if(strstr(dbPath, WTPREFIX) != NULL) - { - cacheStatus = 0; - } - else - { - cacheStatus = 1; - } - } -#endif - // - // file does not exist, create it and get default data - // - if(handle == -1 && errno == ENOENT) - { - if((handle = pclCreateFile(dbPath, cacheStatus)) == -1) - { - DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclFileOpen - failed to create file: "), DLT_STRING(dbPath)); - } - else - { - if(pclFileGetDefaultData(handle, resource_id, dbContext.configKey.policy) == -1) // try to get default data - { - DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("pclFileOpen - no default data available: "), DLT_STRING(resource_id)); - } - } + // check if there is default data available + char pathPrefix[DbPathMaxLen] = { [0 ... DbPathMaxLen-1] = 0}; + char defaultPath[DbPathMaxLen] = { [0 ... DbPathMaxLen-1] = 0}; - set_file_cache_status(handle, cacheStatus); - } + // create path to default data + if(dbContext->configKey.policy == PersistencePolicy_wc) + { + snprintf(pathPrefix, DbPathMaxLen, gLocalCachePath, gAppId); + } + else if(dbContext->configKey.policy == PersistencePolicy_wt) + { + snprintf(pathPrefix, DbPathMaxLen, gLocalWtPath, gAppId); + } - if(dbContext.configKey.permission != PersistencePermission_ReadOnly) - { - if(set_file_handle_data(handle, dbContext.configKey.permission, backupPath, csumPath, NULL) != -1) - { - set_file_backup_status(handle, wantBackup); - __sync_fetch_and_add(&gOpenFdArray[handle], FileOpen); // set open flag - } - else - { - close(handle); - handle = EPERS_MAXHANDLE; - } - } - else - { - if(set_file_handle_data(handle, dbContext.configKey.permission, backupPath, csumPath, NULL) == -1) - { - close(handle); - handle = EPERS_MAXHANDLE; - } - } + // first check for c o n f i g u r a b l e default data + snprintf(defaultPath, DbPathMaxLen, "%s%s/%s", pathPrefix, PERS_ORG_CONFIG_DEFAULT_DATA_FOLDER_NAME_, resource_id); + + printf("The conf default path: %s\n", defaultPath); + + return open(defaultPath, flags); +} + + + +int pclFileOpen(unsigned int ldbid, const char* resource_id, unsigned int user_no, unsigned int seat_no) +{ + int handle = EPERS_NOT_INITIALIZED; + + if(__sync_add_and_fetch(&gPclInitCounter, 0) > 0) + { + PersistenceInfo_s dbContext; + + int shared_DB = 0; + + char dbKey[DbKeyMaxLen] = {0}; // database key + char dbPath[DbPathMaxLen] = {0}; // database location + + //DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclFileOpen: "), DLT_INT(ldbid), DLT_STRING(resource_id) ); + + dbContext.context.ldbid = ldbid; + dbContext.context.seat_no = seat_no; + dbContext.context.user_no = user_no; + + // get database context: database path and database key + shared_DB = get_db_context(&dbContext, resource_id, ResIsFile, dbKey, dbPath); + + // + // check if the resource is marked as a file resource + // + if(dbContext.configKey.type == PersistenceResourceType_file) + { + if(user_no == PCL_USER_DEFAULTDATA) + { + handle = pclFileOpenDefaultData(&dbContext, resource_id); + set_file_user_id(handle, PCL_USER_DEFAULTDATA); } - // - // requested resource is not in the RCT, so create resource as local/cached. - // else { - // assemble file string for local cached location - snprintf(dbPath, DbPathMaxLen, gLocalCacheFilePath, gAppId, user_no, seat_no, resource_id); - handle = pclCreateFile(dbPath, 1); - set_file_cache_status(handle, 1); - - if(handle != -1) - { - if(set_file_handle_data(handle, PersistencePermission_ReadWrite, backupPath, csumPath, NULL) != -1) - { - set_file_backup_status(handle, 1); - __sync_fetch_and_add(&gOpenFdArray[handle], FileOpen); // set open flag - } - else - { -#if USE_FILECACHE - pfcCloseFile(handle); -#else - close(handle); -#endif - handle = EPERS_MAXHANDLE; - } - } + handle = pclFileOpenRegular(&dbContext, resource_id, dbKey, dbPath, shared_DB, user_no, seat_no); } } else @@ -385,7 +440,7 @@ int pclFileReadData(int fd, void * buffer, int buffer_size) if(__sync_add_and_fetch(&gPclInitCounter, 0) > 0) { #if USE_FILECACHE - if(get_file_cache_status(fd) == 1) + if(get_file_cache_status(fd) == 1 && get_file_user_id(fd) != PCL_USER_DEFAULTDATA) { readSize = pfcReadFile(fd, buffer, buffer_size); } @@ -521,10 +576,10 @@ int pclFileWriteData(int fd, const void * buffer, int buffer_size) int permission = get_file_permission(fd); if(permission != -1) { - if(permission != PersistencePermission_ReadOnly) + if(permission != PersistencePermission_ReadOnly ) { // check if a backup file has to be created - if(get_file_backup_status(fd) == 0) + if(get_file_backup_status(fd) == 0 && get_file_user_id(fd) != PCL_USER_DEFAULTDATA) { char csumBuf[ChecksumBufSize] = {0}; @@ -538,7 +593,7 @@ int pclFileWriteData(int fd, const void * buffer, int buffer_size) } #if USE_FILECACHE - if(get_file_cache_status(fd) == 1) + if(get_file_cache_status(fd) == 1 && get_file_user_id(fd) != PCL_USER_DEFAULTDATA) { size = pfcWriteFile(fd, buffer, buffer_size); } diff --git a/src/persistence_client_library_handle.c b/src/persistence_client_library_handle.c index 6950c4d..4ba7462 100644 --- a/src/persistence_client_library_handle.c +++ b/src/persistence_client_library_handle.c @@ -197,6 +197,7 @@ int set_file_handle_data(int idx, PersistencePermission_e permission, const char gFileHandleArray[idx].permission = permission; gFileHandleArray[idx].filePath = filePath; // check to do if this works gFileHandleArray[idx].cacheStatus = -1; // set to -1 by default + gFileHandleArray[idx].userId = 0; // default value } pthread_mutex_unlock(&gFileHandleAccessMtx); } @@ -274,6 +275,32 @@ int get_file_cache_status(int idx) } return status; } + + +void set_file_user_id(int idx, int userID) +{ + if(pthread_mutex_lock(&gFileHandleAccessMtx) == 0) + { + gFileHandleArray[idx].userId = userID; + + pthread_mutex_unlock(&gFileHandleAccessMtx); + } +} + +int get_file_user_id(int idx) +{ + int id = -1; + if(pthread_mutex_lock(&gFileHandleAccessMtx) == 0) + { + if(MaxPersHandle >= idx) + { + id = gFileHandleArray[idx].userId; + } + pthread_mutex_unlock(&gFileHandleAccessMtx); + } + return id; +} + //---------------------------------------------------------- //---------------------------------------------------------- diff --git a/src/persistence_client_library_handle.h b/src/persistence_client_library_handle.h index 48ab055..f0db145 100644 --- a/src/persistence_client_library_handle.h +++ b/src/persistence_client_library_handle.h @@ -47,6 +47,8 @@ typedef struct _PersistenceFileHandle_s int backupCreated; /// flag to indicate if file must be cached int cacheStatus; + /// the user id + int userId; /// path to the backup file char backupPath[DbPathMaxLen]; /// path to the checksum file @@ -221,6 +223,27 @@ void set_file_cache_status(int idx, int status); * 1 if file must be cached */ int get_file_cache_status(int idx); + + +/** + * @brief set the user id + * @attention "No index check will be done" + * + * @param idx the index + * @param userID the user id + */ +void set_file_user_id(int idx, int userID); + + +/** + * @brief get the user id of the file + * @attention "No index check will be done" + * + * @param idx the index + * + * @return the user id + */ +int get_file_user_id(int idx); //---------------------------------------------------------------- //---------------------------------------------------------------- diff --git a/test/persistence_client_library_test.c b/test/persistence_client_library_test.c index 98fd2c1..aedd150 100644 --- a/test/persistence_client_library_test.c +++ b/test/persistence_client_library_test.c @@ -768,7 +768,7 @@ END_TEST START_TEST(test_DataFileConfDefault) { - int fd = 0, ret = 0; + int fd = 0; char readBuffer[READ_SIZE] = {0}; char* refBuffer01 = "Some default file content: 01 Configurable default data 01."; char* refBuffer02 = "Some default file content: 02 Configurable default data 02."; @@ -776,21 +776,16 @@ START_TEST(test_DataFileConfDefault) // -- file interface --- memset(readBuffer, 0, READ_SIZE); fd = pclFileOpen(PCL_LDBID_LOCAL, "media/mediaData_01.configurable", 99, 99); - ret = pclFileReadData(fd, readBuffer, READ_SIZE); - printf("Size: %d - Soll:%d\n", ret, strlen(refBuffer01)); - printf("READ BUFFER: \"%s\"\n", readBuffer); + (void)pclFileReadData(fd, readBuffer, READ_SIZE); fail_unless(strncmp(readBuffer, refBuffer01, strlen(refBuffer01)) == 0, "Buffer not correctly read => mediaData_01.configurable"); - - ret = pclFileClose(fd); + (void)pclFileClose(fd); memset(readBuffer, 0, READ_SIZE); fd = pclFileOpen(PCL_LDBID_LOCAL, "media/mediaData_02.configurable", 99, 99); - ret = pclFileReadData(fd, readBuffer, READ_SIZE); + (void)pclFileReadData(fd, readBuffer, READ_SIZE); fail_unless(strncmp(readBuffer, refBuffer02, strlen(refBuffer02)) == 0, "Buffer not correctly read => mediaData_01.configurable"); - - printf("READ BUFFER: %s\n", readBuffer); - ret = pclFileClose(fd); + (void)pclFileClose(fd); } END_TEST @@ -1255,7 +1250,7 @@ START_TEST(test_WriteConfDefault) X_TEST_REPORT_DESCRIPTION("Write configurable default data"); X_TEST_REPORT_TYPE(GOOD); */ - int ret = 0; + int ret = 0, fd = 0; unsigned char writeBuffer[] = "This is a test string"; unsigned char writeBuffer2[] = "And this is a test string which is different form previous test string"; unsigned char readBuffer[READ_SIZE] = {0}; @@ -1276,6 +1271,24 @@ START_TEST(test_WriteConfDefault) fail_unless(strncmp((char*)readBuffer, (char*)writeBuffer2, strlen((char*)readBuffer)) == 0, "Buffer2 not correctly read"); //printf(" --- test_ReadConfDefault => statusHandle/writeconfdefault01: \"%s\" => \"%s\" \n retIst: %d retSoll: %d\n", readBuffer, writeBuffer2, ret, strlen((char*)writeBuffer2)); + + // -- file interface --- + memset(readBuffer, 0, READ_SIZE); + fd = pclFileOpen(PCL_LDBID_LOCAL, "media/mediaData.configurable", PCL_USER_DEFAULTDATA, 99); + ret = pclFileWriteData(fd, writeBuffer, strlen((char*)writeBuffer)); + pclFileSeek(fd, 0, SEEK_SET); + ret = pclFileReadData(fd, readBuffer, READ_SIZE); + fail_unless(strncmp((char*)readBuffer, (char*)writeBuffer, strlen((char*)writeBuffer)) == 0, "Buffer not correctly read"); + (void)pclFileClose(fd); + + memset(readBuffer, 0, READ_SIZE); + fd = pclFileOpen(PCL_LDBID_LOCAL, "media/mediaData.configurable", PCL_USER_DEFAULTDATA, 99); + ret = pclFileWriteData(fd, writeBuffer2, strlen((char*)writeBuffer2)); + pclFileSeek(fd, 0, SEEK_SET); + ret = pclFileReadData(fd, readBuffer, READ_SIZE); + fail_unless(strncmp((char*)readBuffer, (char*)writeBuffer2, strlen((char*)writeBuffer2)) == 0, "Buffer2 not correctly read"); + (void)pclFileClose(fd); + } END_TEST |