From b76fd83ca0b8f198924ad58f6f03204e9289c721 Mon Sep 17 00:00:00 2001 From: Ingo Huerner Date: Wed, 1 Oct 2014 11:11:31 +0200 Subject: Fixed GENIVI bug 286 --- src/persistence_client_library.c | 146 ++++++++++++++++++--------------- test/persistence_client_library_test.c | 125 ++++++++++++++++++++++++---- 2 files changed, 190 insertions(+), 81 deletions(-) diff --git a/src/persistence_client_library.c b/src/persistence_client_library.c index cea6784..d675695 100644 --- a/src/persistence_client_library.c +++ b/src/persistence_client_library.c @@ -57,9 +57,9 @@ static int gCancelCounter = 0; int customAsyncInitClbk(int errcode) { - printf("Dummy async init Callback\n"); + printf("Dummy async init Callback\n"); - return 1; + return 1; } @@ -73,17 +73,26 @@ int pclInitLibrary(const char* appName, int shutdownMode) if(gPclInitialized == PCLnotInitialized) { + char rctFilename[DbPathMaxLen] = {0}; gShutdownMode = shutdownMode; DLT_REGISTER_CONTEXT(gPclDLTContext,"PCL","Context for persistence client library logging"); DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclInitLibrary => I N I T Persistence Client Library - "), DLT_STRING(appName), DLT_STRING("- init counter: "), DLT_INT(gPclInitialized) ); - char blacklistPath[DbPathMaxLen] = {0}; + /* security check for valid application: + if the RCT table exists, the application is proven to be valid, + otherwise return EPERS_NOPRCTABLE */ + + snprintf(rctFilename, DbPathMaxLen, gLocalWtPathKey, appName, gResTableCfg); + + if(access(rctFilename, F_OK) == 0) + { + char blacklistPath[DbPathMaxLen] = {0}; #if USE_FILECACHE - DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("Using the filecache!!!")); - pfcInitCache(appName); + DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("Using the filecache!!!")); + pfcInitCache(appName); #endif pthread_mutex_lock(&gDbusPendingRegMtx); // block until pending received @@ -93,7 +102,7 @@ int pclInitLibrary(const char* appName, int shutdownMode) if(readBlacklistConfigFile(blacklistPath) == -1) { - DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("pclInitLibrary - failed to access blacklist:"), DLT_STRING(blacklistPath)); + DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("pclInitLibrary - failed to access blacklist:"), DLT_STRING(blacklistPath)); } #if USE_XSTRACE_PERS @@ -101,9 +110,9 @@ int pclInitLibrary(const char* appName, int shutdownMode) #endif if(setup_dbus_mainloop() == -1) { - DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary - Failed to setup main loop")); - pthread_mutex_unlock(&gDbusPendingRegMtx); - return EPERS_DBUS_MAINLOOP; + DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary - Failed to setup main loop")); + pthread_mutex_unlock(&gDbusPendingRegMtx); + return EPERS_DBUS_MAINLOOP; } #if USE_XSTRACE_PERS xsm_send_user_event("%s - %d\n", __FUNCTION__, __LINE__); @@ -112,26 +121,26 @@ int pclInitLibrary(const char* appName, int shutdownMode) if(gShutdownMode != PCL_SHUTDOWN_TYPE_NONE) { - // register for lifecycle dbus messages - if(register_lifecycle(shutdownMode) == -1) - { - DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => Failed to register to lifecycle dbus interface")); - pthread_mutex_unlock(&gDbusPendingRegMtx); - return EPERS_REGISTER_LIFECYCLE; - } + // register for lifecycle dbus messages + if(register_lifecycle(shutdownMode) == -1) + { + DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => Failed to register to lifecycle dbus interface")); + pthread_mutex_unlock(&gDbusPendingRegMtx); + return EPERS_REGISTER_LIFECYCLE; + } } #if USE_PASINTERFACE DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("PAS interface is enabled!!")); if(register_pers_admin_service() == -1) { - DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary - Failed to register to pers admin dbus interface")); - pthread_mutex_unlock(&gDbusPendingRegMtx); - return EPERS_REGISTER_ADMIN; + DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary - Failed to register to pers admin dbus interface")); + pthread_mutex_unlock(&gDbusPendingRegMtx); + return EPERS_REGISTER_ADMIN; + } + else + { + DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclInitLibrary - Successfully established IPC protocol for PCL.")); } - else - { - DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclInitLibrary - Successfully established IPC protocol for PCL.")); - } #else DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("PAS interface is not enabled, enable with \"./configure --enable-pasinterface\"")); #endif @@ -139,7 +148,7 @@ int pclInitLibrary(const char* appName, int shutdownMode) // load custom plugins if(load_custom_plugins(customAsyncInitClbk) < 0) { - DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("Failed to load custom plugins")); + DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("Failed to load custom plugins")); } // initialize keyHandle array @@ -152,6 +161,11 @@ int pclInitLibrary(const char* appName, int shutdownMode) gAppId[MaxAppNameLen-1] = '\0'; gPclInitialized++; + } + else + { + rval = EPERS_NOPRCTABLE; + } } else if(gPclInitialized >= PCLinitialized) { @@ -180,9 +194,9 @@ int pclDeinitLibrary(void) if(gPclInitialized == PCLinitialized) { int* retval; - MainLoopData_u data; - data.message.cmd = (uint32_t)CMD_QUIT; - data.message.string[0] = '\0'; // no string parameter, set to 0 + MainLoopData_u data; + data.message.cmd = (uint32_t)CMD_QUIT; + data.message.string[0] = '\0'; // no string parameter, set to 0 DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclDeinitLibrary - D E I N I T client library - "), DLT_STRING(gAppId), DLT_STRING("- init counter: "), DLT_INT(gPclInitialized)); @@ -194,12 +208,12 @@ int pclDeinitLibrary(void) #if USE_PASINTERFACE == 1 rval = unregister_pers_admin_service(); if(0 != rval) - { - DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclDeinitLibrary - Failed to de-initialize IPC protocol for PCL.")); - } + { + DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclDeinitLibrary - Failed to de-initialize IPC protocol for PCL.")); + } else { - DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclDeinitLibrary - Successfully de-initialized IPC protocol for PCL.")); + DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclDeinitLibrary - Successfully de-initialized IPC protocol for PCL.")); } #endif @@ -217,7 +231,7 @@ int pclDeinitLibrary(void) } } - process_prepare_shutdown(Shutdown_Full); // close all db's and fd's and block access + process_prepare_shutdown(Shutdown_Full); // close all db's and fd's and block access // send quit command to dbus mainloop deliverToMainloop_NM(&data); @@ -244,8 +258,8 @@ int pclDeinitLibrary(void) } else { - DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("pclDeinitLibrary - D E I N I T client library - "), DLT_STRING(gAppId), - DLT_STRING("- NOT INITIALIZED: ")); + DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("pclDeinitLibrary - D E I N I T client library - "), DLT_STRING(gAppId), + DLT_STRING("- NOT INITIALIZED: ")); rval = EPERS_NOT_INITIALIZED; } @@ -261,38 +275,38 @@ int pclDeinitLibrary(void) int pclLifecycleSet(int shutdown) { - int rval = 0; - - if(gShutdownMode == PCL_SHUTDOWN_TYPE_NONE) - { - if(shutdown == PCL_SHUTDOWN) - { - DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclLifecycleSet - PCL_SHUTDOWN -"), DLT_STRING(gAppId)); - process_prepare_shutdown(Shutdown_Partial); // close all db's and fd's and block access - } - else if(shutdown == PCL_SHUTDOWN_CANCEL) - { - DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclLifecycleSet - PCL_SHUTDOWN_CANCEL -"), DLT_STRING(gAppId), DLT_STRING(" Cancel Counter - "), DLT_INT(gCancelCounter)); - if(gCancelCounter < Shutdown_MaxCount) - { - pers_unlock_access(); - } - else - { - rval = EPERS_SHUTDOWN_MAX_CANCEL; - } - } - else - { - rval = EPERS_COMMON; - } - } - else - { - rval = EPERS_SHUTDOWN_NO_PERMIT; - } - - return rval; + int rval = 0; + + if(gShutdownMode == PCL_SHUTDOWN_TYPE_NONE) + { + if(shutdown == PCL_SHUTDOWN) + { + DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclLifecycleSet - PCL_SHUTDOWN -"), DLT_STRING(gAppId)); + process_prepare_shutdown(Shutdown_Partial); // close all db's and fd's and block access + } + else if(shutdown == PCL_SHUTDOWN_CANCEL) + { + DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclLifecycleSet - PCL_SHUTDOWN_CANCEL -"), DLT_STRING(gAppId), DLT_STRING(" Cancel Counter - "), DLT_INT(gCancelCounter)); + if(gCancelCounter < Shutdown_MaxCount) + { + pers_unlock_access(); + } + else + { + rval = EPERS_SHUTDOWN_MAX_CANCEL; + } + } + else + { + rval = EPERS_COMMON; + } + } + else + { + rval = EPERS_SHUTDOWN_NO_PERMIT; + } + + return rval; } diff --git a/test/persistence_client_library_test.c b/test/persistence_client_library_test.c index c5ea0a0..1c453da 100644 --- a/test/persistence_client_library_test.c +++ b/test/persistence_client_library_test.c @@ -57,6 +57,8 @@ char* gWriteBackupTestData = "This is the content of the file /Data/mnt-c/lt-pe char* gWriteRecoveryTestData = "This is the data to recover: /Data/mnt-c/lt-persistence_client_library_test/user/1/seat/1/media/mediaDB_DataRecovery.db"; char* gRecovChecksum = "608a3b5d"; // generated with http://www.tools4noobs.com/online_php_functions/crc32/ +// function prototype +void run_concurrency_test(); void data_setup(void) @@ -1360,6 +1362,21 @@ END_TEST +START_TEST(test_ValidApplication) +{ + int ret = 0; + unsigned int shutdownReg = PCL_SHUTDOWN_TYPE_FAST | PCL_SHUTDOWN_TYPE_NORMAL; + + ret = pclInitLibrary("InvalidAppID", shutdownReg); + //printf("pclInitLibrary => ret: %d\n", ret); + x_fail_unless(ret == EPERS_NOPRCTABLE, "pclInitLibrary => invalid application ID not detected"); + + pclDeinitLibrary(); +} +END_TEST + + + static Suite * persistencyClientLib_suite() { Suite * s = suite_create("Persistency client library"); @@ -1440,6 +1457,10 @@ static Suite * persistencyClientLib_suite() tcase_add_test(tc_Notifications, test_Notifications); tcase_set_timeout(tc_Notifications, 2); + TCase * tc_ValidApplication = tcase_create("ValidApplication"); + tcase_add_test(tc_ValidApplication, test_ValidApplication); + tcase_set_timeout(tc_ValidApplication, 2); + suite_add_tcase(s, tc_persSetData); tcase_add_checked_fixture(tc_persSetData, data_setup, data_teardown); @@ -1493,6 +1514,8 @@ static Suite * persistencyClientLib_suite() suite_add_tcase(s, tc_Plugin); tcase_add_checked_fixture(tc_Plugin, data_setup, data_teardown); + suite_add_tcase(s, tc_ValidApplication); + suite_add_tcase(s, tc_InitDeinit); return s; @@ -1515,25 +1538,36 @@ int main(int argc, char *argv[]) /// debug log and trace (DLT) setup DLT_REGISTER_APP("PCLt","tests the persistence client library"); -#if 1 - Suite * s = persistencyClientLib_suite(); - SRunner * sr = srunner_create(s); - srunner_set_xml(sr, "/tmp/persistenceClientLibraryTest.xml"); - srunner_set_log(sr, "/tmp/persistenceClientLibraryTest.log"); - srunner_run_all(sr, CK_VERBOSE /*CK_NORMAL CK_VERBOSE*/); - - nr_failed = srunner_ntests_failed(sr); - nr_run = srunner_ntests_run(sr); - tResult = srunner_results(sr); - for(i = 0; i< nr_run; i++) + if(argc >= 2) { - (void)tr_rtype(tResult[i]); // get status of each test - //fail = tr_rtype(tResult[i]); // get status of each test - //printf("[%d] Fail: %d \n", i, fail); + printf("Running concurrency tests\n"); + + run_concurrency_test(); } + else + { +#if 1 + Suite * s = persistencyClientLib_suite(); + SRunner * sr = srunner_create(s); + srunner_set_xml(sr, "/tmp/persistenceClientLibraryTest.xml"); + srunner_set_log(sr, "/tmp/persistenceClientLibraryTest.log"); + srunner_run_all(sr, CK_VERBOSE /*CK_NORMAL CK_VERBOSE*/); + + printf("Running automated tests\n"); + nr_failed = srunner_ntests_failed(sr); + nr_run = srunner_ntests_run(sr); + + tResult = srunner_results(sr); + for(i = 0; i< nr_run; i++) + { + (void)tr_rtype(tResult[i]); // get status of each test + //fail = tr_rtype(tResult[i]); // get status of each test + //printf("[%d] Fail: %d \n", i, fail); + } - srunner_free(sr); + srunner_free(sr); + } #endif // unregister debug log and trace @@ -1545,3 +1579,64 @@ int main(int argc, char *argv[]) } + +void do_pcl_concurrency_access(const char* applicationID, const char* resourceID, int operation) +{ + int ret = 0, i = 0; + unsigned int shutdownReg = PCL_SHUTDOWN_TYPE_FAST | PCL_SHUTDOWN_TYPE_NORMAL; + unsigned char buffer[READ_SIZE] = {0}; + + (void)pclInitLibrary(applicationID, shutdownReg); + + for(i=0; i< 200; i++) + { + printf("[%d] - i: %d", operation, i); + if(operation == 0 ) + { + ret = pclKeyWriteData(0x20, resourceID, 2, 1, (unsigned char*)"Test notify shared data", strlen("Test notify shared data")); + if(ret < 0) + printf("Failed to write data: %d\n", ret); + } + else if(operation == 1) + { + memset(buffer, 0, READ_SIZE); + ret = pclKeyReadData(0x20, resourceID, 3, 2, buffer, READ_SIZE); + if(ret < 0) + printf("Failed to read data: %d\n", ret); + } + else + { + printf("invalid operation - end!!"); + break; + } + } + + pclDeinitLibrary(); +} + + +void run_concurrency_test() +{ + const char* appId_one = "lt-persistence_client_library_test"; + const char* appId_two = "pfs_test"; + + int pid = fork(); + + if (pid == 0) + { /*child*/ + printf("Started child process with PID: [%d] \n", pid); + + do_pcl_concurrency_access(appId_one, "links/last_link2", 0); + + _exit(EXIT_SUCCESS); + } + else if (pid > 0) + { /*parent*/ + printf("Started father process with PID: [%d] \n", pid); + + do_pcl_concurrency_access(appId_one, "links/last_link3", 1); + + _exit(EXIT_SUCCESS); + } +} + -- cgit v1.2.1