diff options
author | Ingo Huerner <ingo.huerner@xse.de> | 2014-01-24 14:33:15 +0100 |
---|---|---|
committer | Ingo Huerner <ingo.huerner@xse.de> | 2014-01-24 14:33:15 +0100 |
commit | a756aac7ed08de6ab876fbfe88a46b07360a8922 (patch) | |
tree | 89a878740546cf464cfeaf8094fe364df7c3366d /src | |
parent | bdca9b7b7fabd6f6a6506a33b39c1a6d1a667703 (diff) | |
download | persistence-client-library-a756aac7ed08de6ab876fbfe88a46b07360a8922.tar.gz |
File backups on seperate partition; Fixed bug 146; created performance benchmark; minor optimization; disabled PAS interface by default, to enable use configure --enable-pasinterface
Diffstat (limited to 'src')
-rw-r--r-- | src/persistence_client_library.c | 22 | ||||
-rw-r--r-- | src/persistence_client_library_backup_filelist.c | 457 | ||||
-rw-r--r-- | src/persistence_client_library_backup_filelist.h | 68 | ||||
-rw-r--r-- | src/persistence_client_library_custom_loader.h | 4 | ||||
-rw-r--r-- | src/persistence_client_library_data_organization.c | 39 | ||||
-rw-r--r-- | src/persistence_client_library_db_access.c | 28 | ||||
-rw-r--r-- | src/persistence_client_library_dbus_cmd.c | 23 | ||||
-rw-r--r-- | src/persistence_client_library_dbus_service.c | 13 | ||||
-rw-r--r-- | src/persistence_client_library_file.c | 493 | ||||
-rw-r--r-- | src/persistence_client_library_key.c | 1 | ||||
-rw-r--r-- | src/persistence_client_library_prct_access.c | 2 | ||||
-rw-r--r-- | src/persistence_client_library_prct_access.h | 4 |
12 files changed, 636 insertions, 518 deletions
diff --git a/src/persistence_client_library.c b/src/persistence_client_library.c index ac1c830..34c13ac 100644 --- a/src/persistence_client_library.c +++ b/src/persistence_client_library.c @@ -66,6 +66,15 @@ int pclInitLibrary(const char* appName, int shutdownMode) /// blacklist path environment variable const char *pBlacklistPath = getenv("PERS_BLACKLIST_PATH"); +#if USE_PASINTERFACE == 1 + //printf("* ADMIN INTERFACE is - e n a b l e d - \n"); + DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("PAS interface is enabled!!")); +#else + //printf("* ADMIN INTERFACE is - d i s a b l e d - enable with \"./configure --enable-pasinterface\"\n"); + DLT_LOG(gDLTContext, DLT_LOG_WARN, DLT_STRING("PAS interface is not enabled, enable with \"./configure --enable-pasinterface\"")); +#endif + + pthread_mutex_lock(&gDbusPendingRegMtx); // block until pending received if(pDataSize != NULL) @@ -90,6 +99,7 @@ int pclInitLibrary(const char* appName, int shutdownMode) return EPERS_DBUS_MAINLOOP; } + if(gShutdownMode != PCL_SHUTDOWN_TYPE_NONE) { // register for lifecycle and persistence admin service dbus messages @@ -100,13 +110,14 @@ int pclInitLibrary(const char* appName, int shutdownMode) return EPERS_REGISTER_LIFECYCLE; } } - +#if USE_PASINTERFACE == 1 if(register_pers_admin_service() == -1) { DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => Failed to register to pers admin dbus interface")); pthread_mutex_unlock(&gDbusPendingRegMtx); return EPERS_REGISTER_ADMIN; } +#endif /// get custom library names to load status = get_custom_libraries(); @@ -186,12 +197,13 @@ int pclDeinitLibrary(void) { DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclDeinitLibrary -> D E I N I T client library - "), DLT_STRING(gAppId), DLT_STRING("- init counter: "), DLT_INT(gPclInitialized)); - // unregister for lifecycle and persistence admin service dbus messages if(gShutdownMode != PCL_SHUTDOWN_TYPE_NONE) rval = unregister_lifecycle(gShutdownMode); +#if USE_PASINTERFACE == 1 rval = unregister_pers_admin_service(); +#endif // unload custom client libraries for(i=0; i<PersCustomLib_LastEntry; i++) @@ -207,6 +219,12 @@ int pclDeinitLibrary(void) } } + // close all apend rct + pers_rct_close_all(); + + // close opend database + pers_db_close_all(); + gPclInitialized = PCLnotInitialized; DLT_UNREGISTER_CONTEXT(gDLTContext); diff --git a/src/persistence_client_library_backup_filelist.c b/src/persistence_client_library_backup_filelist.c index 24cf12b..168f30c 100644 --- a/src/persistence_client_library_backup_filelist.c +++ b/src/persistence_client_library_backup_filelist.c @@ -17,6 +17,7 @@ */ #include "persistence_client_library_backup_filelist.h" +#include "persistence_client_library_handle.h" #include "rbtree.h" #include "../include_protected/crc32.h" #include "../include_protected/persistence_client_library_data_organization.h" @@ -317,3 +318,459 @@ void key_val_rel(void *p ) } +int pclCreateFile(const char* path) +{ + const char* delimiters = "/\n"; // search for blank and end of line + char* tokenArray[24]; + char* thePath = (char*)path; + int numTokens = 0, i = 0, validPath = 1; + int handle = 0; + + tokenArray[numTokens++] = strtok(thePath, delimiters); + while(tokenArray[numTokens-1] != NULL ) + { + tokenArray[numTokens] = strtok(NULL, delimiters); + if(tokenArray[numTokens] != NULL) + { + numTokens++; + if(numTokens >= 24) + { + validPath = 0; + break; + } + } + else + { + break; + } + } + + if(validPath == 1) + { + char createPath[DbPathMaxLen] = {0}; + snprintf(createPath, DbPathMaxLen, "/%s",tokenArray[0] ); + for(i=1; i<numTokens-1; i++) + { + // create folders + strncat(createPath, "/", DbPathMaxLen-1); + strncat(createPath, tokenArray[i], DbPathMaxLen-1); + mkdir(createPath, 0744); + } + // finally create the file + strncat(createPath, "/", DbPathMaxLen-1); + strncat(createPath, tokenArray[i], DbPathMaxLen-1); + handle = open(createPath, O_CREAT|O_RDWR |O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); + if(handle != -1) + { + if(handle < MaxPersHandle) + { + __sync_fetch_and_add(&gOpenFdArray[handle], FileOpen); // set open flag + } + else + { + close(handle); + handle = EPERS_MAXHANDLE; + } + } + } + else + { + DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclCreateFile ==> no valid path to create: "), DLT_STRING(path) ); + } + + return handle; +} + + +int pclVerifyConsistency(const char* origPath, const char* backupPath, const char* csumPath, int openFlags) +{ + int handle = 0, readSize = 0; + int backupAvail = 0, csumAvail = 0; + int fdCsum = 0, fdBackup = 0; + + char origCsumBuf[ChecksumBufSize] = {0}; + char backCsumBuf[ChecksumBufSize] = {0}; + char csumBuf[ChecksumBufSize] = {0}; + + // check if we have a backup and checksum file + backupAvail = access(backupPath, F_OK); + csumAvail = access(csumPath, F_OK); + + // ************************************************* + // there is a backup file and a checksum + // ************************************************* + if( (backupAvail == 0) && (csumAvail == 0) ) + { + DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclVerifyConsistency => there is a backup file AND a checksum")); + // calculate checksum form backup file + fdBackup = open(backupPath, O_RDONLY); + if(fdBackup != -1) + { + pclCalcCrc32Csum(fdBackup, backCsumBuf); + + fdCsum = open(csumPath, O_RDONLY); + if(fdCsum != -1) + { + readSize = read(fdCsum, csumBuf, ChecksumBufSize); + if(readSize > 0) + { + if(strcmp(csumBuf, backCsumBuf) == 0) + { + // checksum matches ==> replace with original file + handle = pclRecoverFromBackup(fdBackup, origPath); + } + else + { + // checksum does not match, check checksum with original file + handle = open(origPath, openFlags); + if(handle != -1) + { + pclCalcCrc32Csum(handle, origCsumBuf); + if(strcmp(csumBuf, origCsumBuf) != 0) + { + close(handle); + handle = -1; // error: file corrupt + } + // else case: checksum matches ==> keep original file ==> nothing to do + + } + else + { + close(handle); + handle = -1; // error: file corrupt + } + } + } + close(fdCsum); + } + else + { + close(fdCsum); + handle = -1; // error: file corrupt + } + } + else + { + handle = -1; + } + close(fdBackup); + } + // ************************************************* + // there is ONLY a checksum file + // ************************************************* + else if(csumAvail == 0) + { + DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclVerifyConsistency => there is ONLY a checksum file")); + + fdCsum = open(csumPath, O_RDONLY); + if(fdCsum != -1) + { + readSize = read(fdCsum, csumBuf, ChecksumBufSize); + if(readSize <= 0) + { + DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclVerifyConsistency => read checksum: invalid readSize")); + } + close(fdCsum); + + // calculate the checksum form the original file to see if it matches + handle = open(origPath, openFlags); + if(handle != -1) + { + pclCalcCrc32Csum(handle, origCsumBuf); + + if(strcmp(csumBuf, origCsumBuf) != 0) + { + close(handle); + handle = -1; // checksum does NOT match ==> error: file corrupt + } + // else case: checksum matches ==> keep original file ==> nothing to do + } + else + { + close(handle); + handle = -1; // error: file corrupt + } + } + else + { + close(fdCsum); + handle = -1; // error: file corrupt + } + } + // ************************************************* + // there is ONLY a backup file + // ************************************************* + else if(backupAvail == 0) + { + DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclVerifyConsistency => there is ONLY a backup file")); + + // calculate checksum form backup file + fdBackup = open(backupPath, O_RDONLY); + if(fdBackup != -1) + { + pclCalcCrc32Csum(fdBackup, backCsumBuf); + close(fdBackup); + + // calculate the checksum form the original file to see if it matches + handle = open(origPath, openFlags); + if(handle != -1) + { + pclCalcCrc32Csum(handle, origCsumBuf); + + if(strcmp(backCsumBuf, origCsumBuf) != 0) + { + close(handle); + handle = -1; // checksum does NOT match ==> error: file corrupt + } + // else case: checksum matches ==> keep original file ==> nothing to do + + } + else + { + close(handle); + handle = -1; // error: file corrupt + } + } + else + { + close(fdBackup); + handle = -1; // error: file corrupt + } + } + // for else case: nothing to do + + + // if we are in an inconsistent state: delete file, backup and checksum + if(handle == -1) + { + remove(origPath); + remove(backupPath); + remove(csumPath); + } + + return handle; +} + + + +int pclRecoverFromBackup(int backupFd, const char* original) +{ + int handle = 0; + int readSize = 0; + char buffer[RDRWBufferSize]; + + handle = open(original, O_TRUNC | O_RDWR); + if(handle != -1) + { + // copy data from one file to another + while((readSize = read(backupFd, buffer, RDRWBufferSize)) > 0) + { + if(write(handle, buffer, readSize) != readSize) + { + DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclRecoverFromBackup => couldn't write whole buffer")); + break; + } + } + + } + + return handle; +} + + + +int pclCreateBackup(const char* dstPath, int srcfd, const char* csumPath, const char* csumBuf) +{ + int dstFd = 0, csfd = 0; + int readSize = -1; + char buffer[RDRWBufferSize]; + + if(access(dstPath, F_OK) != 0) + { + char pathToCreate[DbPathMaxLen] = {0}; + strncpy(pathToCreate, dstPath, DbPathMaxLen); + pclCreateFileAndPath(pathToCreate); + } + + // create checksum file and and write checksum + csfd = open(csumPath, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); + if(csfd != -1) + { + int csumSize = strlen(csumBuf); + if(write(csfd, csumBuf, csumSize) != csumSize) + { + DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclCreateBackup => failed to write checksum to file")); + } + close(csfd); + } + else + { + DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclCreateBackup => failed to create checksum file:"), DLT_STRING(strerror(errno)) ); + } + + // create backup file, user and group has read/write permission, others have read permission + dstFd = open(dstPath, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); + if(dstFd != -1) + { + off_t curPos = 0; + // remember the current position + curPos = lseek(srcfd, 0, SEEK_CUR); + + // copy data from one file to another + while((readSize = read(srcfd, buffer, RDRWBufferSize)) > 0) + { + if(write(dstFd, buffer, readSize) != readSize) + { + DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclCreateBackup => couldn't write whole buffer")); + break; + } + } + + if(readSize == -1) + DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pcl_create_backup => error copying file")); + + if((readSize = close(dstFd)) == -1) + DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pcl_create_backup => error closing fd")); + + // set back to the position + lseek(srcfd, curPos, SEEK_SET); + } + else + { + DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclCreateBackup => failed to open backup file"), + DLT_STRING(dstPath), DLT_STRING(strerror(errno))); + } + + return readSize; +} + + + +int pclCalcCrc32Csum(int fd, char crc32sum[]) +{ + int rval = 1; + + if(crc32sum != 0) + { + char* buf; + struct stat statBuf; + + fstat(fd, &statBuf); + buf = malloc((unsigned int)statBuf.st_size); + + if(buf != 0) + { + off_t curPos = 0; + // remember the current position + curPos = lseek(fd, 0, SEEK_CUR); + + if(curPos != 0) + { + // set to beginning of the file + lseek(fd, 0, SEEK_SET); + } + + while((rval = read(fd, buf, statBuf.st_size)) > 0) + { + unsigned int crc = 0; + crc = pclCrc32(crc, (unsigned char*)buf, statBuf.st_size); + snprintf(crc32sum, ChecksumBufSize-1, "%x", crc); + } + + // set back to the position + lseek(fd, curPos, SEEK_SET); + + free(buf); + } + } + return rval; +} + + + +int pclBackupNeeded(const char* path) +{ + return need_backup_key(pclCrc32(0, (const unsigned char*)path, strlen(path))); +} + + + +int pclCreateFileAndPath(const char* path) +{ + const char* delimiters = "/\n"; // search for blank and end of line + char* tokenArray[24]; + char* thePath = (char*)path; + char createPath[DbPathMaxLen] = {0}; + int numTokens = 0, i = 0, validPath = 1; + int rval = -1; + + tokenArray[numTokens++] = strtok(thePath, delimiters); + while(tokenArray[numTokens-1] != NULL ) + { + tokenArray[numTokens] = strtok(NULL, delimiters); + if(tokenArray[numTokens] != NULL) + { + numTokens++; + if(numTokens >= 24) + { + validPath = 0; + break; + } + } + else + { + break; + } + } + + if(validPath == 1) + { + snprintf(createPath, DbPathMaxLen, "/%s",tokenArray[0] ); + for(i=1; i<numTokens-1; i++) + { + // create folders + strncat(createPath, "/", DbPathMaxLen-1); + strncat(createPath, tokenArray[i], DbPathMaxLen-1); + mkdir(createPath, 0744); + } + // finally create the file + strncat(createPath, "/", DbPathMaxLen-1); + strncat(createPath, tokenArray[i], DbPathMaxLen-1); + rval = open(createPath, O_CREAT|O_RDWR |O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); + close(rval); + } + else + { + DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclCreateFileAndPath ==> no valid path to create:"), DLT_STRING(path)); + } + + return rval; +} + + + +int pclGetPosixPermission(PersistencePermission_e permission) +{ + int posixPerm = 0; + + switch( (int)permission) + { + case PersistencePermission_ReadWrite: + posixPerm = O_RDWR; + break; + case PersistencePermission_ReadOnly: + posixPerm = O_RDONLY; + break; + case PersistencePermission_WriteOnly: + posixPerm = O_WRONLY; + break; + default: + posixPerm = O_RDONLY; + break; + } + + return posixPerm; +} + + + diff --git a/src/persistence_client_library_backup_filelist.h b/src/persistence_client_library_backup_filelist.h index d89181d..65a6a3c 100644 --- a/src/persistence_client_library_backup_filelist.h +++ b/src/persistence_client_library_backup_filelist.h @@ -30,7 +30,75 @@ int readBlacklistConfigFile(const char* filename); +/** + * @brief + * + * @param + * + * @return + */ int need_backup_key(unsigned int key); +/** + * @brief create the file + * + * @param + * + * @return + */ +int pclCreateFile(const char* path); + + +/** + * @brief create a backup of a file + * + * @param + * + * @return + */ +int pclCreateBackup(const char* srcPath, int srcfd, const char* csumPath, const char* csumBuf); + + +/** + * @brief recover file form backup + * + * @param + * + * @return + */ +int pclRecoverFromBackup(int backupFd, const char* original); + + +/** + * @brief calculate crc32 checksum + * + * @param + * + * @return + */ +int pclCalcCrc32Csum(int fd, char crc32sum[]); + + +/** + * @brief verify file for consistency + * + * @param + * + * @return + */ +int pclVerifyConsistency(const char* origPath, const char* backupPath, const char* csumPath, int openFlags); + + +/** + * @brief check if file needs to be backuped + * + * @param + * + * @return + */ +inline int pclBackupNeeded(const char* path); + + + #endif /* PERS_BACKUP_BLACKLIST_H */ diff --git a/src/persistence_client_library_custom_loader.h b/src/persistence_client_library_custom_loader.h index b1b90fe..ff92fcd 100644 --- a/src/persistence_client_library_custom_loader.h +++ b/src/persistence_client_library_custom_loader.h @@ -158,7 +158,7 @@ int load_all_custom_libraries(); * * @return the array position or -1 if the position can't be found */ -int check_valid_idx(int idx); +inline int check_valid_idx(int idx); @@ -167,7 +167,7 @@ int check_valid_idx(int idx); * * @return the name of the custom library ot NULL if invalid */ -char* get_custom_client_lib_name(int idx); +inline char* get_custom_client_lib_name(int idx); /** diff --git a/src/persistence_client_library_data_organization.c b/src/persistence_client_library_data_organization.c index 73d45cf..12d5eea 100644 --- a/src/persistence_client_library_data_organization.c +++ b/src/persistence_client_library_data_organization.c @@ -45,34 +45,47 @@ const char* gUser = "/user/"; const char* gSeat = "/seat/"; +/// cached path location +#define CACHEPREFIX "/Data/mnt-c/" +/// write through path location +#define WTPREFIX "/Data/mnt-wt/" + +/// size of cached path string +const int gCPathPrefixSize = sizeof(CACHEPREFIX)-1; +/// size of write through string +const int gWTPathPrefixSize = sizeof(WTPREFIX)-1; + +/// path for the backup location +const char* gBackupPrefix = "/Data/mnt-backup/"; + /// path prefix for local cached database: /Data/mnt_c/<appId>/ (<database_name> -const char* gLocalCachePath = "/Data/mnt-c/%s"; +const char* gLocalCachePath = CACHEPREFIX "%s"; /// path prefix for local write through database /Data/mnt_wt/<appId>/<database_name> -const char* gLocalWtPath = "/Data/mnt-wt/%s"; +const char* gLocalWtPath = WTPREFIX "%s"; /// path prefix for shared cached database: /Data/mnt_c/Shared/Group/<group_no>/<database_name> -const char* gSharedCachePath = "/Data/mnt-c/%s/Shared_Group_%x"; +const char* gSharedCachePath = CACHEPREFIX "%s/Shared_Group_%x"; /// path prefix for shared write through database: /Data/mnt_wt/Shared/Group/<group_no>/<database_name> -const char* gSharedWtPath = "/Data/mnt-wt/%s/Shared_Group_%x"; +const char* gSharedWtPath = WTPREFIX "%s/Shared_Group_%x"; /// path prefix for shared public cached database: /Data/mnt_c/Shared/Public//<database_name> -const char* gSharedPublicCachePath = "/Data/mnt-c/%s/Shared_Public"; +const char* gSharedPublicCachePath = CACHEPREFIX "%s/Shared_Public"; /// path prefix for shared public write through database: /Data/mnt_wt/Shared/Public/<database_name> -const char* gSharedPublicWtPath = "/Data/mnt-wt/%s/Shared_Public"; +const char* gSharedPublicWtPath = WTPREFIX "%s/Shared_Public"; /// path prefix for local cached database: /Data/mnt_c/<appId>/ (<database_name> -const char* gLocalCachePathKey = "/Data/mnt-c/%s%s"; +const char* gLocalCachePathKey = CACHEPREFIX "%s%s"; /// path prefix for local write through database /Data/mnt_wt/<appId>/<database_name> -const char* gLocalWtPathKey = "/Data/mnt-wt/%s%s"; +const char* gLocalWtPathKey = WTPREFIX "%s%s"; /// path prefix for shared cached database: /Data/mnt_c/Shared/Group/<group_no>/<database_name> -const char* gSharedCachePathKey = "/Data/mnt-c/%s/Shared_Group_%x%s"; +const char* gSharedCachePathKey = CACHEPREFIX "%s/Shared_Group_%x%s"; /// path prefix for shared write through database: /Data/mnt_wt/Shared/Group/<group_no>/<database_name> -const char* gSharedWtPathKey = "/Data/mnt-wt/%s/Shared_Group_%x%s"; +const char* gSharedWtPathKey = WTPREFIX "%s/Shared_Group_%x%s"; /// path prefix for shared public cached database: /Data/mnt_c/Shared/Public//<database_name> -const char* gSharedPublicCachePathKey = "/Data/mnt-c/%s/Shared_Public%s"; +const char* gSharedPublicCachePathKey = CACHEPREFIX "%s/Shared_Public%s"; /// path prefix for shared public write through database: /Data/mnt_wt/Shared/Public/<database_name> -const char* gSharedPublicWtPathKey = "/Data/mnt-wt/%s/Shared_Public%s"; +const char* gSharedPublicWtPathKey = WTPREFIX "%s/Shared_Public%s"; /// path prefix for local cached files: /Data/mnt_c/<appId>/<user>/<seat>/<resource> -const char* gLocalCacheFilePath = "/Data/mnt-c/%s/user/%d/seat/%d/%s"; +const char* gLocalCacheFilePath = CACHEPREFIX "%s/user/%d/seat/%d/%s"; const char* gChangeSignal = "PersistenceResChange"; diff --git a/src/persistence_client_library_db_access.c b/src/persistence_client_library_db_access.c index e974198..8c10ae9 100644 --- a/src/persistence_client_library_db_access.c +++ b/src/persistence_client_library_db_access.c @@ -209,6 +209,29 @@ void pers_db_close_all() } +void pers_rct_close_all() +{ + int i = 0; + itzam_btree* resourceTable = NULL; + itzam_state state = ITZAM_FAILED; + + // close open persistence resource configuration table + for(i=0; i< PrctDbTableSize; i++) + { + resourceTable = (itzam_btree*)get_resource_cfg_table_by_idx(i); + // dereference opend database + if(resourceTable != NULL && get_resource_cfg_table_status(i) == 1) + { + state = itzam_btree_close(resourceTable); + invalidate_resource_cfg_table(i); + if (state != ITZAM_OKAY) + { + DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("process_prepare_shutdown => itzam_btree_close: Itzam problem"), DLT_STRING(STATE_MESSAGES[state])); + } + } + } +} + int pers_db_read_key(char* dbPath, char* key, PersistenceInfo_s* info, unsigned char* buffer, unsigned int buffer_size) { int read_size = -1; @@ -766,7 +789,8 @@ int pers_db_cursor_create(char* dbPath) int pers_db_cursor_next(unsigned int handlerDB) { - int rval = -1; + int rval = -99; + //if(handlerDB < MaxPersHandle && handlerDB >= 0) if(handlerDB < MaxPersHandle ) { @@ -786,11 +810,13 @@ int pers_db_cursor_next(unsigned int handlerDB) } else { + printf("Invalid handle\n"); DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_next ==> invalid handle: "), DLT_INT(handlerDB)); } } else { + printf("Handle bigger than max\n"); DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_next ==> handle bigger than max:"), DLT_INT(MaxPersHandle)); } return rval; diff --git a/src/persistence_client_library_dbus_cmd.c b/src/persistence_client_library_dbus_cmd.c index c3f69af..b9a99b4 100644 --- a/src/persistence_client_library_dbus_cmd.c +++ b/src/persistence_client_library_dbus_cmd.c @@ -170,8 +170,6 @@ void process_block_and_write_data_back(unsigned int requestID, unsigned int stat void process_prepare_shutdown(unsigned char requestId, unsigned int status) { int i = 0; - itzam_btree* resourceTable = NULL; - itzam_state state = ITZAM_FAILED; // block write pers_lock_access(); @@ -187,23 +185,10 @@ void process_prepare_shutdown(unsigned char requestId, unsigned int status) } } - // close open gvdb persistence resource configuration table - for(i=0; i< PrctDbTableSize; i++) - { - resourceTable = get_resource_cfg_table_by_idx(i); - // dereference opend database - if(resourceTable != NULL && get_resource_cfg_table_status(i) == 1) - { - state = itzam_btree_close(resourceTable); - invalidate_resource_cfg_table(i); - if (state != ITZAM_OKAY) - { - DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("process_prepare_shutdown => itzam_btree_close: Itzam problem"), DLT_STRING(STATE_MESSAGES[state])); - } - } - } + // close all opend rct + pers_rct_close_all(); - //close opend database + // close opend database pers_db_close_all(); @@ -305,7 +290,7 @@ void process_send_pas_register(DBusConnection* conn, int regType, int notificati if(!dbus_pending_call_set_notify(pending, msg_pending_func, method, NULL)) { - printf("process_send_pas_register => dbus_pending_call_set_notify: FAILED\n"); + DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("process_send_pas_register => dbus_pending_call_set_notify: FAILED\n") ); } dbus_pending_call_unref(pending); } diff --git a/src/persistence_client_library_dbus_service.c b/src/persistence_client_library_dbus_service.c index 486b04a..ae45186 100644 --- a/src/persistence_client_library_dbus_service.c +++ b/src/persistence_client_library_dbus_service.c @@ -243,6 +243,8 @@ void* run_mainloop(void* dataPtr) // setup the dbus mainLoop(vtablePersAdmin, vtableLifecycle, vtableFallback, dataPtr); + printf("<== run_mainloop\n"); + return NULL; } @@ -501,8 +503,10 @@ int mainLoop(DBusObjectPathVTable vtable, DBusObjectPathVTable vtable2, dbus_bus_add_match(conn, "type='signal',interface='org.genivi.persistence.admin',member='PersistenceModeChanged',path='/org/genivi/persistence/admin'", &err); // register for messages - if ( (TRUE==dbus_connection_register_object_path(conn, "/org/genivi/persistence/adminconsumer", &vtable, userData)) - && (TRUE==dbus_connection_register_object_path(conn, "/org/genivi/NodeStateManager/LifeCycleConsumer", &vtable2, userData)) + if ( (TRUE==dbus_connection_register_object_path(conn, "/org/genivi/NodeStateManager/LifeCycleConsumer", &vtable2, userData)) +#if USE_PASINTERFACE == 1 + && (TRUE==dbus_connection_register_object_path(conn, "/org/genivi/persistence/adminconsumer", &vtable, userData)) +#endif && (TRUE==dbus_connection_register_fallback(conn, "/", &vtableFallback, userData)) ) { if( (TRUE!=dbus_connection_set_watch_functions(conn, addWatch, removeWatch, watchToggled, NULL, NULL)) @@ -593,7 +597,7 @@ int mainLoop(DBusObjectPathVTable vtable, DBusObjectPathVTable vtable2, process_send_lifecycle_register(conn, (buf[1]), buf[2]); break; case CMD_QUIT: - bContinue = FALSE; + bContinue = 0; break; // ****************************************************** @@ -643,7 +647,9 @@ int mainLoop(DBusObjectPathVTable vtable, DBusObjectPathVTable vtable2, } while (0!=bContinue); } +#if USE_PASINTERFACE == 1 dbus_connection_unregister_object_path(conn, "/org/genivi/persistence/adminconsumer"); +#endif dbus_connection_unregister_object_path(conn, "/org/genivi/NodeStateManager/LifeCycleConsumer"); dbus_connection_unregister_object_path(conn, "/"); } @@ -656,6 +662,7 @@ int mainLoop(DBusObjectPathVTable vtable, DBusObjectPathVTable vtable2, pthread_cond_signal(&gDbusInitializedCond); pthread_mutex_unlock(&gDbusInitializedMtx); + printf("End Mainloop\n"); return 0; } diff --git a/src/persistence_client_library_file.c b/src/persistence_client_library_file.c index fea9c68..d73fe12 100644 --- a/src/persistence_client_library_file.c +++ b/src/persistence_client_library_file.c @@ -38,21 +38,6 @@ #include <stdlib.h> -// header prototype definition of internal functions -int pclCreateFile(const char* path); - -int pclCreateBackup(const char* srcPath, int srcfd, const char* csumPath, const char* csumBuf); - -int pclRecoverFromBackup(int backupFd, const char* original); - -int pclCalcCrc32Csum(int fd, char crc32sum[]); - -int pclVerifyConsistency(const char* origPath, const char* backupPath, const char* csumPath, int openFlags); - -int pclBackupNeeded(const char* path); -//------------------------------------------------------------- - - int pclFileClose(int fd) { @@ -160,6 +145,23 @@ int pclFileOpen(unsigned int ldbid, const char* resource_id, unsigned int user_n if(dbContext.configKey.type == PersistenceResourceType_file) // check if the resource is really a file { + // create backup path + int length = 0; + char fileSubPath[DbPathMaxLen] = {0}; + + if(dbContext.configKey.policy == PersistencePolicy_wc) + { + length = gCPathPrefixSize; + } + else + { + length = gWTPathPrefixSize; + } + + strncpy(fileSubPath, dbPath+length, DbPathMaxLen); + snprintf(backupPath, DbPathMaxLen, "%s%s", gBackupPrefix, fileSubPath); + snprintf(csumPath, DbPathMaxLen, "%s%s%s", gBackupPrefix, fileSubPath, ".crc"); + if(shared_DB >= 0) // check valid database context { int flags = pclGetPosixPermission(dbContext.configKey.permission); @@ -168,9 +170,6 @@ int pclFileOpen(unsigned int ldbid, const char* resource_id, unsigned int user_n if( (dbContext.configKey.permission != PersistencePermission_ReadOnly) && pclBackupNeeded(dbPath) ) { - snprintf(backupPath, DbPathMaxLen, "%s%s", dbPath, "~"); - snprintf(csumPath, DbPathMaxLen, "%s%s", dbPath, "~.crc"); - if((handle = pclVerifyConsistency(dbPath, backupPath, csumPath, flags)) == -1) { DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclFileOpen: error => file inconsistent, recovery N O T possible!")); @@ -194,7 +193,6 @@ int pclFileOpen(unsigned int ldbid, const char* resource_id, unsigned int user_n { strcpy(gFileHandleArray[handle].backupPath, backupPath); strcpy(gFileHandleArray[handle].csumPath, csumPath); - gFileHandleArray[handle].backupCreated = 0; gFileHandleArray[handle].permission = dbContext.configKey.permission; } @@ -220,10 +218,8 @@ int pclFileOpen(unsigned int ldbid, const char* resource_id, unsigned int user_n { if(handle < MaxPersHandle) { - snprintf(backupPath, DbPathMaxLen, "%s%s", dbPath, "~"); - snprintf(csumPath, DbPathMaxLen, "%s%s", dbPath, "~.crc"); - __sync_fetch_and_add(&gOpenFdArray[handle], FileOpen); // set open flag + strcpy(gFileHandleArray[handle].backupPath, backupPath); strcpy(gFileHandleArray[handle].csumPath, csumPath); gFileHandleArray[handle].backupCreated = 0; @@ -378,7 +374,6 @@ int pclFileWriteData(int fd, const void * buffer, int buffer_size) // calculate checksum pclCalcCrc32Csum(fd, csumBuf); - // create checksum and backup file pclCreateBackup(gFileHandleArray[fd].backupPath, fd, gFileHandleArray[fd].csumPath, csumBuf); @@ -562,455 +557,3 @@ int pclFileReleasePath(int pathHandle) -/**************************************************************************************** - * Functions to create backup files - ****************************************************************************************/ - -int pclCreateFile(const char* path) -{ - const char* delimiters = "/\n"; // search for blank and end of line - char* tokenArray[24]; - char* thePath = (char*)path; - int numTokens = 0, i = 0, validPath = 1; - int handle = 0; - - tokenArray[numTokens++] = strtok(thePath, delimiters); - while(tokenArray[numTokens-1] != NULL ) - { - tokenArray[numTokens] = strtok(NULL, delimiters); - if(tokenArray[numTokens] != NULL) - { - numTokens++; - if(numTokens >= 24) - { - validPath = 0; - break; - } - } - else - { - break; - } - } - - if(validPath == 1) - { - char createPath[DbPathMaxLen] = {0}; - snprintf(createPath, DbPathMaxLen, "/%s",tokenArray[0] ); - for(i=1; i<numTokens-1; i++) - { - // create folders - strncat(createPath, "/", DbPathMaxLen-1); - strncat(createPath, tokenArray[i], DbPathMaxLen-1); - mkdir(createPath, 0744); - } - // finally create the file - strncat(createPath, "/", DbPathMaxLen-1); - strncat(createPath, tokenArray[i], DbPathMaxLen-1); - handle = open(createPath, O_CREAT|O_RDWR |O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); - if(handle != -1) - { - if(handle < MaxPersHandle) - { - __sync_fetch_and_add(&gOpenFdArray[handle], FileOpen); // set open flag - } - else - { - close(handle); - handle = EPERS_MAXHANDLE; - } - } - } - else - { - DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclCreateFile ==> no valid path to create: "), DLT_STRING(path) ); - } - - return handle; -} - - -int pclVerifyConsistency(const char* origPath, const char* backupPath, const char* csumPath, int openFlags) -{ - int handle = 0, readSize = 0; - int backupAvail = 0, csumAvail = 0; - int fdCsum = 0, fdBackup = 0; - - char origCsumBuf[ChecksumBufSize] = {0}; - char backCsumBuf[ChecksumBufSize] = {0}; - char csumBuf[ChecksumBufSize] = {0}; - - // check if we have a backup and checksum file - backupAvail = access(backupPath, F_OK); - csumAvail = access(csumPath, F_OK); - - // ************************************************* - // there is a backup file and a checksum - // ************************************************* - if( (backupAvail == 0) && (csumAvail == 0) ) - { - DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclVerifyConsistency => there is a backup file AND a checksum")); - // calculate checksum form backup file - fdBackup = open(backupPath, O_RDONLY); - if(fdBackup != -1) - { - pclCalcCrc32Csum(fdBackup, backCsumBuf); - - fdCsum = open(csumPath, O_RDONLY); - if(fdCsum != -1) - { - readSize = read(fdCsum, csumBuf, ChecksumBufSize); - if(readSize > 0) - { - if(strcmp(csumBuf, backCsumBuf) == 0) - { - // checksum matches ==> replace with original file - handle = pclRecoverFromBackup(fdBackup, origPath); - } - else - { - // checksum does not match, check checksum with original file - handle = open(origPath, openFlags); - if(handle != -1) - { - pclCalcCrc32Csum(handle, origCsumBuf); - if(strcmp(csumBuf, origCsumBuf) != 0) - { - close(handle); - handle = -1; // error: file corrupt - } - // else case: checksum matches ==> keep original file ==> nothing to do - - } - else - { - close(handle); - handle = -1; // error: file corrupt - } - } - } - close(fdCsum); - } - else - { - close(fdCsum); - handle = -1; // error: file corrupt - } - } - else - { - handle = -1; - } - close(fdBackup); - } - // ************************************************* - // there is ONLY a checksum file - // ************************************************* - else if(csumAvail == 0) - { - DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclVerifyConsistency => there is ONLY a checksum file")); - - fdCsum = open(csumPath, O_RDONLY); - if(fdCsum != -1) - { - readSize = read(fdCsum, csumBuf, ChecksumBufSize); - if(readSize <= 0) - { - DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclVerifyConsistency => read checksum: invalid readSize")); - } - close(fdCsum); - - // calculate the checksum form the original file to see if it matches - handle = open(origPath, openFlags); - if(handle != -1) - { - pclCalcCrc32Csum(handle, origCsumBuf); - - if(strcmp(csumBuf, origCsumBuf) != 0) - { - close(handle); - handle = -1; // checksum does NOT match ==> error: file corrupt - } - // else case: checksum matches ==> keep original file ==> nothing to do - } - else - { - close(handle); - handle = -1; // error: file corrupt - } - } - else - { - close(fdCsum); - handle = -1; // error: file corrupt - } - } - // ************************************************* - // there is ONLY a backup file - // ************************************************* - else if(backupAvail == 0) - { - DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("pclVerifyConsistency => there is ONLY a backup file")); - - // calculate checksum form backup file - fdBackup = open(backupPath, O_RDONLY); - if(fdBackup != -1) - { - pclCalcCrc32Csum(fdBackup, backCsumBuf); - close(fdBackup); - - // calculate the checksum form the original file to see if it matches - handle = open(origPath, openFlags); - if(handle != -1) - { - pclCalcCrc32Csum(handle, origCsumBuf); - - if(strcmp(backCsumBuf, origCsumBuf) != 0) - { - close(handle); - handle = -1; // checksum does NOT match ==> error: file corrupt - } - // else case: checksum matches ==> keep original file ==> nothing to do - - } - else - { - close(handle); - handle = -1; // error: file corrupt - } - } - else - { - close(fdBackup); - handle = -1; // error: file corrupt - } - } - // for else case: nothing to do - - - // if we are in an inconsistent state: delete file, backup and checksum - if(handle == -1) - { - remove(origPath); - remove(backupPath); - remove(csumPath); - } - - return handle; -} - - - -int pclRecoverFromBackup(int backupFd, const char* original) -{ - int handle = 0; - int readSize = 0; - char buffer[RDRWBufferSize]; - - handle = open(original, O_TRUNC | O_RDWR); - if(handle != -1) - { - // copy data from one file to another - while((readSize = read(backupFd, buffer, RDRWBufferSize)) > 0) - { - if(write(handle, buffer, readSize) != readSize) - { - DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclRecoverFromBackup => couldn't write whole buffer")); - break; - } - } - - } - - return handle; -} - - - -int pclCreateBackup(const char* dstPath, int srcfd, const char* csumPath, const char* csumBuf) -{ - int dstFd = 0, csfd = 0; - int readSize = -1; - char buffer[RDRWBufferSize]; - - // create checksum file and and write checksum - csfd = open(csumPath, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); - if(csfd != -1) - { - int csumSize = strlen(csumBuf); - if(write(csfd, csumBuf, csumSize) != csumSize) - { - DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclCreateBackup => failed to write checksum to file")); - } - close(csfd); - } - else - { - DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclCreateBackup => failed to create checksum file:"), DLT_STRING(strerror(errno)) ); - } - - - // create backup file, user and group has read/write permission, others have read permission - dstFd = open(dstPath, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); - if(dstFd != -1) - { - off_t curPos = 0; - // remember the current position - curPos = lseek(srcfd, 0, SEEK_CUR); - - // copy data from one file to another - while((readSize = read(srcfd, buffer, RDRWBufferSize)) > 0) - { - if(write(dstFd, buffer, readSize) != readSize) - { - DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclCreateBackup => couldn't write whole buffer")); - break; - } - } - - if(readSize == -1) - DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pcl_create_backup => error copying file")); - - if((readSize = close(dstFd)) == -1) - DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pcl_create_backup => error closing fd")); - - // set back to the position - lseek(srcfd, curPos, SEEK_SET); - } - else - { - DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclCreateBackup => failed to open backup file"), - DLT_STRING(dstPath), DLT_STRING(strerror(errno))); - } - - return readSize; -} - - - -int pclCalcCrc32Csum(int fd, char crc32sum[]) -{ - int rval = 1; - - if(crc32sum != 0) - { - char* buf; - struct stat statBuf; - - fstat(fd, &statBuf); - buf = malloc((unsigned int)statBuf.st_size); - - if(buf != 0) - { - off_t curPos = 0; - // remember the current position - curPos = lseek(fd, 0, SEEK_CUR); - - if(curPos != 0) - { - // set to beginning of the file - lseek(fd, 0, SEEK_SET); - } - - while((rval = read(fd, buf, statBuf.st_size)) > 0) - { - unsigned int crc = 0; - crc = pclCrc32(crc, (unsigned char*)buf, statBuf.st_size); - snprintf(crc32sum, ChecksumBufSize-1, "%x", crc); - } - - // set back to the position - lseek(fd, curPos, SEEK_SET); - - free(buf); - } - } - return rval; -} - - - -int pclBackupNeeded(const char* path) -{ - return need_backup_key(pclCrc32(0, (const unsigned char*)path, strlen(path))); -} - - - -int pclCreateFileAndPath(const char* path) -{ - const char* delimiters = "/\n"; // search for blank and end of line - char* tokenArray[24]; - char* thePath = (char*)path; - char createPath[DbPathMaxLen] = {0}; - int numTokens = 0, i = 0, validPath = 1; - int rval = -1; - - tokenArray[numTokens++] = strtok(thePath, delimiters); - while(tokenArray[numTokens-1] != NULL ) - { - tokenArray[numTokens] = strtok(NULL, delimiters); - if(tokenArray[numTokens] != NULL) - { - numTokens++; - if(numTokens >= 24) - { - validPath = 0; - break; - } - } - else - { - break; - } - } - - if(validPath == 1) - { - snprintf(createPath, DbPathMaxLen, "/%s",tokenArray[0] ); - for(i=1; i<numTokens-1; i++) - { - // create folders - strncat(createPath, "/", DbPathMaxLen-1); - strncat(createPath, tokenArray[i], DbPathMaxLen-1); - mkdir(createPath, 0744); - } - // finally create the file - strncat(createPath, "/", DbPathMaxLen-1); - strncat(createPath, tokenArray[i], DbPathMaxLen-1); - rval = open(createPath, O_CREAT|O_RDWR |O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); - close(rval); - } - else - { - DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclCreateFileAndPath ==> no valid path to create:"), DLT_STRING(path)); - } - - return rval; -} - - - -int pclGetPosixPermission(PersistencePermission_e permission) -{ - int posixPerm = 0; - - switch(permission) - { - case PersistencePermission_ReadWrite: - posixPerm = O_RDWR; - break; - case PersistencePermission_ReadOnly: - posixPerm = O_RDONLY; - break; - case PersistencePermission_WriteOnly: - posixPerm = O_WRONLY; - break; - default: - posixPerm = O_RDONLY; - break; - } - - return posixPerm; -} - diff --git a/src/persistence_client_library_key.c b/src/persistence_client_library_key.c index 6f42dcc..a080a1e 100644 --- a/src/persistence_client_library_key.c +++ b/src/persistence_client_library_key.c @@ -134,6 +134,7 @@ int pclKeyHandleClose(int key_handle) else { set_persistence_handle_close_idx(key_handle); + rval = 1; } // invalidate entries diff --git a/src/persistence_client_library_prct_access.c b/src/persistence_client_library_prct_access.c index b27c125..6dac0e1 100644 --- a/src/persistence_client_library_prct_access.c +++ b/src/persistence_client_library_prct_access.c @@ -192,7 +192,7 @@ int get_db_context(PersistenceInfo_s* dbContext, const char* resource_id, unsign // dbContext->configKey.policy = PersistencePolicy_wc; dbContext->configKey.storage = PersistenceStorage_local; - dbContext->configKey.permission = O_RDWR; + dbContext->configKey.permission = PersistencePermission_ReadWrite; dbContext->configKey.max_size = defaultMaxKeyValDataSize; if(isFile == PersistenceResourceType_file) { diff --git a/src/persistence_client_library_prct_access.h b/src/persistence_client_library_prct_access.h index 44982f3..a14ebdc 100644 --- a/src/persistence_client_library_prct_access.h +++ b/src/persistence_client_library_prct_access.h @@ -79,7 +79,7 @@ itzam_btree* get_resource_cfg_table_by_idx(int i); * * @return status of database, 1 is db is opened and 0 is closed */ -int get_resource_cfg_table_status(int i); +inline int get_resource_cfg_table_status(int i); @@ -88,7 +88,7 @@ int get_resource_cfg_table_status(int i); * * @param i the index */ -void invalidate_resource_cfg_table(int i); +inline void invalidate_resource_cfg_table(int i); |