* \{
*/
+#define PCL_SHUTDOWN 1 /// trigger shutdown
+#define PCL_SHUTDOWN_CANEL 0 // cancel shutdown
-#define PCL_SHUTDOWN_TYPE_FAST 2 /// Client registered for fast lifecycle shutdown
-#define PCL_SHUTDOWN_TYPE_NORMAL 1 /// Client registered for normal lifecycle shutdown
-#define PCL_SHUTDOWN_TYPE_NONE 0 /// Client does not register to lifecycle shutdown
+#define PCL_SHUTDOWN_TYPE_FAST 2 /// Client registered for fast lifecycle shutdown
+#define PCL_SHUTDOWN_TYPE_NORMAL 1 /// Client registered for normal lifecycle shutdown
+#define PCL_SHUTDOWN_TYPE_NONE 0 /// Client does not register to lifecycle shutdown
/**
* @param shutdownMode shutdown mode ::PCL_SHUTDOWN_TYPE_FAST or ::PCL_SHUTDOWN_TYPE_NORMAL
*
* @return positive value: success;
- * On error a negative value will be returned with th following error codes:
+ * On error a negative value will be returned with the following error codes:
* ::EPERS_NOT_INITIALIZED, ::EPERS_INIT_DBUS_MAINLOOP,
* ::EPERS_REGISTER_LIFECYCLE, ::EPERS_REGISTER_ADMIN
*/
*/
int pclDeinitLibrary(void);
+
+
+
+/**
+ * @brief pclLifecycleSet client library
+ * This function can be called if to flush and write back the data form cache to memory device.
+ * The function is only available if PCL_SHUTDOWN_TYPE_NONE has been used in pclInitLibrary.
+ *
+ * @attention This function is currently N O T part of the GENIVI compliance specification
+ * @attention In order to prevent misuse of this function the cancel shutdown request
+ * can only be called 3 times per lifecycle.
+ *
+ * @parm PCL_SHUTDOWN for write back data when shutdown is requested,
+ * and PCL_SHUTDOWN_CANEL when shutdown cancel request has been received.
+ *
+ * @return positive value: success;
+ * On error a negative value will be returned with the following error codes:
+ * ::EPERS_COMMON, :.EPERS_MAX_CANCEL_SHUTDOWN, ::EPERS_SHTDWN_NO_PERMIT
+ */
+int pclLifecycleSet(int shutdown);
+
+
/** \} */
#ifdef __cplusplus
#define EPERS_OPENFILE (-10)
/// invalid buffer or key
#define EPERS_DESER_BUFORKEY (-11)
-/// can't allocat memory for deserialization of keyvalue
+/// can't allocate memory for deserialization of key/value
#define EPERS_DESER_ALLOCMEM (-12)
-/// no ploicy avaliable in data to serialize
+/// no ploicy available in data to serialize
#define EPERS_DESER_POLICY (-13)
-/// no store type avaliable in data to serialize
+/// no store type available in data to serialize
#define EPERS_DESER_STORE (-14)
-/// no permission avaliable in data to serialize
+/// no permission available in data to serialize
#define EPERS_DESER_PERM (-15)
-/// no max size avaliable in data to serialize
+/// no max size available in data to serialize
#define EPERS_DESER_MAXSIZE (-16)
-/// no responsibility avaliable in data to serialize
+/// no responsibility available in data to serialize
#define EPERS_DESER_RESP (-17)
/// out of array bounds
#define EPERS_OUTOFBOUNDS (-18)
#define EPERS_CONFIGNOTAVAILABLE (-20)
/// can't stat config file
#define EPERS_CONFIGNOSTAT (-21)
-/// plugin functin not found
+/// plugin function not found
#define EPERS_NOPLUGINFCNT (-22)
/// dlopen error
#define EPERS_DLOPENERROR (-23)
#define EPERS_NOPLUGINFUNCT (-24)
/// file remove error
#define EPERS_FILEREMOVE (-25)
-/// err code to signalize last entry in DB
+/// err code to signalizes last entry in DB
#define EPERS_LAST_ENTRY_IN_DB (-26)
/// internal database error
#define EPERS_DB_ERROR_INTERNAL (-27)
#define EPERS_NOTIFY_SIG (-31)
/// client library has not been initialized
#define EPERS_NOT_INITIALIZED (-32)
-// max buffer size
+/// max buffer size
#define EPERS_MAX_BUFF_SIZE (-33)
-// failed to setup dbus mainloop
+/// failed to setup dbus mainloop
#define EPERS_DBUS_MAINLOOP (-34)
-// failed register lifecycle dbus
+/// failed register lifecycle dbus
#define EPERS_REGISTER_LIFECYCLE (-35)
-// failed register admin service dbus
+/// failed register admin service dbus
#define EPERS_REGISTER_ADMIN (-36)
-// registration on this key is not allowed
+/// registration on this key is not allowed
#define EPERS_NOTIFY_NOT_ALLOWED (-37)
-// the requested resource is not a file
+/// the requested resource is not a file
#define EPERS_RESOURCE_NO_FILE (-38)
-// write to requested resource failed, read onyl resource
+/// write to requested resource failed, read only resource
#define EPERS_RESOURCE_READ_ONLY (-39)
+/// max numbers of cancel shutdown exceeded
+#define EPERS_SHTDWN_MAX_CANCEL (-40)
+/// not permitted to use this function
+#define EPERS_SHTDWN_NO_PERMIT (-42)
#ifdef __cplusplus
}
static int gShutdownMode = 0;
+static int gCancelCounter = 0;
+
int pclInitLibrary(const char* appName, int shutdownMode)
{
DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("pclInit => Failed to load custom library config table => error number:"), DLT_INT(status));
}
+ pers_unlock_access();
+
// assign application name
strncpy(gAppId, appName, MaxAppNameLen);
gAppId[MaxAppNameLen-1] = '\0';
}
}
- // close all apend rct
- pers_rct_close_all();
-
- // close opend database
- database_close_all();
-
- // close persistence handles
- close_all_persistence_handle();
+ process_prepare_shutdown(Shutdown_Full); // close all db and fd's and block access
// end dbus library
bContinue = 0;
+int pclLifecycleSet(int shutdown)
+{
+ int rval = 0;
+
+ if(gShutdownMode == PCL_SHUTDOWN_TYPE_NONE)
+ {
+ if(PCL_SHUTDOWN)
+ {
+ process_prepare_shutdown(Shutdown_Partial); // close all db and fd's and block access
+ }
+ else if(PCL_SHUTDOWN_CANEL)
+ {
+ if(gCancelCounter < Shutdown_MaxCount)
+ {
+ pers_unlock_access();
+ }
+ else
+ {
+ rval = EPERS_SHTDWN_MAX_CANCEL;
+ }
+ }
+ else
+ {
+ rval = EPERS_COMMON;
+ }
+ }
+ else
+ {
+ rval = EPERS_SHTDWN_NO_PERMIT;
+ }
+
+return rval;
+}
+
FileClosed = 0, /// flag to identify if file will be closed
FileOpen = 1, /// flag to identify if file has been opend
+ Shutdown_Partial = 0, /// make partial Shutdown (close but not free everything)
+ Shutdown_Full = 1, /// make complete Shutdown (close and free everything)
+ Shutdown_MaxCount = 3, /// max number of shutdown cancel calls
+
NsmShutdownNormal = 1, /// lifecycle shutdown normal
NsmErrorStatus_OK = 1, /// lifecycle return OK idicator
NsmErrorStatus_Fail = -1, /// lifecycle return failed indicator
#include "persistence_client_library_db_access.h"
#include <dlfcn.h>
+#include <errno.h>
// function prototype
-void process_prepare_shutdown(unsigned char requestId, unsigned int status)
+void process_prepare_shutdown(int complete)
{
- int i = 0;
-
- (void)requestId;
- (void)status;
+ int i = 0, rval = 0;
// block write
pers_lock_access();
if(gOpenFdArray[tmp] == FileOpen)
{
fsync(tmp);
- close(tmp);
+
+#if USE_FILECACHE
+ rval = pfcCloseFile(tmp);
+#else
+ if(complete > 0)
+ {
+ rval = close(tmp);
+ }
+#endif
+ if(rval == -1)
+ {
+ DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("process_prepare_shutdown => failed to close file: "), DLT_STRING(strerror(errno)) );
+ }
+
}
}
// close opend database
database_close_all();
-
- // unload custom client libraries
- for(i=0; i<PersCustomLib_LastEntry; i++)
+ if(complete > 0)
{
- if(gPersCustomFuncs[i].custom_plugin_deinit != NULL)
- {
- // deinitialize plugin
- gPersCustomFuncs[i].custom_plugin_deinit();
- // close library handle
- dlclose(gPersCustomFuncs[i].handle);
+ close_all_persistence_handle();
+ }
- invalidate_custom_plugin(i);
- }
+
+ if(complete > 0)
+ {
+ // unload custom client libraries
+ for(i=0; i<PersCustomLib_LastEntry; i++)
+ {
+ if(gPersCustomFuncs[i].custom_plugin_deinit != NULL)
+ {
+ // deinitialize plugin
+ gPersCustomFuncs[i].custom_plugin_deinit();
+ // close library handle
+ dlclose(gPersCustomFuncs[i].handle);
+
+ invalidate_custom_plugin(i);
+ }
+ }
}
}
/**
* @brief process a shutdown message (close all open files, open databases, ...
- *
- * @param requestId the requestID
- * @param status the status
*/
-void process_prepare_shutdown(unsigned char requestId, unsigned int status);
+void process_prepare_shutdown(int complete);
/**
process_send_pas_request(conn, (buf[2]), buf[1]);
break;
case CMD_LC_PREPARE_SHUTDOWN:
- process_prepare_shutdown((buf[2]), buf[1]);
+ process_prepare_shutdown(Shutdown_Full);
process_send_lifecycle_request(conn, (buf[2]), buf[1]);
break;
case CMD_SEND_NOTIFY_SIGNAL: