9c224646d3c83c11fe0c2c32c3508a8a7cac40ee
[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
46 int pclInitLibrary(const char* appName, int shutdownMode)
47 {
48    int status = 0;
49    int i = 0, rval = 1;
50
51    if(gPclInitialized == PCLnotInitialized)
52    {
53       gShutdownMode = shutdownMode;
54
55       DLT_REGISTER_CONTEXT(gPclDLTContext,"PCL","Context for persistence client library logging");
56       DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclInitLibrary => I N I T  Persistence Client Library - "), DLT_STRING(gAppId),
57                            DLT_STRING("- init counter: "), DLT_INT(gPclInitialized) );
58
59       /// environment variable for on demand loading of custom libraries
60       const char *pOnDemandLoad = getenv("PERS_CUSTOM_LIB_LOAD_ON_DEMAND");
61       /// environment variable for max key value data
62       const char *pDataSize = getenv("PERS_MAX_KEY_VAL_DATA_SIZE");
63       /// blacklist path environment variable
64       const char *pBlacklistPath = getenv("PERS_BLACKLIST_PATH");
65
66 #if USE_FILECACHE
67    printf("* * * * * * Using the filecache!  * * * * * * * * *\n");
68
69    pfcInitCache(appName);
70 #else
71    printf("* * * * * * N O T  using the filecache! * * * * * *\n");
72 #endif
73
74 #if USE_PASINTERFACE == 1
75       //printf("* ADMIN INTERFACE is  - e n a b l e d - \n");
76       DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("PAS interface is enabled!!"));
77 #else
78       //printf("* ADMIN INTERFACE is  - d i s a b l e d - enable with \"./configure --enable-pasinterface\"\n");
79       DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("PAS interface is not enabled, enable with \"./configure --enable-pasinterface\""));
80 #endif
81
82
83       pthread_mutex_lock(&gDbusPendingRegMtx);   // block until pending received
84
85       if(pDataSize != NULL)
86       {
87          gMaxKeyValDataSize = atoi(pDataSize);
88       }
89
90       if(pBlacklistPath == NULL)
91       {
92          pBlacklistPath = "/etc/pclBackupBlacklist.txt";   // default path
93       }
94
95       if(readBlacklistConfigFile(pBlacklistPath) == -1)
96       {
97          DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("pclInitLibrary -> failed to access blacklist:"), DLT_STRING(pBlacklistPath));
98       }
99
100       if(setup_dbus_mainloop() == -1)
101       {
102          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => Failed to setup main loop"));
103          pthread_mutex_unlock(&gDbusPendingRegMtx);
104          return EPERS_DBUS_MAINLOOP;
105       }
106
107
108       if(gShutdownMode != PCL_SHUTDOWN_TYPE_NONE)
109       {
110          // register for lifecycle and persistence admin service dbus messages
111          if(register_lifecycle(shutdownMode) == -1)
112          {
113             DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => Failed to register to lifecycle dbus interface"));
114             pthread_mutex_unlock(&gDbusPendingRegMtx);
115             return EPERS_REGISTER_LIFECYCLE;
116          }
117       }
118 #if USE_PASINTERFACE == 1
119       if(register_pers_admin_service() == -1)
120       {
121          DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => Failed to register to pers admin dbus interface"));
122          pthread_mutex_unlock(&gDbusPendingRegMtx);
123          return EPERS_REGISTER_ADMIN;
124       }
125 #endif
126
127       /// get custom library names to load
128       status = get_custom_libraries();
129       if(status >= 0)
130       {
131          // initialize custom library structure
132          for(i = 0; i < PersCustomLib_LastEntry; i++)
133          {
134             invalidate_custom_plugin(i);
135          }
136
137          if(pOnDemandLoad == NULL)  // load all available libraries now
138          {
139             for(i=0; i < PersCustomLib_LastEntry; i++ )
140             {
141                if(check_valid_idx(i) != -1)
142                {
143                   if(load_custom_library(i, &gPersCustomFuncs[i] ) == 1)
144                   {
145                      if( (gPersCustomFuncs[i].custom_plugin_init) != NULL)
146                      {
147                         DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclInitLibrary => Loaded plugin: "),
148                                                            DLT_STRING(get_custom_client_lib_name(i)));
149                         gPersCustomFuncs[i].custom_plugin_init();
150                      }
151                      else
152                      {
153                         DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => E r r o r could not load plugin functions: "),
154                                                             DLT_STRING(get_custom_client_lib_name(i)));
155                      }
156                   }
157                   else
158                   {
159                      DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pclInitLibrary => E r r o r could not load plugin: "),
160                                           DLT_STRING(get_custom_client_lib_name(i)));
161                   }
162                }
163                else
164                {
165                   continue;
166                }
167             }
168          }
169       }
170       else
171       {
172          DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("pclInit => Failed to load custom library config table => error number:"), DLT_INT(status));
173       }
174
175       // assign application name
176       strncpy(gAppId, appName, MaxAppNameLen);
177       gAppId[MaxAppNameLen-1] = '\0';
178
179       gPclInitialized++;
180    }
181    else if(gPclInitialized >= PCLinitialized)
182    {
183       gPclInitialized++; // increment init counter
184       DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclInitLibrary => I N I T  Persistence Client Library - "), DLT_STRING(gAppId),
185                            DLT_STRING("- ONLY INCREMENT init counter: "), DLT_INT(gPclInitialized) );
186    }
187    return rval;
188 }
189
190
191
192 int pclDeinitLibrary(void)
193 {
194    int i = 0, rval = 1;
195
196    if(gPclInitialized == PCLinitialized)
197    {
198       int* retval;
199       DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclDeinitLibrary -> D E I N I T  client library - "), DLT_STRING(gAppId),
200                                          DLT_STRING("- init counter: "), DLT_INT(gPclInitialized));
201
202       // unregister for lifecycle and persistence admin service dbus messages
203       if(gShutdownMode != PCL_SHUTDOWN_TYPE_NONE)
204          rval = unregister_lifecycle(gShutdownMode);
205
206 #if USE_PASINTERFACE == 1
207       rval = unregister_pers_admin_service();
208 #endif
209
210       // unload custom client libraries
211       for(i=0; i<PersCustomLib_LastEntry; i++)
212       {
213          if(gPersCustomFuncs[i].custom_plugin_deinit != NULL)
214          {
215             // deinitialize plugin
216             gPersCustomFuncs[i].custom_plugin_deinit();
217             // close library handle
218             dlclose(gPersCustomFuncs[i].handle);
219
220             invalidate_custom_plugin(i);
221          }
222       }
223
224       // close all apend rct
225       pers_rct_close_all();
226
227       // close opend database
228       database_close_all();
229
230       // close persistence handles
231       close_all_persistence_handle();
232
233       // end dbus library
234       bContinue = 0;
235
236       // send quit command to dbus mainloop
237       deliverToMainloop_NM(CMD_QUIT, 0, 0);
238
239       // wait until the dbus mainloop has ended
240       pthread_join(gMainLoopThread, (void**)&retval);
241
242       pthread_mutex_unlock(&gDbusPendingRegMtx);
243       pthread_mutex_unlock(&gDbusInitializedMtx);
244
245       gPclInitialized = PCLnotInitialized;
246
247       DLT_UNREGISTER_CONTEXT(gPclDLTContext);
248    }
249    else if(gPclInitialized > PCLinitialized)
250    {
251       DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("pclDeinitLibrary -> D E I N I T  client library - "), DLT_STRING(gAppId),
252                                            DLT_STRING("- ONLY DECREMENT init counter: "), DLT_INT(gPclInitialized));
253       gPclInitialized--;   // decrement init counter
254    }
255    else
256    {
257       rval = EPERS_NOT_INITIALIZED;
258    }
259    return rval;
260 }
261
262
263
264
265
266