1 /******************************************************************************
4 * Company XS Embedded GmbH
5 *****************************************************************************/
6 /******************************************************************************
7 * This Source Code Form is subject to the terms of the
8 * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed
9 * with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 ******************************************************************************/
12 * @file persistence_client_library.c
13 * @ingroup Persistence client library
14 * @author Ingo Huerner
15 * @brief Implementation of the persistence client library.
16 * Library provides an API to access persistent data
21 #include "persistence_client_library_lc_interface.h"
22 #include "persistence_client_library_pas_interface.h"
23 #include "persistence_client_library_dbus_service.h"
24 #include "persistence_client_library_handle.h"
25 #include "persistence_client_library_custom_loader.h"
26 #include "persistence_client_library.h"
27 #include "persistence_client_library_backup_filelist.h"
28 #include "persistence_client_library_db_access.h"
29 #include "persistence_client_library_dbus_cmd.h"
32 #include <persistence_file_cache.h>
39 #include <dbus/dbus.h>
41 /// debug log and trace (DLT) setup
42 DLT_DECLARE_CONTEXT(gPclDLTContext);
45 /// global variable to store lifecycle shutdown mode
46 static int gShutdownMode = 0;
47 /// global shutdown cancel counter
48 static int gCancelCounter = 0;
51 int customAsyncInitClbk(int errcode)
53 printf("Dummy async init Callback\n");
59 int pclInitLibrary(const char* appName, int shutdownMode)
63 if(gPclInitialized == PCLnotInitialized)
65 gShutdownMode = shutdownMode;
67 DLT_REGISTER_CONTEXT(gPclDLTContext,"PCL","Context for persistence client library logging");
68 DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclInitLibrary => I N I T Persistence Client Library - "), DLT_STRING(appName),
69 DLT_STRING("- init counter: "), DLT_INT(gPclInitialized) );
71 /// environment variable for max key value data
72 const char *pDataSize = getenv("PERS_MAX_KEY_VAL_DATA_SIZE");
73 /// blacklist path environment variable
74 const char *pBlacklistPath = getenv("PERS_BLACKLIST_PATH");
77 DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("Using the filecache!!!"));
78 pfcInitCache(appName);
81 pthread_mutex_lock(&gDbusPendingRegMtx); // block until pending received
85 gMaxKeyValDataSize = atoi(pDataSize);
88 if(pBlacklistPath == NULL)
90 pBlacklistPath = "/etc/pclBackupBlacklist.txt"; // default path
93 if(readBlacklistConfigFile(pBlacklistPath) == -1)
95 DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("pclInitLibrary -> failed to access blacklist:"), DLT_STRING(pBlacklistPath));
98 if(setup_dbus_mainloop() == -1)
100 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => Failed to setup main loop"));
101 pthread_mutex_unlock(&gDbusPendingRegMtx);
102 return EPERS_DBUS_MAINLOOP;
106 if(gShutdownMode != PCL_SHUTDOWN_TYPE_NONE)
108 // register for lifecycle dbus messages
109 if(register_lifecycle(shutdownMode) == -1)
111 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => Failed to register to lifecycle dbus interface"));
112 pthread_mutex_unlock(&gDbusPendingRegMtx);
113 return EPERS_REGISTER_LIFECYCLE;
116 #if USE_PASINTERFACE == 1
117 DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("PAS interface is enabled!!"));
118 if(register_pers_admin_service() == -1)
120 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => Failed to register to pers admin dbus interface"));
121 pthread_mutex_unlock(&gDbusPendingRegMtx);
122 return EPERS_REGISTER_ADMIN;
126 DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclInitLibrary => Successfully established IPC protocol for PCL."));
129 DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("PAS interface is not enabled, enable with \"./configure --enable-pasinterface\""));
132 // load custom plugins
133 if(load_custom_plugins(customAsyncInitClbk) < 0)
135 DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("Failed to load custom plugins"));
138 // initialize keyHandle array
139 init_key_handle_array();
141 pers_unlock_access();
143 // assign application name
144 strncpy(gAppId, appName, MaxAppNameLen);
145 gAppId[MaxAppNameLen-1] = '\0';
149 else if(gPclInitialized >= PCLinitialized)
151 gPclInitialized++; // increment init counter
152 DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclInitLibrary => I N I T Persistence Client Library - "), DLT_STRING(gAppId),
153 DLT_STRING("- ONLY INCREMENT init counter: "), DLT_INT(gPclInitialized) );
161 int pclDeinitLibrary(void)
165 if(gPclInitialized == PCLinitialized)
169 data.message.cmd = (uint32_t)CMD_QUIT;
170 data.message.string[0] = '\0'; // no string parameter, set to 0
172 DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclDeinitLibrary -> D E I N I T client library - "), DLT_STRING(gAppId),
173 DLT_STRING("- init counter: "), DLT_INT(gPclInitialized));
175 // unregister for lifecycle dbus messages
176 if(gShutdownMode != PCL_SHUTDOWN_TYPE_NONE)
177 rval = unregister_lifecycle(gShutdownMode);
179 #if USE_PASINTERFACE == 1
180 rval = unregister_pers_admin_service();
183 DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclDeinitLibrary => Failed to de-initialize IPC protocol for PCL."));
187 DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclDeinitLibrary => Successfully de-initialized IPC protocol for PCL."));
191 // unload custom client libraries
192 for(i=0; i<PersCustomLib_LastEntry; i++)
194 if(gPersCustomFuncs[i].custom_plugin_deinit != NULL)
196 // deinitialize plugin
197 gPersCustomFuncs[i].custom_plugin_deinit();
198 // close library handle
199 dlclose(gPersCustomFuncs[i].handle);
201 invalidate_custom_plugin(i);
205 process_prepare_shutdown(Shutdown_Full); // close all db's and fd's and block access
207 // send quit command to dbus mainloop
208 deliverToMainloop_NM(&data);
210 // wait until the dbus mainloop has ended
211 pthread_join(gMainLoopThread, (void**)&retval);
213 pthread_mutex_unlock(&gDbusPendingRegMtx);
214 pthread_mutex_unlock(&gDbusInitializedMtx);
216 gPclInitialized = PCLnotInitialized;
222 DLT_UNREGISTER_CONTEXT(gPclDLTContext);
224 else if(gPclInitialized > PCLinitialized)
226 DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclDeinitLibrary -> D E I N I T client library - "), DLT_STRING(gAppId),
227 DLT_STRING("- ONLY DECREMENT init counter: "), DLT_INT(gPclInitialized));
228 gPclInitialized--; // decrement init counter
232 rval = EPERS_NOT_INITIALIZED;
239 int pclLifecycleSet(int shutdown)
243 if(gShutdownMode == PCL_SHUTDOWN_TYPE_NONE)
245 if(shutdown == PCL_SHUTDOWN)
247 process_prepare_shutdown(Shutdown_Partial); // close all db's and fd's and block access
249 else if(shutdown == PCL_SHUTDOWN_CANEL)
251 if(gCancelCounter < Shutdown_MaxCount)
253 pers_unlock_access();
257 rval = EPERS_SHUTDOWN_MAX_CANCEL;
267 rval = EPERS_SHUTDOWN_NO_PERMIT;