Added use of default data for files; added test data that can be used by PAS installa...
[profile/ivi/persistence-client-library.git] / src / persistence_client_library.c
1 /******************************************************************************
2  * Project         Persistency
3  * (c) copyright   2012
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 ******************************************************************************/
11  /**
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
17  * @see            
18  */
19
20
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
30 #if USE_FILECACHE
31    #include <persistence_file_cache.h>
32 #endif
33
34 #include <string.h>
35 #include <errno.h>
36 #include <stdlib.h>
37 #include <dlfcn.h>
38 #include <dbus/dbus.h>
39
40 /// debug log and trace (DLT) setup
41 DLT_DECLARE_CONTEXT(gPclDLTContext);
42
43 static int gShutdownMode = 0;
44
45 static int gCancelCounter = 0;
46
47
48 int pclInitLibrary(const char* appName, int shutdownMode)
49 {
50    int status = 0;
51    int i = 0, rval = 1;
52
53    if(gPclInitialized == PCLnotInitialized)
54    {
55       gShutdownMode = shutdownMode;
56
57       DLT_REGISTER_CONTEXT(gPclDLTContext,"PCL","Context for persistence client library logging");
58       DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclInitLibrary => I N I T  Persistence Client Library - "), DLT_STRING(gAppId),
59                            DLT_STRING("- init counter: "), DLT_INT(gPclInitialized) );
60
61       /// environment variable for on demand loading of custom libraries
62       const char *pOnDemandLoad = getenv("PERS_CUSTOM_LIB_LOAD_ON_DEMAND");
63       /// environment variable for max key value data
64       const char *pDataSize = getenv("PERS_MAX_KEY_VAL_DATA_SIZE");
65       /// blacklist path environment variable
66       const char *pBlacklistPath = getenv("PERS_BLACKLIST_PATH");
67
68 #if USE_FILECACHE
69    printf("* * * * * * Using the filecache!  * * * * * * * * *\n");
70
71    pfcInitCache(appName);
72 #else
73    printf("* * * * * * N O T  using the filecache! * * * * * *\n");
74 #endif
75
76 #if USE_PASINTERFACE == 1
77       //printf("* ADMIN INTERFACE is  - e n a b l e d - \n");
78       DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("PAS interface is enabled!!"));
79 #else
80       //printf("* ADMIN INTERFACE is  - d i s a b l e d - enable with \"./configure --enable-pasinterface\"\n");
81       DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("PAS interface is not enabled, enable with \"./configure --enable-pasinterface\""));
82 #endif
83
84
85       pthread_mutex_lock(&gDbusPendingRegMtx);   // block until pending received
86
87       if(pDataSize != NULL)
88       {
89          gMaxKeyValDataSize = atoi(pDataSize);
90       }
91
92       if(pBlacklistPath == NULL)
93       {
94          pBlacklistPath = "/etc/pclBackupBlacklist.txt";   // default path
95       }
96
97       if(readBlacklistConfigFile(pBlacklistPath) == -1)
98       {
99          DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("pclInitLibrary -> failed to access blacklist:"), DLT_STRING(pBlacklistPath));
100       }
101
102       if(setup_dbus_mainloop() == -1)
103       {
104          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => Failed to setup main loop"));
105          pthread_mutex_unlock(&gDbusPendingRegMtx);
106          return EPERS_DBUS_MAINLOOP;
107       }
108
109
110       if(gShutdownMode != PCL_SHUTDOWN_TYPE_NONE)
111       {
112          // register for lifecycle and persistence admin service dbus messages
113          if(register_lifecycle(shutdownMode) == -1)
114          {
115             DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => Failed to register to lifecycle dbus interface"));
116             pthread_mutex_unlock(&gDbusPendingRegMtx);
117             return EPERS_REGISTER_LIFECYCLE;
118          }
119       }
120 #if USE_PASINTERFACE == 1
121       if(register_pers_admin_service() == -1)
122       {
123          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => Failed to register to pers admin dbus interface"));
124          pthread_mutex_unlock(&gDbusPendingRegMtx);
125          return EPERS_REGISTER_ADMIN;
126       }
127 #endif
128
129       /// get custom library names to load
130       status = get_custom_libraries();
131       if(status >= 0)
132       {
133          // initialize custom library structure
134          for(i = 0; i < PersCustomLib_LastEntry; i++)
135          {
136             invalidate_custom_plugin(i);
137          }
138
139          if(pOnDemandLoad == NULL)  // load all available libraries now
140          {
141             for(i=0; i < PersCustomLib_LastEntry; i++ )
142             {
143                if(check_valid_idx(i) != -1)
144                {
145                   if(load_custom_library(i, &gPersCustomFuncs[i] ) == 1)
146                   {
147                      if( (gPersCustomFuncs[i].custom_plugin_init) != NULL)
148                      {
149                         DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclInitLibrary => Loaded plugin: "),
150                                                            DLT_STRING(get_custom_client_lib_name(i)));
151                         gPersCustomFuncs[i].custom_plugin_init();
152                      }
153                      else
154                      {
155                         DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => E r r o r could not load plugin functions: "),
156                                                             DLT_STRING(get_custom_client_lib_name(i)));
157                      }
158                   }
159                   else
160                   {
161                      DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => E r r o r could not load plugin: "),
162                                           DLT_STRING(get_custom_client_lib_name(i)));
163                   }
164                }
165                else
166                {
167                   continue;
168                }
169             }
170          }
171       }
172       else
173       {
174          DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("pclInit => Failed to load custom library config table => error number:"), DLT_INT(status));
175       }
176
177       pers_unlock_access();
178
179       // assign application name
180       strncpy(gAppId, appName, MaxAppNameLen);
181       gAppId[MaxAppNameLen-1] = '\0';
182
183       gPclInitialized++;
184    }
185    else if(gPclInitialized >= PCLinitialized)
186    {
187       gPclInitialized++; // increment init counter
188       DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclInitLibrary => I N I T  Persistence Client Library - "), DLT_STRING(gAppId),
189                            DLT_STRING("- ONLY INCREMENT init counter: "), DLT_INT(gPclInitialized) );
190    }
191    return rval;
192 }
193
194
195
196 int pclDeinitLibrary(void)
197 {
198    int i = 0, rval = 1;
199
200    if(gPclInitialized == PCLinitialized)
201    {
202       int* retval;
203       DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclDeinitLibrary -> D E I N I T  client library - "), DLT_STRING(gAppId),
204                                          DLT_STRING("- init counter: "), DLT_INT(gPclInitialized));
205
206       // unregister for lifecycle and persistence admin service dbus messages
207       if(gShutdownMode != PCL_SHUTDOWN_TYPE_NONE)
208          rval = unregister_lifecycle(gShutdownMode);
209
210 #if USE_PASINTERFACE == 1
211       rval = unregister_pers_admin_service();
212 #endif
213
214       // unload custom client libraries
215       for(i=0; i<PersCustomLib_LastEntry; i++)
216       {
217          if(gPersCustomFuncs[i].custom_plugin_deinit != NULL)
218          {
219             // deinitialize plugin
220             gPersCustomFuncs[i].custom_plugin_deinit();
221             // close library handle
222             dlclose(gPersCustomFuncs[i].handle);
223
224             invalidate_custom_plugin(i);
225          }
226       }
227
228       process_prepare_shutdown(Shutdown_Full);  // close all db's and fd's and block access
229
230       // end dbus library
231       bContinue = 0;
232
233       // send quit command to dbus mainloop
234       deliverToMainloop_NM(CMD_QUIT, 0, 0);
235
236       // wait until the dbus mainloop has ended
237       pthread_join(gMainLoopThread, (void**)&retval);
238
239       pthread_mutex_unlock(&gDbusPendingRegMtx);
240       pthread_mutex_unlock(&gDbusInitializedMtx);
241
242       gPclInitialized = PCLnotInitialized;
243
244       DLT_UNREGISTER_CONTEXT(gPclDLTContext);
245    }
246    else if(gPclInitialized > PCLinitialized)
247    {
248       DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclDeinitLibrary -> D E I N I T  client library - "), DLT_STRING(gAppId),
249                                            DLT_STRING("- ONLY DECREMENT init counter: "), DLT_INT(gPclInitialized));
250       gPclInitialized--;   // decrement init counter
251    }
252    else
253    {
254       rval = EPERS_NOT_INITIALIZED;
255    }
256    return rval;
257 }
258
259
260
261 int pclLifecycleSet(int shutdown)
262 {
263         int rval = 0;
264
265         if(gShutdownMode == PCL_SHUTDOWN_TYPE_NONE)
266         {
267                 if(PCL_SHUTDOWN)
268                 {
269                         process_prepare_shutdown(Shutdown_Partial);     // close all db's and fd's and block access
270                 }
271                 else if(PCL_SHUTDOWN_CANEL)
272                 {
273                         if(gCancelCounter < Shutdown_MaxCount)
274                         {
275                                 pers_unlock_access();
276                         }
277                         else
278                         {
279                                 rval = EPERS_SHUTDOWN_MAX_CANCEL;
280                         }
281                 }
282                 else
283                 {
284                         rval = EPERS_COMMON;
285                 }
286         }
287         else
288         {
289                 rval = EPERS_SHUTDOWN_NO_PERMIT;
290         }
291
292         return rval;
293 }
294
295
296
297