From 47e5a424c8ef6e33565737f20d3bd81f69c8efc9 Mon Sep 17 00:00:00 2001 From: Cosmin Cernat Date: Tue, 7 Jun 2016 19:07:58 +0300 Subject: PAS Vers. 1.0.8 - Fixed bug 437 - pas daemon stops triggering the system.d watchdog after changing system time Change-Id: I066ce314e4382df2565e4aafad3049648743bf07 Signed-off-by: Cosmin Cernat --- Administrator/src/ssw_pers_admin_dbus.c | 618 ++++--- .../src/ssw_pers_admin_resource_config_add.c | 55 +- Administrator/src/ssw_pers_admin_service.c | 1736 ++++++++++---------- ChangeLog | 20 +- configure.ac | 4 +- 5 files changed, 1284 insertions(+), 1149 deletions(-) diff --git a/Administrator/src/ssw_pers_admin_dbus.c b/Administrator/src/ssw_pers_admin_dbus.c index 0214642..e24ec93 100644 --- a/Administrator/src/ssw_pers_admin_dbus.c +++ b/Administrator/src/ssw_pers_admin_dbus.c @@ -11,14 +11,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Date Author Reason -* 2013-09-17 uidu0250 CSP_WZ#5633: Wait for NSM to start before registration. -* 2013-03-09 uidu0250 CSP_WZ#4480: Added persadmin_QuitDBusMainLoop function -* 2013-04-04 uidu0250 CSP_WZ#2739: Moved PAS<->PCL communication to common part under PersCommonIPC. -* 2013.03.26 uidu0250 CSP_WZ#3171: Update PAS registration to NSM -* 2013.02.15 uidu0250 CSP_WZ#8849: Modified PAS<->PCL communication interface -* 2013.02.04 uidu0250 CSP_WZ#2211: Rework for QAC compliancy -* 2012.11.28 uidu0250 CSP_WZ#1280: Updated implementation according to the updated org.genivi.persistence.admin interface -* 2012.11.13 uidu0250 CSP_WZ#1280: Initial version +* 2016-06-02 Cosmin Cernat Bugzilla Bug 437: Used glib for watchdog re-triggering +* 2013-09-17 Petrica Manoila CSP_WZ#5633: Wait for NSM to start before registration. +* 2013-03-09 Petrica Manoila CSP_WZ#4480: Added persadmin_QuitDBusMainLoop function +* 2013-04-04 Petrica Manoila CSP_WZ#2739: Moved PAS<->PCL communication to common part under PersCommonIPC. +* 2013.03.26 Petrica Manoila CSP_WZ#3171: Update PAS registration to NSM +* 2013.02.15 Petrica Manoila CSP_WZ#8849: Modified PAS<->PCL communication interface +* 2013.02.04 Petrica Manoila CSP_WZ#2211: Rework for QAC compliancy +* 2012.11.28 Petrica Manoila CSP_WZ#1280: Updated implementation according to the updated org.genivi.persistence.admin interface +* 2012.11.13 Petrica Manoila CSP_WZ#1280: Initial version * **********************************************************************************************************************/ @@ -28,6 +29,7 @@ #include #include #include +#include /* Systemd wdog */ #include "persComErrors.h" @@ -44,7 +46,10 @@ * **********************************************************************************************************************/ -#define PAS_SHUTDOWN_TIMEOUT 60000 /* ms */ +#define ONE_SEC_IN_US ((uint64_t)1000000) /* microseconds */ +#define ONE_SEC_IN_MS (uint64_t)(1000) /* ms */ +#define PAS_WATCHDOG_TIMEOUT_DEFAULT_VALUE_US ((uint64_t)(5 * ONE_SEC_IN_US)) /* microseconds */ +#define PAS_SHUTDOWN_TIMEOUT_MS (60 * ONE_SEC_IN_MS) /* 60 sec */ /********************************************************************************************************************** * @@ -53,13 +58,13 @@ **********************************************************************************************************************/ DLT_IMPORT_CONTEXT(persAdminSvcDLTCtx); -static GMainLoop *g_pMainLoop = NIL; -static GDBusConnection *g_pBusConnection = NIL; -static NodeStateLifeCycleConsumerSkeleton *g_pNSLCSkeleton = NIL; -static NodeStateConsumerProxy *g_pNSCProxy = NIL; +static GMainLoop *g_pMainLoop = NIL; +static GDBusConnection *g_pBusConnection = NIL; +static NodeStateLifeCycleConsumerSkeleton *g_pNSLCSkeleton = NIL; +static NodeStateConsumerProxy *g_pNSCProxy = NIL; -static volatile bool_t g_bDBusConnInit = false; -static bool_t g_bRegisteredToNSM = false; /* registration to NSM status */ +static volatile bool_t g_bDBusConnInit = false; +static bool_t g_bRegisteredToNSM = false; /* registration to NSM status */ /********************************************************************************************************************** @@ -68,21 +73,36 @@ static bool_t g_bRegisteredToNSM = false; /* registration to NSM statu * **********************************************************************************************************************/ -static void OnBusAcquired_cb( GDBusConnection *connection, const gchar *name, gpointer user_data); -static void OnNameAcquired_cb( GDBusConnection *connection, const gchar *name, gpointer user_data); -static void OnNameLost_cb( GDBusConnection *connection, const gchar *name, gpointer user_data); -static void OnNameAppeared( GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data); +static void OnBusAcquired_cb( GDBusConnection *connection, const gchar *name, gpointer user_data); +static void OnNameAcquired_cb( GDBusConnection *connection, const gchar *name, gpointer user_data); +static void OnNameLost_cb( GDBusConnection *connection, const gchar *name, gpointer user_data); +static void OnNameAppeared( GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data); -/* LifecycleRequest */ -static gboolean OnHandleLifecycleRequest ( NodeStateLifeCycleConsumer *object, - GDBusMethodInvocation *invocation, - guint arg_Request, - guint arg_RequestId); +/* LifecycleRequest DBus handler - signature based on generated code */ +static gboolean OnHandleLifecycleRequest(NodeStateLifeCycleConsumer *object, + GDBusMethodInvocation *invocation, + guint arg_Request, + guint arg_RequestId); -/* ExportNSMConsumerIF */ -static bool_t ExportNSMConsumerIF(GDBusConnection *connection); +/* Export NSM Consumer IF on DBus */ +static bool_t persadmin_ExportNSMConsumerIF(GDBusConnection *connection); +/** + * \brief Get re-trigger rate from environment variable (from .service file) + * + * \return re-trigger rate (in seconds) + **/ +static uint32_t persadmin_GetWdogRetriggerRate(void); + +/** + * \brief Performs WDOG re-triggering based on the value defined + * + * \param user_data : unused, can be NIL + * + * \return TRUE if successfulls, FALSE otherwise + */ +static gboolean persadmin_WDogRetriggerCB(gpointer user_data); /********************************************************************************************************************** @@ -97,23 +117,23 @@ static bool_t ExportNSMConsumerIF(GDBusConnection *connection); * \return void * **********************************************************************************************************************/ -static void OnBusAcquired_cb( GDBusConnection *connection, - const gchar *name, - gpointer user_data) +static void OnBusAcquired_cb(GDBusConnection *connection, + const gchar *name, + gpointer user_data) { - bool_t bRetVal; + bool_t bRetVal; - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Successfully connected to D-Bus.")); + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Successfully connected to D-Bus.")); - /* Store the connection. */ - g_pBusConnection = connection; + /* Store the connection. */ + g_pBusConnection = connection; - /* Export the org.genivi.NodeStateManager.LifeCycleConsumer interface over DBus trough the PAS object */ - bRetVal = ExportNSMConsumerIF(connection); - if(true == bRetVal) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Successfully connected to D-Bus and exported object.")); - } + /* Export the org.genivi.NodeStateManager.LifeCycleConsumer interface over DBus trough the PAS object */ + bRetVal = persadmin_ExportNSMConsumerIF(connection); + if(true == bRetVal) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Successfully connected to D-Bus and exported object.")); + } } @@ -130,15 +150,25 @@ static void OnBusAcquired_cb( GDBusConnection *connection, * **********************************************************************************************************************/ -static void OnNameAcquired_cb( GDBusConnection *connection, - const gchar *name, - gpointer user_data) +static void OnNameAcquired_cb(GDBusConnection *connection, + const gchar *name, + gpointer user_data) { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Successfully obtained D-Bus name:"); - DLT_STRING(name)); + uint32_t u32RetriggerRate; + + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Successfully obtained D-Bus name:"); + DLT_STRING(name)); + + /* Get watchdog retrigger rate */ + u32RetriggerRate = persadmin_GetWdogRetriggerRate(); + + /* Add WDOG re-triggering callback */ + g_timeout_add( u32RetriggerRate * ONE_SEC_IN_MS, + &persadmin_WDogRetriggerCB, + NIL); - /* DBus connection initialized */ - g_bDBusConnInit = true; + /* DBus connection initialized */ + g_bDBusConnInit = true; } @@ -156,28 +186,28 @@ static void OnNameAcquired_cb( GDBusConnection *connection, * \return void * **********************************************************************************************************************/ -static void OnNameLost_cb( GDBusConnection *connection, - const gchar *name, - gpointer user_data ) +static void OnNameLost_cb(GDBusConnection *connection, + const gchar *name, + gpointer user_data ) { - if(connection == NIL) - { - /* Error: the connection could not be established. */ - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to establish D-Bus connection.")); - } - else - { - /* Error: connection established, but name not obtained. This might be a second instance of the application */ - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to obtain bus name "); - DLT_STRING(name); - DLT_STRING(".")); - } - - /* In both cases leave the main loop. */ - g_main_loop_quit(g_pMainLoop); - - /* DBus connection lost */ - g_bDBusConnInit = false; + if(connection == NIL) + { + /* Error: the connection could not be established. */ + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to establish D-Bus connection.")); + } + else + { + /* Error: connection established, but name not obtained. This might be a second instance of the application */ + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to obtain bus name "); + DLT_STRING(name); + DLT_STRING(".")); + } + + /* In both cases leave the main loop. */ + g_main_loop_quit(g_pMainLoop); + + /* DBus connection lost */ + g_bDBusConnInit = false; } @@ -193,71 +223,72 @@ static void OnNameLost_cb( GDBusConnection *connection, * \return void * **********************************************************************************************************************/ -static void OnNameAppeared( GDBusConnection *connection, - const gchar *name, - const gchar *name_owner, - gpointer user_data ) +static void OnNameAppeared(GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data ) { - GError *pError = NIL; - gboolean gbRetVal; - gint gErrorCode = NsmErrorStatus_NotSet; - - if(false == g_bRegisteredToNSM) - { - /* Register to NSM as shutdown client */ - g_pNSCProxy = NIL; - g_pNSCProxy = (NodeStateConsumerProxy *) node_state_consumer_proxy_new_sync(g_pBusConnection, - G_DBUS_PROXY_FLAGS_NONE, - NSM_BUS_NAME, - NSM_CONSUMER_OBJECT, - NIL, - &pError); - if(NIL == g_pNSCProxy) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_DEBUG, DLT_STRING("Failed to create proxy for NSC. Error :"), - DLT_STRING(pError->message)); - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to register to NSM as shutdown client.")); - g_error_free (pError); - } - else - { - /* Synchronous call to "RegisterShutdownClient" */ - gbRetVal = node_state_consumer_call_register_shutdown_client_sync( (NodeStateConsumer *)g_pNSCProxy, - PERSISTENCE_ADMIN_SVC_BUS_NAME, - PERSISTENCE_ADMIN_SVC_OBJ_PATH, - NSM_SHUTDOWNTYPE_NORMAL|NSM_SHUTDOWNTYPE_FAST, - PAS_SHUTDOWN_TIMEOUT, - &gErrorCode, - NIL, - &pError); - if(FALSE == gbRetVal) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_DEBUG, DLT_STRING("RegisterShutdownClient call failed. Error :"), - DLT_STRING(pError->message)); - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to register to NSM as shutdown client.")); - - g_error_free (pError); - g_object_unref(g_pNSCProxy); - g_pNSCProxy = NIL; - } - else - { - if(NsmErrorStatus_Ok != gErrorCode) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to register to NSM as shutdown client. Error code :"), - DLT_INT(gErrorCode)); - g_object_unref(g_pNSCProxy); - g_pNSCProxy = NIL; - } - else - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Successfully registered to NSM as shutdown client.")); - - g_bRegisteredToNSM = true; - } - } - } - } + GError *pError = NIL; + gboolean gbRetVal; + gint gErrorCode = NsmErrorStatus_NotSet; + + if(false == g_bRegisteredToNSM) + { + /* Register to NSM as shutdown client */ + g_pNSCProxy = NIL; + g_pNSCProxy = (NodeStateConsumerProxy *) node_state_consumer_proxy_new_sync(g_pBusConnection, + G_DBUS_PROXY_FLAGS_NONE, + NSM_BUS_NAME, + NSM_CONSUMER_OBJECT, + NIL, + &pError); + if(NIL == g_pNSCProxy) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_DEBUG, DLT_STRING("Failed to create proxy for NSC. Error :"), + DLT_STRING(pError->message)); + + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to register to NSM as shutdown client.")); + g_error_free (pError); + } + else + { + /* Synchronous call to "RegisterShutdownClient" */ + gbRetVal = node_state_consumer_call_register_shutdown_client_sync( (NodeStateConsumer *)g_pNSCProxy, + PERSISTENCE_ADMIN_SVC_BUS_NAME, + PERSISTENCE_ADMIN_SVC_OBJ_PATH, + NSM_SHUTDOWNTYPE_NORMAL|NSM_SHUTDOWNTYPE_FAST, + PAS_SHUTDOWN_TIMEOUT_MS, + &gErrorCode, + NIL, + &pError); + if(FALSE == gbRetVal) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_DEBUG, DLT_STRING("RegisterShutdownClient call failed. Error :"), + DLT_STRING(pError->message)); + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to register to NSM as shutdown client.")); + + g_error_free (pError); + g_object_unref(g_pNSCProxy); + g_pNSCProxy = NIL; + } + else + { + if(NsmErrorStatus_Ok != gErrorCode) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to register to NSM as shutdown client. Error code :"), + DLT_INT(gErrorCode)); + g_object_unref(g_pNSCProxy); + g_pNSCProxy = NIL; + } + else + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Successfully registered to NSM as shutdown client.")); + + g_bRegisteredToNSM = true; + } + } + } + } } /********************************************************************************************************************** @@ -266,54 +297,54 @@ static void OnNameAppeared( GDBusConnection *connection, * Signature based on generated code. * **********************************************************************************************************************/ -static gboolean OnHandleLifecycleRequest ( NodeStateLifeCycleConsumer *object, - GDBusMethodInvocation *invocation, - guint arg_Request, - guint arg_RequestId) +static gboolean OnHandleLifecycleRequest(NodeStateLifeCycleConsumer *object, + GDBusMethodInvocation *invocation, + guint arg_Request, + guint arg_RequestId) { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Received NSM shutdown notification.")); - - /* send a NsmErrorStatus_ResponsePending response and wait for PAS to - * finish any operation in progress */ - node_state_life_cycle_consumer_complete_lifecycle_request( object, - invocation, - NsmErrorStatus_ResponsePending); - - - if( (0 != (NSM_SHUTDOWNTYPE_NORMAL & arg_Request)) || - (0 != (NSM_SHUTDOWNTYPE_FAST & arg_Request))) - { - /* set shutdown state and wait for the current operation to finish*/ - /* Any other PAS request is denied after this point - * (unless a cancel shutdown notification is received) - */ - (void)persadmin_set_shutdown_state(true); - } - else - { - if(0 != (NSM_SHUTDOWNTYPE_RUNUP & arg_Request)) - { - (void)persadmin_set_shutdown_state(false); - } - else - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_WARN, DLT_STRING("Invalid NSM notification received:"), - DLT_UINT(arg_Request)); - } - } - - - /* Notify NSM that the request was finished */ - node_state_consumer_call_lifecycle_request_complete((NodeStateConsumer *)g_pNSCProxy, - arg_RequestId, - NsmErrorStatus_Ok, - NIL, - NIL, - NIL); - - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Finished preparing for shutdown.")); - - return (TRUE); + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Received NSM shutdown notification.")); + + /* send a NsmErrorStatus_ResponsePending response and wait for PAS to + * finish any operation in progress */ + node_state_life_cycle_consumer_complete_lifecycle_request( object, + invocation, + NsmErrorStatus_ResponsePending); + + + if( (0 != (NSM_SHUTDOWNTYPE_NORMAL & arg_Request)) || + (0 != (NSM_SHUTDOWNTYPE_FAST & arg_Request))) + { + /* set shutdown state and wait for the current operation to finish*/ + /* Any other PAS request is denied after this point + * (unless a cancel shutdown notification is received) + */ + (void)persadmin_set_shutdown_state(true); + } + else + { + if(0 != (NSM_SHUTDOWNTYPE_RUNUP & arg_Request)) + { + (void)persadmin_set_shutdown_state(false); + } + else + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_WARN, DLT_STRING("Invalid NSM notification received:"), + DLT_UINT(arg_Request)); + } + } + + + /* Notify NSM that the request was finished */ + node_state_consumer_call_lifecycle_request_complete((NodeStateConsumer *)g_pNSCProxy, + arg_RequestId, + NsmErrorStatus_Ok, + NIL, + NIL, + NIL); + + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Finished preparing for shutdown.")); + + return (TRUE); }/*DG C8ISQP-ISQP Metric 10-SSW_Administrator_0001*/ @@ -327,29 +358,81 @@ static gboolean OnHandleLifecycleRequest ( NodeStateLifeCycleConsumer *object, * \return true if successful, false otherwise * **********************************************************************************************************************/ -static bool_t ExportNSMConsumerIF(GDBusConnection *connection) +static bool_t persadmin_ExportNSMConsumerIF(GDBusConnection *connection) { - GError *pError = NIL; - - /* Create object to offer on the DBus (for NSMConsumer) */ - g_pNSLCSkeleton = (NodeStateLifeCycleConsumerSkeleton*) node_state_life_cycle_consumer_skeleton_new(); - - (void)g_signal_connect(g_pNSLCSkeleton, "handle-lifecycle-request", G_CALLBACK(&OnHandleLifecycleRequest), NIL); - - /* Attach interface to the object and export it */ - if(FALSE == g_dbus_interface_skeleton_export( G_DBUS_INTERFACE_SKELETON(g_pNSLCSkeleton), - g_pBusConnection, - PERSISTENCE_ADMIN_SVC_OBJ_PATH, - &pError)) - { - /* Error: NSM Consumer object could not be exported. */ - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to export LifeCycleConsumer interface. Error :"), - DLT_STRING(pError->message)); - g_error_free(pError); - return false; - } - - return true; + GError *pError = NIL; + + /* Create object to offer on the DBus (for NSMConsumer) */ + g_pNSLCSkeleton = (NodeStateLifeCycleConsumerSkeleton*) node_state_life_cycle_consumer_skeleton_new(); + + (void)g_signal_connect(g_pNSLCSkeleton, "handle-lifecycle-request", G_CALLBACK(&OnHandleLifecycleRequest), NIL); + + /* Attach interface to the object and export it */ + if(FALSE == g_dbus_interface_skeleton_export( G_DBUS_INTERFACE_SKELETON(g_pNSLCSkeleton), + g_pBusConnection, + PERSISTENCE_ADMIN_SVC_OBJ_PATH, + &pError)) + { + /* Error: NSM Consumer object could not be exported. */ + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to export LifeCycleConsumer interface. Error :"), + DLT_STRING(pError->message)); + g_error_free(pError); + return false; + } + + return true; +} + + +static uint32_t persadmin_GetWdogRetriggerRate(void) +{ + const char *sWdogUSec = NIL; + uint64_t u64WdogUSec = 0; + + sWdogUSec = getenv("WATCHDOG_USEC"); + if(NIL == sWdogUSec) + { + /* use default watchdog re-trigger rate */ + u64WdogUSec = PAS_WATCHDOG_TIMEOUT_DEFAULT_VALUE_US; + + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Using default watchdog re-trigger rate :"); + DLT_UINT64(u64WdogUSec / 1000); + DLT_STRING("ms.")); + } + else + { + u64WdogUSec = strtoul(sWdogUSec, NULL, 10); + + /* The min. valid value for systemd is 1 s => WATCHDOG_USEC at least needs to contain 1.000.000 us */ + if(u64WdogUSec < ONE_SEC_IN_US) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Error: Invalid WDOG config: WATCHDOG_USEC:"); + DLT_STRING(sWdogUSec); + DLT_STRING(".Using default watchdog re-trigger rate :"); + DLT_UINT32(PAS_WATCHDOG_TIMEOUT_DEFAULT_VALUE_US / 1000); + DLT_STRING("ms")); + + u64WdogUSec = PAS_WATCHDOG_TIMEOUT_DEFAULT_VALUE_US; + } + else + { + u64WdogUSec /= 2; + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("WDOG retrigger rate [ms]:"); + DLT_UINT32(u64WdogUSec/1000)); + } + } + + return (uint32_t)(u64WdogUSec / ONE_SEC_IN_US); +} + + +static gboolean persadmin_WDogRetriggerCB(gpointer user_data) +{ + sd_notify(0, "WATCHDOG=1"); + + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Triggered systemd WDOG")); + + return (TRUE); } @@ -360,63 +443,64 @@ static bool_t ExportNSMConsumerIF(GDBusConnection *connection) */ void persadmin_RunDBusMainLoop(void) { - uint32_t u32ConnectionId; - guint watcherId; - GBusNameWatcherFlags flags = G_BUS_NAME_WATCHER_FLAGS_NONE; - - /* Initialize GLib */ - g_type_init(); /* deprecated. Since GLib 2.36, the type system is initialized automatically and this function does nothing.*/ - - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Creating a new DBus connection...")); - - /* Connect to the D-Bus. Obtain a bus name to offer PAS objects */ - u32ConnectionId = g_bus_own_name( PERSISTENCE_ADMIN_SVC_BUS_TYPE - , PERSISTENCE_ADMIN_SVC_BUS_NAME - , G_BUS_NAME_OWNER_FLAGS_NONE - , &OnBusAcquired_cb - , &OnNameAcquired_cb - , &OnNameLost_cb - , NIL - , NIL); - - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("D-Bus connection Id: "), DLT_UINT32(u32ConnectionId)); - - /* Watch the NSM bus name */ - watcherId = g_bus_watch_name ( PERSISTENCE_ADMIN_SVC_BUS_TYPE, /* NSM uses the same bus type as PAS */ - NSM_BUS_NAME, - flags, - &OnNameAppeared, - NIL, - NIL, - NIL); - - /* Create the main loop */ - g_pMainLoop = g_main_loop_new(NIL, FALSE); - - /* The main loop is only canceled if the Node is completely shut down or the D-Bus connection fails */ - g_main_loop_run(g_pMainLoop); - - g_bus_unwatch_name (watcherId); - - /* If the main loop returned, clean up. Release bus name and main loop */ - g_bus_unown_name(u32ConnectionId); - - g_main_loop_unref(g_pMainLoop); - g_pMainLoop = NIL; - - /* Release the (created) skeleton object */ - if(NIL != g_pNSLCSkeleton) - { - g_object_unref(g_pNSLCSkeleton); - g_pNSLCSkeleton = NIL; - } - - /* Release the (created) proxy object */ - if(NIL != g_pNSCProxy) - { - g_object_unref(g_pNSCProxy); - g_pNSCProxy = NIL; - } + uint32_t u32ConnectionId; + guint watcherId; + + GBusNameWatcherFlags flags = G_BUS_NAME_WATCHER_FLAGS_NONE; + + /* Initialize GLib */ + g_type_init(); /* deprecated. Since GLib 2.36, the type system is initialized automatically and this function does nothing.*/ + + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Creating a new DBus connection...")); + + /* Connect to the D-Bus. Obtain a bus name to offer PAS objects */ + u32ConnectionId = g_bus_own_name( PERSISTENCE_ADMIN_SVC_BUS_TYPE + , PERSISTENCE_ADMIN_SVC_BUS_NAME + , G_BUS_NAME_OWNER_FLAGS_NONE + , &OnBusAcquired_cb + , &OnNameAcquired_cb + , &OnNameLost_cb + , NIL + , NIL); + + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("D-Bus connection Id: "), DLT_UINT32(u32ConnectionId)); + + /* Watch the NSM bus name */ + watcherId = g_bus_watch_name ( PERSISTENCE_ADMIN_SVC_BUS_TYPE, /* NSM uses the same bus type as PAS */ + NSM_BUS_NAME, + flags, + &OnNameAppeared, + NIL, + NIL, + NIL); + + /* Create the main loop */ + g_pMainLoop = g_main_loop_new(NIL, FALSE); + + /* The main loop is only canceled if the Node is completely shut down or the D-Bus connection fails */ + g_main_loop_run(g_pMainLoop); + + g_bus_unwatch_name (watcherId); + + /* If the main loop returned, clean up. Release bus name and main loop */ + g_bus_unown_name(u32ConnectionId); + + g_main_loop_unref(g_pMainLoop); + g_pMainLoop = NIL; + + /* Release the (created) skeleton object */ + if(NIL != g_pNSLCSkeleton) + { + g_object_unref(g_pNSLCSkeleton); + g_pNSLCSkeleton = NIL; + } + + /* Release the (created) proxy object */ + if(NIL != g_pNSCProxy) + { + g_object_unref(g_pNSCProxy); + g_pNSCProxy = NIL; + } } @@ -427,14 +511,14 @@ void persadmin_RunDBusMainLoop(void) */ void persadmin_QuitDBusMainLoop(void) { - if(true == g_bDBusConnInit) - { - if(NIL != g_pMainLoop) - { - g_main_loop_quit(g_pMainLoop); - g_bDBusConnInit = false; - } - } + if(true == g_bDBusConnInit) + { + if(NIL != g_pMainLoop) + { + g_main_loop_quit(g_pMainLoop); + g_bDBusConnInit = false; + } + } } @@ -443,8 +527,8 @@ void persadmin_QuitDBusMainLoop(void) * * \return true if registered to NSM, false otherwise */ -bool_t persadmin_IsRegisteredToNSM(void) +bool_t persadmin_IsRegisteredToNSM(void) { - return g_bRegisteredToNSM; + return g_bRegisteredToNSM; } diff --git a/Administrator/src/ssw_pers_admin_resource_config_add.c b/Administrator/src/ssw_pers_admin_resource_config_add.c index c49efa6..973bfca 100644 --- a/Administrator/src/ssw_pers_admin_resource_config_add.c +++ b/Administrator/src/ssw_pers_admin_resource_config_add.c @@ -11,18 +11,19 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Date Author Reason -* 2013.10.23 uidl9757 CSP_WZ#6300: Installation of the default values in context of the custom keys not working -* 2013.09.27 uidl9757 CSP_WZ#5781: Fix memory leakage -* 2013.09.23 uidl9757 CSP_WZ#5781: Watchdog timeout of pas-daemon -* 2013.06.07 uidl9757 CSP_WZ#4260: Variable sContext of type pas_cfg_instFoldCtx_s is not initialized. -* 2013.04.12 uidl9757 CSP_WZ#3450: Fix SCC warnings -* 2013.04.02 uidl9757 CSP_WZ#2798: Fix some of review findings -* 2013.03.21 uidl9757 CSP_WZ#2798: Complete rework to allow configuration based on json files -* 2012.12.13 uidl9757 CSP_WZ#1280: Update according to new detailed description: - https://workspace1.conti.de/content/00002483/Team%20Documents/01%20Technical%20Documentation - /04%20OIP/20_SW_Packages/03_Persistence/Administration_Service - /Configure%20and%20initialize%20data%20and%20policy%20for%20new%20application%20-%20questions.doc -* 2012.11.29 uidl9757 CSP_WZ#1280: Created +* 2016-06-02 Cosmin Cernat Bugzilla Bug 437: Moved WDOG re-triggering to glib loop +* 2013.10.23 Ionut Ieremie CSP_WZ#6300: Installation of the default values in context of the custom keys not working +* 2013.09.27 Ionut Ieremie CSP_WZ#5781: Fix memory leakage +* 2013.09.23 Ionut Ieremie CSP_WZ#5781: Watchdog timeout of pas-daemon +* 2013.06.07 Ionut Ieremie CSP_WZ#4260: Variable sContext of type pas_cfg_instFoldCtx_s is not initialized. +* 2013.04.12 Ionut Ieremie CSP_WZ#3450: Fix SCC warnings +* 2013.04.02 Ionut Ieremie CSP_WZ#2798: Fix some of review findings +* 2013.03.21 Ionut Ieremie CSP_WZ#2798: Complete rework to allow configuration based on json files +* 2012.12.13 Ionut Ieremie CSP_WZ#1280: Update according to new detailed description: + https://workspace1.conti.de/content/00002483/Team%20Documents/01%20Technical%20Documentation + /04%20OIP/20_SW_Packages/03_Persistence/Administration_Service + /Configure%20and%20initialize%20data%20and%20policy%20for%20new%20application%20-%20questions.doc +* 2012.11.29 Ionut Ieremie CSP_WZ#1280: Created * **********************************************************************************************************************/ @@ -497,9 +498,6 @@ static sint_t pas_conf_configureDataForPublic(void) sint_t hRules = -1 ; - /* retrigger watchdog */ - persadmin_RetriggerWatchdog(); - /* initialize */ (void)memset(&sContext, 0x0, sizeof(sContext)); @@ -791,9 +789,6 @@ static sint_t pas_conf_configureDataForGroup( constpstr_t grou str_t destInstallFolder[PERSADMIN_MAX_PATH_LENGHT] ; str_t srcInstallFolder[PERSADMIN_MAX_PATH_LENGHT] ; - - /* retrigger watchdog */ - persadmin_RetriggerWatchdog(); if( (PersAdminCfgInstallRules_Uninstall == eInstallRule) || (PersAdminCfgInstallRules_NewInstall == eInstallRule)) @@ -1475,9 +1470,6 @@ static sint_t pas_conf_configureDataForApp(constpstr_t appID, PersAdminCfgInstal str_t destInstallFolder[PERSADMIN_MAX_PATH_LENGHT] ; str_t srcInstallFolder[PERSADMIN_MAX_PATH_LENGHT] ; - /* retrigger watchdog */ - persadmin_RetriggerWatchdog(); - if( (PersAdminCfgInstallRules_Uninstall == eInstallRule) || (PersAdminCfgInstallRules_NewInstall == eInstallRule)) { @@ -2775,15 +2767,8 @@ static sint_t pas_conf_updateRctForInstallFolder(pas_cfg_instFoldCtx_s* const /* first remove the obsolete resources */ sint_t iPosInList = 0 ; pstr_t pCurrentResource = NIL ; - sint_t iCurrentNumberOfResourceProcessed = 0 ; while(bEverythingOK && (iPosInList < psInstallFolderCtx->sLists.sObsoleteResources.sizeOfList)) { - if(0 == (++iCurrentNumberOfResourceProcessed)%15) /* retrigger watchdog once for every 15 resources processed*/ - { - /* retrigger watchdog */ - persadmin_RetriggerWatchdog(); - } - pCurrentResource = psInstallFolderCtx->sLists.sObsoleteResources.pList + iPosInList ; /*DG C8MR2R-MISRA-C:2004 Rule 17.4-SSW_Administrator_0006*/ if(0 <= persComRctDelete(hDestRCT, pCurrentResource)) { @@ -2809,17 +2794,10 @@ static sint_t pas_conf_updateRctForInstallFolder(pas_cfg_instFoldCtx_s* const PersistenceConfigurationKey_s sOldConfig = {PersistencePolicy_na} ; PersistenceConfigurationKey_s sNewConfig = {PersistencePolicy_na}; bool_t bIsNewRsource = false ; - sint_t iCurrentNumberOfResourceProcessed = 0 ; while(bEverythingOK && (iPosInList < psInstallFolderCtx->sLists.sSrcRCT.sizeOfList)) { bIsNewRsource = false ; pCurrentResource = psInstallFolderCtx->sLists.sSrcRCT.pList + iPosInList ; /*DG C8MR2R-MISRA-C:2004 Rule 17.4-SSW_Administrator_0006*/ - - if(0 == (++iCurrentNumberOfResourceProcessed)%15) /* retrigger watchdog once for every 15 resources processed*/ - { - /* retrigger watchdog */ - persadmin_RetriggerWatchdog(); - } if(0 <= persAdmCfgRctRead(hSrcRCT, pCurrentResource, &sNewConfig)) { @@ -2888,7 +2866,6 @@ static sint_t pas_conf_configureForDefault(pas_cfg_instFoldCtx_s* const psInstal { sint_t iPosInListOfResources = 0 ; pstr_t pCurrentResourceID = NIL ; - sint_t iCurrentNumberOfResourceProcessed = 0 ; /* for each resource in the list: * - find out which kind of configuration to apply (if any) @@ -2897,12 +2874,6 @@ static sint_t pas_conf_configureForDefault(pas_cfg_instFoldCtx_s* const psInstal { bool_t bSkipCurrentResource = false ; pas_cfg_configTypes_e eConfigTypeForResource = pas_cfg_configType_dontTouch ; - - if(0 == (++iCurrentNumberOfResourceProcessed)%15) /* retrigger watchdog once for every 15 resources processed*/ - { - /* retrigger watchdog */ - persadmin_RetriggerWatchdog(); - } pCurrentResourceID = psLists->sSrcRCT.pList + iPosInListOfResources ; /*DG C8MR2R-MISRA-C:2004 Rule 17.4-SSW_Administrator_0006*/ diff --git a/Administrator/src/ssw_pers_admin_service.c b/Administrator/src/ssw_pers_admin_service.c index 038dbbf..a020be7 100644 --- a/Administrator/src/ssw_pers_admin_service.c +++ b/Administrator/src/ssw_pers_admin_service.c @@ -11,23 +11,25 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Date Author Reason -* 2014.09.11 uidu0250 OvipRbt#8870: Fixed timeout calculation in WDOG retriggering mechanism. -* 2013.10.07 uidu0250 CSP_WZ#5965: Fixed timeout calculation for mq_timedreceive -* 2013.09.23 uidl9757 CSP_WZ#5781: Watchdog timeout of pas-daemon -* 2013.09.17 uidu0250 CSP_WZ#5633: Ignore requests received before registration to NSM -* 2013.09.03 uidu0250 CSP_WZ#4480: Implement watchdog functionality -* 2013.05.23 uidu0250 CSP_WZ#3831: Adapt PAS to be started as a service by systemd -* 2013.04.19 uidu0250 CSP_WZ#3424: Add PAS IF extension for "restore to default" -* 2013.04.04 uidu0250 CSP_WZ#2739: Using PersCommonIPC for requests to PCL -* 2013.03.26 uidu0250 CSP_WZ#3171: Update PAS registration to NSM -* 2012.11.16 uidl9757 CSP_WZ#1280: persadmin_response_msg_s: rename bResult to result and change type to long -* 2012.11.13 uidu0250 CSP_WZ#1280: Implemented DBus registration/notification mechanism -* 2012.11.12 uidl9757 CSP_WZ#1280: Created (only stubs for access lib part introduced) +* 2016.06.22 Cosmin Cernat Bugzilla Bug 437: Remove timeout calculation dependency on the system time. +* Moved WDOG re-triggering to glib loop. +* 2016.06.22 Cosmin Cernat Bugzilla Bug 437: Open existing sync objects to support a PAS restart +* 2014.09.11 Petrica Manoila OvipRbt#8870: Fixed timeout calculation in WDOG retriggering mechanism. +* 2013.10.07 Petrica Manoila CSP_WZ#5965: Fixed timeout calculation for mq_timedreceive +* 2013.09.23 Ionut Ieremie CSP_WZ#5781: Watchdog timeout of pas-daemon +* 2013.09.17 Petrica Manoila CSP_WZ#5633: Ignore requests received before registration to NSM +* 2013.09.03 Petrica Manoila CSP_WZ#4480: Implement watchdog functionality +* 2013.05.23 Petrica Manoila CSP_WZ#3831: Adapt PAS to be started as a service by systemd +* 2013.04.19 Petrica Manoila CSP_WZ#3424: Add PAS IF extension for "restore to default" +* 2013.04.04 Petrica Manoila CSP_WZ#2739: Using PersCommonIPC for requests to PCL +* 2013.03.26 Petrica Manoila CSP_WZ#3171: Update PAS registration to NSM +* 2012.11.16 Ionut Ieremie CSP_WZ#1280: persadmin_response_msg_s: rename bResult to result and change type to long +* 2012.11.13 Petrica Manoila CSP_WZ#1280: Implemented DBus registration/notification mechanism +* 2012.11.12 Ionut Ieremie CSP_WZ#1280: Created (only stubs for access lib part introduced) * **********************************************************************************************************************/ /* ---------------------- include files --------------------------------- */ -#include "persComTypes.h" #include "stdio.h" #include "string.h" #include "stdlib.h" @@ -37,15 +39,16 @@ #include "fcntl.h" #include #include -#include /* used for watchdog re-triggering */ +#include #include #include #include #include #include -#include /* Syslog messages */ -#include /* Systemd wdog */ +#include /* Syslog messages */ +#include /* Systemd wdog */ +#include "persComTypes.h" #include "persComErrors.h" #include "persistence_admin_service.h" @@ -59,44 +62,49 @@ /* ---------- local defines, macros, constants and type definitions ------------ */ /* Definition of the process name for this application. Used for logging. */ -#define PERSISTENCE_ADMIN_PROC_NAME "PersistenceAdminService" +#define PERSISTENCE_ADMIN_PROC_NAME "PersistenceAdminService" -#define LT_HDR "PAS >>" +#define LT_HDR "PAS >>" -#define INIT_PROC_PID 1 -#define ONE_SEC_IN_US (1000000U) /* microseconds */ +#define INIT_PROC_PID 1 -#define OS_SUCCESS_CODE 0 -#define OS_ERROR_CODE (-1) -#define OS_INVALID_HANDLE (-1) +#define OS_SUCCESS_CODE 0 +#define OS_ERROR_CODE (-1) +#define OS_INVALID_HANDLE (-1) -#define DAEMONIZE_FAIL_RET_VAL (-1) -#define DAEMONIZE_SUCCESS_RET_VAL 1 -#define DAEMONIZE_PARENT_RET_VAL 0 +#define DAEMONIZE_FAIL_RET_VAL (-1) +#define DAEMONIZE_SUCCESS_RET_VAL 1 +#define DAEMONIZE_PARENT_RET_VAL 0 -#define PAS_PID_FILE_NAME "pers_admin_svc.pid" -#define PAS_PID_FILE_PATH "/tmp/" PAS_PID_FILE_NAME -#define PAS_SYSPROC_PATH "/proc" -#define PAS_PID_MAX_SIZE 10 -#define PAS_PID_PROC_PATH_MAX_SIZE (PAS_PID_MAX_SIZE + 6) /* PAS_PID_MAX_SIZE + strlen(PAS_SYSPROC_PATH) + 1 */ +#define PAS_PID_FILE_NAME "pers_admin_svc.pid" +#define PAS_PID_FILE_PATH "/tmp/" PAS_PID_FILE_NAME +#define PAS_SYSPROC_PATH "/proc" +#define PAS_PID_MAX_SIZE 10 +#define PAS_PID_PROC_PATH_MAX_SIZE (PAS_PID_MAX_SIZE + 6) /* PAS_PID_MAX_SIZE + strlen(PAS_SYSPROC_PATH) + 1 */ -#define PAS_WATCHDOG_USEC_DEFAULT_VALUE (5 * ONE_SEC_IN_US) /* microseconds */ -#define PAS_ACCESS_LIB_REQ_QUEUE_TIMEOUT (50000U) /* 50 ms in microseconds */ +#define ONE_MS_IN_US ((sint64_t)1000) /* one ms in microseconds */ +#define ONE_SEC_IN_US ((sint64_t)1000 * ONE_MS_IN_US) /* one sec in microseconds */ +#define PAS_ACCESS_LIB_REQ_QUEUE_TIMEOUT_US ((sint64_t)((sint64_t)50 * ONE_MS_IN_US)) /* 50 ms in microseconds */ /* ----------global variables. initialization of global contexts ------------ */ DLT_DECLARE_CONTEXT(persAdminSvcDLTCtx); -static sint32_t g_hPASPidFile = OS_INVALID_HANDLE; +static sint32_t g_hPASPidFile = OS_INVALID_HANDLE; -static bool_t g_bOpInProgress = false; -static bool_t g_bShutdownInProgress = false; -static volatile bool_t g_bRunAccessLibThread = true; +static bool_t g_bOpInProgress = false; +static bool_t g_bShutdownInProgress = false; +static volatile bool_t g_bRunAccessLibThread = true; -static pthread_mutex_t shutdownMtx; -static pthread_cond_t shutdownCond; +static pthread_mutex_t g_shutdownMtx; +static pthread_cond_t g_shutdownCond; + +/* Access lib communication objects */ +static sem_t * g_pSyncSem = NIL; +static mqd_t g_mqdMsgQueueRequest = OS_INVALID_HANDLE; +static mqd_t g_mqdMsgQueueResponse = OS_INVALID_HANDLE; /* ---------------------- local functions declarations ---------------------------------- */ @@ -105,75 +113,97 @@ static pthread_cond_t shutdownCond; * \brief Access lib thread. Thread responsible to perform (on behalf of the clients) * the requests available in persistence_admin_service.h * - * \param arg: thread arguments + * \param arg: thread arguments * * \return NIL **/ -static void * persadmin_AccessLibThread (void *arg); +static void* persadmin_AccessLibThread (void* arg); + +/** + * \brief Initialize access lib communication objects. (to receive the requests available in persistence_admin_service.h) + * + * \return true if successful, false otherwise + **/ +static bool_t persadmin_InitAccessLibComm (void); + +/** + * \brief Close access lib communication objects. + * + * \return void + **/ +static void persadmin_CloseAccessLibComm (void); /** * \brief Process the specified request (from the requests available in persistence_admin_service.h) * - * \param psRequest: request details + * \param psRequest: request details * \param pResult_out: request result * * \return true if successful, false otherwise **/ -static bool_t persadmin_ProcessRequest (persadmin_request_msg_s* psRequest, long* pResult_out); +static bool_t persadmin_ProcessRequest (persadmin_request_msg_s* psRequest, long* pResult_out); /** * \brief The function is called from main and turns the current process into a daemon. * - * \param pProcessName: Specifies the name of the process to be daemonized. + * \param pProcessName: Specifies the name of the process to be daemonized. * * \return 0 : parent process returned; positive value: success; negative value: error **/ -static sint_t persadmin_DaemonizeProcess(pstr_t pProcessName); +static sint_t persadmin_DaemonizeProcess (pstr_t pProcessName); /** * \brief Run main daemon actions. * * \return 0 : success; negative value: error **/ -static sint_t persadmin_RunDaemon(void); +static sint_t persadmin_RunDaemon(void); /** * \brief Signal handler. * - * \param signum : signal identifier + * \param signum : signal identifier * * \return void **/ -static void persadmin_HandleTerm(int signum); +static void persadmin_HandleTerm(int signum); /** * \brief The function is called from main. It checks if the unlocks the PID file and closes the opened handles. * * \return true if the process is already running, false otherwise **/ -static bool_t persadmin_IsAlreadyRunning(void); +static bool_t persadmin_IsAlreadyRunning(void); /** * \brief The function is called from main and writes the child PID to be used by systemd * * \return true if successful, false otherwise **/ -static bool_t persadmin_LockPidFile(void); +static bool_t persadmin_LockPidFile(void); /** * \brief The function is called from main. It unlocks the PID file and closes the opened handles. * * \return void **/ -static void persadmin_EndPASProcess(void); +static void persadmin_EndPASProcess(void); + /** - * \brief Get re-trigger rate from environment variable (from .service file) + * \brief Read a message from the specified message queue. + * If there is no message in the queue, the call will block for the specified timeout, or until a message is available. * - * \return re-trigger rate (in seconds) - **/ -static uint32_t persadmin_GetWdogRetriggerRate(void); + * \param mqdes [in] message queue descriptor (obtained with mq_open) + * \param msg_ptr [out] pointer to the buffer where the message obtained is placed + * \param msg_len [in] the size of the buffer pointed to by msg_ptr, this must be greater than the mq_msgsize attribute of the queue + * + * \return on success, the number of bytes in the received message; on error, a negative value is returned; 0 is returned in case of timeout + */ +static sint_t persadmin_ReadMsgFromQueue( mqd_t mqdes, + uint8_t *msg_ptr, + size_t msg_len); /* ---------------------- public functions definition ---------------------------------- */ @@ -186,35 +216,35 @@ static uint32_t persadmin_GetWdogRetriggerRate(void); */ void persadmin_set_shutdown_state(bool_t state) { - if(OS_SUCCESS_CODE != pthread_mutex_lock(&shutdownMtx)) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); - DLT_STRING("Failed to lock the shutdown mutex. errno ="); - DLT_INT(errno));/*DG C8MR2R-MISRA-C:2004 Rule 20.5-SSW_Administrator_0003*/ - } - else - { - if(true == state) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Shutdown request received. Waiting for active operations to complete...")); - - /* wait for any pending operation */ - while (true == g_bOpInProgress) { - (void)pthread_cond_wait(&shutdownCond, &shutdownMtx); - } - - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Completed all running operations before shutdown.")); - } - else - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Shutdown canceled notification received.")); - } - - g_bShutdownInProgress = state; - - (void)pthread_mutex_unlock(&shutdownMtx); - } -}/*DG C8ISQP-ISQP Metric 10-SSW_Administrator_0001*/ + if(OS_SUCCESS_CODE != pthread_mutex_lock(&g_shutdownMtx)) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); + DLT_STRING("Failed to lock the shutdown mutex. Error :"); + DLT_STRING(strerror(errno))); + } + else + { + if(true == state) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Shutdown request received. Waiting for active operations to complete...")); + + /* wait for any pending operation */ + while (true == g_bOpInProgress) { + pthread_cond_wait(&g_shutdownCond, &g_shutdownMtx); + } + + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Completed all running operations before shutdown.")); + } + else + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Shutdown canceled notification received.")); + } + + g_bShutdownInProgress = state; + + pthread_mutex_unlock(&g_shutdownMtx); + } +} /** @@ -226,11 +256,18 @@ void persadmin_set_shutdown_state(bool_t state) */ long persadmin_resource_config_change_properties(char* resource_config_file) { - printf("persadmin_resource_config_change_properties(%s) \n", - resource_config_file) ; - printf("persadmin_resource_config_change_properties - NOT IMPLEMENTED \n") ; + if(NIL != resource_config_file) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); + DLT_STRING("persadmin_resource_config_change_properties("); + DLT_STRING(resource_config_file); + DLT_STRING(")")); + } + + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); + DLT_STRING("persadmin_resource_config_change_properties - NOT IMPLEMENTED")); - return -1 ; + return (long)PAS_FAILURE_OPERATION_NOT_SUPPORTED; } @@ -246,848 +283,879 @@ long persadmin_resource_config_change_properties(char* resource_config_file) */ long persadmin_user_data_copy(unsigned int src_user_no, unsigned int src_seat_no, unsigned int dest_user_no, unsigned int dest_seat_no) { - printf("persadmin_user_data_copy(%d %d %d %d) \n", - src_user_no, src_seat_no, dest_user_no, dest_seat_no) ; - printf("persadmin_user_data_copy - NOT IMPLEMENTED \n") ; - - return -1 ; + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); + DLT_STRING("persadmin_user_data_copy("); + DLT_UINT(src_user_no); + DLT_UINT(src_seat_no); + DLT_UINT(dest_user_no); + DLT_UINT(dest_seat_no); + DLT_STRING(")")); + + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); + DLT_STRING("persadmin_user_data_copy - NOT IMPLEMENTED")); + + return (long)PAS_FAILURE_OPERATION_NOT_SUPPORTED; } /* ---------------------- local functions definition ---------------------- */ -static bool_t persadmin_ProcessRequest(persadmin_request_msg_s* psRequest, long* pResult_out) +static bool_t persadmin_InitAccessLibComm(void) { - bool_t bEverythingOK = true; - bool_t bLockedMtx = false; - long result = -1 ; + bool_t bEverythingOK = true; + sint_t sErrnoVal; + uint_t uSemOpenFlag = (uint_t)O_CREAT | (uint_t)O_EXCL; + uint_t uSemModeFlags = (uint_t)S_IRWXU | (uint_t)S_IRWXG | (uint_t)S_IRWXO; + uint_t uQueueOpenFlag = (uint_t)O_CREAT | (uint_t)O_EXCL | (uint_t)O_RDWR; + uint_t uQueueModeFlags = (uint_t)S_IRWXU | (uint_t)S_IRWXG | (uint_t)S_IRWXO; - /* check if PAS is registered to NSM */ - if(false == persadmin_IsRegisteredToNSM()) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_WARN, DLT_STRING("Cannot process request. Not registered to NSM yet...")); - - bEverythingOK = false; - } - - - /* check if a shutdown is in progress */ - if(true == bEverythingOK) - { - if(OS_SUCCESS_CODE != pthread_mutex_lock(&shutdownMtx)) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); - DLT_STRING("Failed to lock the shutdown mutex. errno ="); - DLT_INT(errno));/*DG C8MR2R-MISRA-C:2004 Rule 20.5-SSW_Administrator_0003*/ - bEverythingOK = false; - } - else - { - bLockedMtx = true; - } - } - - if(true == bEverythingOK) - { - if(true == g_bShutdownInProgress) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_WARN, DLT_STRING("Cannot process request. Shutdown is in progress...")); - - *pResult_out = PAS_FAILURE_OS_RESOURCE_ACCESS; - - bEverythingOK = false; - } - } - - if(true == bEverythingOK) - { - g_bOpInProgress = true; - - (void)pthread_mutex_unlock(&shutdownMtx); - bLockedMtx = false; - - switch(psRequest->eRequest) - { - case PAS_Req_DataBackupCreate: - { - result = persadmin_data_backup_create(psRequest->type, psRequest->path1, psRequest->path2, psRequest->user_no, psRequest->seat_no) ; - break ; - } - case PAS_Req_DataBackupRecovery: - { - result = persadmin_data_backup_recovery(psRequest->type, psRequest->path1, psRequest->path2, psRequest->user_no, psRequest->seat_no) ; - break ; - } - case PAS_Req_DataRestoreToDefault: - { - result = persadmin_data_restore_to_default(psRequest->type, psRequest->defaultSource, psRequest->path2, psRequest->user_no, psRequest->seat_no); - break; - } - case PAS_Req_DataFolderExport: - { - result = persadmin_data_folder_export(psRequest->type, psRequest->path1) ; - break ; - } - case PAS_Req_DataFolderImport: - { - result = persadmin_data_folder_import(psRequest->type, psRequest->path1) ; - break ; - } - case PAS_Req_ResourceConfigAdd: - { - result = persadmin_resource_config_add(psRequest->path1) ; - break ; - } - case PAS_Req_ResourceConfigChangeProperties: - { - result = persadmin_resource_config_change_properties(psRequest->path1) ; - break ; - } - case PAS_Req_UserDataCopy: - { - result = persadmin_user_data_copy(psRequest->src_user_no, psRequest->src_seat_no, psRequest->dest_user_no, psRequest->dest_seat_no) ; - break ; - } - case PAS_Req_UserDataDelete: - { - result = persadmin_user_data_delete(psRequest->user_no, psRequest->seat_no) ; - break ; - } - default: - { - /* shall never happen */ - bEverythingOK = false ; - break ; - } - } - - /* operation finished */ - if(OS_SUCCESS_CODE != pthread_mutex_lock(&shutdownMtx)) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); - DLT_STRING("Failed to lock the shutdown mutex. errno ="); - DLT_INT(errno));/*DG C8MR2R-MISRA-C:2004 Rule 20.5-SSW_Administrator_0003*/ - bEverythingOK = false; - } - else - { - bLockedMtx = true; - - g_bOpInProgress = false; - - /* notify any waiting thread */ - (void)pthread_cond_broadcast(&shutdownCond); - } + struct mq_attr mq_attr_request; + struct mq_attr mq_attr_response; + mq_attr_request.mq_maxmsg = 1; /* max 1 message in the queue */ + mq_attr_request.mq_msgsize = sizeof(persadmin_request_msg_s); + mq_attr_response.mq_maxmsg = 1; /* max 1 message in the queue */ + mq_attr_response.mq_msgsize = sizeof(persadmin_response_msg_s); + + /* create access lib sync semaphore */ + g_pSyncSem = sem_open(PERSADMIN_ACCESSLIB_SYNC_SEMAPHORE, (int)uSemOpenFlag, uSemModeFlags, 1); + if(NIL == g_pSyncSem) + { + sErrnoVal = errno; + + /* ignore error in case the object already exists */ + if(EEXIST == sErrnoVal) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); + DLT_STRING("Semaphore"); + DLT_STRING(PERSADMIN_ACCESSLIB_SYNC_SEMAPHORE); + DLT_STRING("already created.")); + } + else + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); + DLT_STRING("Failed to create semaphore"); + DLT_STRING(PERSADMIN_ACCESSLIB_SYNC_SEMAPHORE); + DLT_STRING(". Error :"); + DLT_STRING(strerror(errno))); + bEverythingOK = false; + } + } + else + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); + DLT_STRING("Semaphore"); + DLT_STRING(PERSADMIN_ACCESSLIB_SYNC_SEMAPHORE); + DLT_STRING("created successfully.")); } - if(true == bLockedMtx) - { - (void)pthread_mutex_unlock(&shutdownMtx); - bLockedMtx = false; - } + /* create access lib request queue*/ + if(bEverythingOK) + { + g_mqdMsgQueueRequest = mq_open(PERSADMIN_ACCESSLIB_MSG_QUEUE_REQUEST, (int)uQueueOpenFlag, uQueueModeFlags, &mq_attr_request); + if(OS_INVALID_HANDLE == g_mqdMsgQueueRequest) + { + sErrnoVal = errno; + + /* open the existing request queue */ + if(EEXIST == sErrnoVal) + { + g_mqdMsgQueueRequest = mq_open(PERSADMIN_ACCESSLIB_MSG_QUEUE_REQUEST, O_RDWR, uQueueModeFlags, &mq_attr_request); + if(OS_INVALID_HANDLE == g_mqdMsgQueueRequest) + { + sErrnoVal = errno; + + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); + DLT_STRING("Failed to open request queue"); + DLT_STRING(PERSADMIN_ACCESSLIB_MSG_QUEUE_REQUEST); + DLT_STRING(". Error :"); + DLT_STRING(strerror(sErrnoVal))); + bEverythingOK = false; + } + else + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); + DLT_STRING("Request queue"); + DLT_STRING(PERSADMIN_ACCESSLIB_MSG_QUEUE_REQUEST); + DLT_STRING("opened successfully.")); + } + } + else + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); + DLT_STRING("Failed to open request queue"); + DLT_STRING(PERSADMIN_ACCESSLIB_MSG_QUEUE_REQUEST); + DLT_STRING(". Error :"); + DLT_STRING(strerror(sErrnoVal))); + bEverythingOK = false; + } + } + else + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); + DLT_STRING("Request queue"); + DLT_STRING(PERSADMIN_ACCESSLIB_MSG_QUEUE_REQUEST); + DLT_STRING("created successfully.")); + } + } - *pResult_out = bEverythingOK ? result : PAS_FAILURE ; + /* create access lib response queue*/ + if(bEverythingOK) + { + g_mqdMsgQueueResponse = mq_open(PERSADMIN_ACCESSLIB_MSG_QUEUE_RESPONSE, (int)uQueueOpenFlag, uQueueModeFlags, &mq_attr_response); + if(OS_INVALID_HANDLE == g_mqdMsgQueueResponse) + { + sErrnoVal = errno; + + /* open the existing response queue */ + if(EEXIST == sErrnoVal) + { + g_mqdMsgQueueResponse = mq_open(PERSADMIN_ACCESSLIB_MSG_QUEUE_RESPONSE, O_RDWR, uQueueModeFlags, &mq_attr_response); + if(OS_INVALID_HANDLE == g_mqdMsgQueueResponse) + { + sErrnoVal = errno; + + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); + DLT_STRING("Failed to open response queue"); + DLT_STRING(PERSADMIN_ACCESSLIB_MSG_QUEUE_RESPONSE); + DLT_STRING(". Error :"); + DLT_STRING(strerror(sErrnoVal))); + bEverythingOK = false; + } + else + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); + DLT_STRING("Response queue"); + DLT_STRING(PERSADMIN_ACCESSLIB_MSG_QUEUE_RESPONSE); + DLT_STRING("opened successfully.")); + } + } + else + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); + DLT_STRING("Failed to create response queue"); + DLT_STRING(PERSADMIN_ACCESSLIB_MSG_QUEUE_RESPONSE); + DLT_STRING(". Error :"); + DLT_STRING(strerror(errno))); + bEverythingOK = false; + } + } + else + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); + DLT_STRING("Response queue"); + DLT_STRING(PERSADMIN_ACCESSLIB_MSG_QUEUE_RESPONSE); + DLT_STRING("created successfully.")); + } + } return bEverythingOK; - -}/*DG C8ISQP-ISQP Metric 10-SSW_Administrator_0001*/ +} -static void * persadmin_AccessLibThread(void *arg) +static void persadmin_CloseAccessLibComm(void) { - bool_t bEverythingOK = true; + if(NIL != g_pSyncSem) + { + sem_close(g_pSyncSem); + sem_unlink(PERSADMIN_ACCESSLIB_SYNC_SEMAPHORE); + } - sem_t * pSyncSem = NIL; - mqd_t mqdMsgQueueRequest = OS_INVALID_HANDLE; - mqd_t mqdMsgQueueResponse = OS_INVALID_HANDLE; + if(OS_INVALID_HANDLE != g_mqdMsgQueueRequest) + { + mq_close(g_mqdMsgQueueRequest); + mq_unlink(PERSADMIN_ACCESSLIB_MSG_QUEUE_REQUEST); + } - persadmin_request_msg_s sRequest; - persadmin_response_msg_s sResponse; + if(OS_INVALID_HANDLE != g_mqdMsgQueueResponse) + { + mq_close(g_mqdMsgQueueResponse); + mq_unlink(PERSADMIN_ACCESSLIB_MSG_QUEUE_RESPONSE); + } +} - struct timeval timestamp = {0}; - struct timespec tsTimestamp; - struct timespec tsWdogTimestamp; - struct timespec * pTimestamp = NIL; - uint32_t u32RetriggerRate = 0; - bool_t bWDogTimeoutSet = false; +static bool_t persadmin_ProcessRequest(persadmin_request_msg_s* psRequest, long* pResult_out) +{ + bool_t bEverythingOK = true; + bool_t bLockedMtx = false; + long result = -1 ; - struct mq_attr mq_attr_request; - struct mq_attr mq_attr_response; - mq_attr_request.mq_maxmsg = 1; /* max 1 message in the queue */ - mq_attr_request.mq_msgsize = sizeof(persadmin_request_msg_s); - mq_attr_response.mq_maxmsg = 1; /* max 1 message in the queue */ - mq_attr_response.mq_msgsize = sizeof(persadmin_response_msg_s); + /* check if PAS is registered to NSM */ + if(false == persadmin_IsRegisteredToNSM()) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_WARN, DLT_STRING("Cannot process request. Not registered to NSM yet...")); + + bEverythingOK = false; + } - /* first initialize the resources */ - pSyncSem = sem_open(PERSADMIN_ACCESSLIB_SYNC_SEMAPHORE, O_CREAT|O_EXCL, S_IRWXU|S_IRWXG|S_IRWXO, 1) ; + /* check if a shutdown is in progress */ + if(true == bEverythingOK) { - if(NIL == pSyncSem) + if(OS_SUCCESS_CODE != pthread_mutex_lock(&g_shutdownMtx)) { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); - DLT_STRING("Failed to create semaphore"); - DLT_STRING(PERSADMIN_ACCESSLIB_SYNC_SEMAPHORE); - DLT_STRING(". Error :"); - DLT_STRING(strerror(errno)));/*DG C8MR2R-MISRA-C:2004 Rule 20.5-SSW_Administrator_0003*/ - bEverythingOK = false; + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); + DLT_STRING("Failed to lock the shutdown mutex. Error :"); + DLT_STRING(strerror(errno))); + bEverythingOK = false; } else { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); - DLT_STRING("Semaphore"); - DLT_STRING(PERSADMIN_ACCESSLIB_SYNC_SEMAPHORE); - DLT_STRING("created successfully.")); + bLockedMtx = true; } } - if(bEverythingOK) + if(true == bEverythingOK) { - mqdMsgQueueRequest = mq_open(PERSADMIN_ACCESSLIB_MSG_QUEUE_REQUEST, O_CREAT|O_EXCL|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO, &mq_attr_request); - if(OS_INVALID_HANDLE == mqdMsgQueueRequest) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); - DLT_STRING("Failed to open request queue"); - DLT_STRING(PERSADMIN_ACCESSLIB_MSG_QUEUE_REQUEST); - DLT_STRING(". Error :"); - DLT_STRING(strerror(errno)));/*DG C8MR2R-MISRA-C:2004 Rule 20.5-SSW_Administrator_0003*/ - bEverythingOK = false; - } - else + if(true == g_bShutdownInProgress) { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); - DLT_STRING("Request queue"); - DLT_STRING(PERSADMIN_ACCESSLIB_MSG_QUEUE_REQUEST); - DLT_STRING("created successfully.")); + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_WARN, DLT_STRING("Cannot process request. Shutdown is in progress...")); + + *pResult_out = PAS_FAILURE_OS_RESOURCE_ACCESS; + + bEverythingOK = false; } } - if(bEverythingOK) + if(true == bEverythingOK) { - mqdMsgQueueResponse = mq_open(PERSADMIN_ACCESSLIB_MSG_QUEUE_RESPONSE, O_CREAT|O_EXCL|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO, &mq_attr_response); - if(OS_INVALID_HANDLE == mqdMsgQueueResponse) + g_bOpInProgress = true; + + pthread_mutex_unlock(&g_shutdownMtx); + bLockedMtx = false; + + switch(psRequest->eRequest) + { + case PAS_Req_DataBackupCreate: + { + result = persadmin_data_backup_create(psRequest->type, psRequest->path1, psRequest->path2, psRequest->user_no, psRequest->seat_no) ; + break ; + } + case PAS_Req_DataBackupRecovery: + { + result = persadmin_data_backup_recovery(psRequest->type, psRequest->path1, psRequest->path2, psRequest->user_no, psRequest->seat_no) ; + break ; + } + case PAS_Req_DataRestoreToDefault: + { + result = persadmin_data_restore_to_default(psRequest->type, psRequest->defaultSource, psRequest->path2, psRequest->user_no, psRequest->seat_no); + break; + } + case PAS_Req_DataFolderExport: + { + result = persadmin_data_folder_export(psRequest->type, psRequest->path1) ; + break ; + } + case PAS_Req_DataFolderImport: + { + result = persadmin_data_folder_import(psRequest->type, psRequest->path1) ; + break ; + } + case PAS_Req_ResourceConfigAdd: + { + result = persadmin_resource_config_add(psRequest->path1) ; + break ; + } + case PAS_Req_ResourceConfigChangeProperties: + { + result = persadmin_resource_config_change_properties(psRequest->path1) ; + break ; + } + case PAS_Req_UserDataCopy: + { + result = persadmin_user_data_copy(psRequest->src_user_no, psRequest->src_seat_no, psRequest->dest_user_no, psRequest->dest_seat_no) ; + break ; + } + case PAS_Req_UserDataDelete: + { + result = persadmin_user_data_delete(psRequest->user_no, psRequest->seat_no) ; + break ; + } + default: + { + /* shall never happen */ + bEverythingOK = false ; + break ; + } + } + + /* operation finished */ + if(OS_SUCCESS_CODE != pthread_mutex_lock(&g_shutdownMtx)) { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); - DLT_STRING("Failed to open response queue"); - DLT_STRING(PERSADMIN_ACCESSLIB_MSG_QUEUE_RESPONSE); - DLT_STRING(". Error :"); - DLT_STRING(strerror(errno)));/*DG C8MR2R-MISRA-C:2004 Rule 20.5-SSW_Administrator_0003*/ - bEverythingOK = false; + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); + DLT_STRING("Failed to lock the shutdown mutex. Error :"); + DLT_STRING(strerror(errno))); + bEverythingOK = false; } else { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); - DLT_STRING("Response queue"); - DLT_STRING(PERSADMIN_ACCESSLIB_MSG_QUEUE_RESPONSE); - DLT_STRING("created successfully.")); + bLockedMtx = true; + + g_bOpInProgress = false; + + /* notify any waiting thread */ + pthread_cond_broadcast(&g_shutdownCond); } } - if(bEverythingOK) + if(true == bLockedMtx) + { + pthread_mutex_unlock(&g_shutdownMtx); + bLockedMtx = false; + } + + *pResult_out = bEverythingOK ? result : PAS_FAILURE ; + + return bEverythingOK; + +} + + +static void* persadmin_AccessLibThread(void* arg) +{ + bool_t bEverythingOK = true; + sint_t sFctRetVal; + + persadmin_request_msg_s sRequest; + persadmin_response_msg_s sResponse; + + /* initialize the communication channel */ + bEverythingOK = persadmin_InitAccessLibComm(); + + if(true == bEverythingOK) { - /* get watchdog retrigger rate */ - u32RetriggerRate = persadmin_GetWdogRetriggerRate(); /* everything is initialized now, so we can process requests */ while(true == g_bRunAccessLibThread) { - sint_t sErrCode; - - if(OS_ERROR_CODE == gettimeofday(×tamp, NULL)) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); - DLT_STRING("gettimeofday call failed. Error :"); - DLT_INT(errno));/*DG C8MR2R-MISRA-C:2004 Rule 20.5-SSW_Administrator_0003*/ - break; - } - else - { - if(false == bWDogTimeoutSet) - { - /* determine timeout moment in time based on the re-trigger rate */ - tsWdogTimestamp.tv_sec = timestamp.tv_sec + (__time_t)((u32RetriggerRate / ONE_SEC_IN_US) + ( (uint64_t)timestamp.tv_usec + (u32RetriggerRate % ONE_SEC_IN_US))/ONE_SEC_IN_US ); - tsWdogTimestamp.tv_nsec = (((uint64_t)timestamp.tv_usec + (u32RetriggerRate % ONE_SEC_IN_US)) % ONE_SEC_IN_US) * 1000; - bWDogTimeoutSet = true; - } - - /* determine access lib timeout moment in time */ - tsTimestamp.tv_sec = timestamp.tv_sec + (__time_t)((PAS_ACCESS_LIB_REQ_QUEUE_TIMEOUT / ONE_SEC_IN_US) + ( (uint64_t)timestamp.tv_usec + (PAS_ACCESS_LIB_REQ_QUEUE_TIMEOUT % ONE_SEC_IN_US))/ONE_SEC_IN_US ); - tsTimestamp.tv_nsec = (((uint64_t)timestamp.tv_usec + (PAS_ACCESS_LIB_REQ_QUEUE_TIMEOUT % ONE_SEC_IN_US)) % ONE_SEC_IN_US) * 1000; - - - if( (tsTimestamp.tv_sec < tsWdogTimestamp.tv_sec) || - ((tsTimestamp.tv_sec == tsWdogTimestamp.tv_sec) && (tsTimestamp.tv_nsec < tsWdogTimestamp.tv_nsec))) - { - pTimestamp = &tsTimestamp; - } - else - { - pTimestamp = &tsWdogTimestamp; - } - } - - /* wait for request */ - sErrCode = mq_timedreceive(mqdMsgQueueRequest, (char*)&sRequest, sizeof(sRequest), NIL, pTimestamp); - - switch(sErrCode) - { - case OS_ERROR_CODE: - { - if(ETIMEDOUT == errno)/*DG C8MR2R-MISRA-C:2004 Rule 20.5-SSW_Administrator_0003*/ - { - /* check if watchdog timeout was active */ - if(pTimestamp == &tsWdogTimestamp) - { - /* re-trigger watchdog */ - persadmin_RetriggerWatchdog(); - - /* reset watchdog timeout */ - bWDogTimeoutSet = false; - } - } - else - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); - DLT_STRING("Invalid request received."); - DLT_STRING("Expected"); - DLT_INT(sizeof(sRequest)); - DLT_STRING("bytes")); - g_bRunAccessLibThread = false; - } - } - break; - - case sizeof(sRequest): - { - long requestResult = -1; - sint_t sFctRetVal; - - /* re-trigger watchdog */ - persadmin_RetriggerWatchdog(); - - /* reset watchdog timeout */ - bWDogTimeoutSet = false; - - /* request received in the right format */ - sFctRetVal = persadmin_SendLockAndSyncRequestToPCL(); - if(PERS_COM_SUCCESS != sFctRetVal) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); - DLT_STRING("persadmin_SendLockAndSyncRequestToPCL call failed. Error :"); - DLT_INT(sFctRetVal)); - requestResult = PAS_FAILURE; - } - else - { - if(false == persadmin_ProcessRequest(&sRequest, &requestResult)) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); - DLT_STRING("persadmin_ProcessRequest call failed.")); - } - - (void)persadmin_SendUnlockRequestToPCL(); - } - - sResponse.result = requestResult; - - if(OS_ERROR_CODE == mq_send(mqdMsgQueueResponse, (char*)&sResponse, sizeof(sResponse), 0)) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); - DLT_STRING("Failed to send response. Error :"); - DLT_INT(errno));/*DG C8MR2R-MISRA-C:2004 Rule 20.5-SSW_Administrator_0003*/ - - g_bRunAccessLibThread = false; - } - } - break; - - default: - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); - DLT_STRING("Invalid request received. Returned"); - DLT_INT(sErrCode); - DLT_STRING("bytes. Expected"); - DLT_INT(sizeof(sRequest)); - DLT_STRING("bytes")); - g_bRunAccessLibThread = false; - } - break; - } + /* wait for request */ + sFctRetVal = persadmin_ReadMsgFromQueue(g_mqdMsgQueueRequest, (uint8_t*)&sRequest, sizeof(sRequest)); + if(sFctRetVal < PERS_COM_SUCCESS) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); + DLT_STRING("Failed waiting for access lib requests. Error :"); + DLT_INT(sFctRetVal)); + g_bRunAccessLibThread = false; + } + else + { + switch(sFctRetVal) + { + + case PERS_COM_SUCCESS: + { + /* timeout - repeat the call */ + } + break; + + case sizeof(sRequest): + { + long requestResult = -1; + sint_t sFctRetVal; + + /* request received in the right format */ + sFctRetVal = persadmin_SendLockAndSyncRequestToPCL(); + if(PERS_COM_SUCCESS != sFctRetVal) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); + DLT_STRING("persadmin_SendLockAndSyncRequestToPCL call failed. Error :"); + DLT_INT(sFctRetVal)); + requestResult = PAS_FAILURE; + } + else + { + if(false == persadmin_ProcessRequest(&sRequest, &requestResult)) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); + DLT_STRING("persadmin_ProcessRequest call failed.")); + } + + persadmin_SendUnlockRequestToPCL(); + } + + sResponse.result = requestResult; + + if(OS_ERROR_CODE == mq_send(g_mqdMsgQueueResponse, (char*)&sResponse, sizeof(sResponse), 0)) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); + DLT_STRING("Failed to send response. Error :"); + DLT_STRING(strerror(errno))); + + g_bRunAccessLibThread = false; + } + } + break; + + default: + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_WARN, DLT_STRING(LT_HDR); + DLT_STRING("Invalid request received. Returned"); + DLT_INT(sFctRetVal); + DLT_STRING("bytes. Expected"); + DLT_INT(sizeof(sRequest)); + DLT_STRING("bytes")); + /* ignore request and continue */ + } + break; + } + } } } - /* close handles */ - if(NIL != pSyncSem) - { - (void)sem_close(pSyncSem); - (void)sem_unlink(PERSADMIN_ACCESSLIB_SYNC_SEMAPHORE); - } + /* close the communication channel */ + persadmin_CloseAccessLibComm(); + + return NIL; +}/*DG C8ISQP-ISQP Metric 10-SSW_Administrator_0001*/ + - if(OS_INVALID_HANDLE != mqdMsgQueueRequest) /* && OS_ERROR_CODE != mqdMsgQueueRequest */ +static sint_t persadmin_DaemonizeProcess(pstr_t pProcessName) +{ + pid_t pid, sid; + sint_t sRetVal = DAEMONIZE_SUCCESS_RET_VAL; + + if(NIL == pProcessName) { - (void)mq_close(mqdMsgQueueRequest); - (void)mq_unlink(PERSADMIN_ACCESSLIB_MSG_QUEUE_REQUEST); + syslog(LOG_ERR, "PAS >> Invalid argument in persadmin_DaemonizeProcess call."); + + sRetVal = DAEMONIZE_FAIL_RET_VAL; } - if(OS_INVALID_HANDLE != mqdMsgQueueResponse) /* && OS_ERROR_CODE != mqdMsgQueueResponse */ + if(DAEMONIZE_SUCCESS_RET_VAL == sRetVal) { - (void)mq_close(mqdMsgQueueResponse); - (void)mq_unlink(PERSADMIN_ACCESSLIB_MSG_QUEUE_RESPONSE); - } + syslog(LOG_INFO, "PAS >> Daemon process %s starting.", pProcessName); - return NIL; -}/*DG C8ISQP-ISQP Metric 10-SSW_Administrator_0001*/ + /* Fork off the parent process */ + pid = fork(); + if (pid < 0) + { + syslog(LOG_ERR, "PAS >> Unable to fork, code=%d (%s).", errno, strerror(errno));/*DG C8MR2R-MISRA-C:2004 Rule 20.5-SSW_Administrator_0003*/ + + sRetVal = DAEMONIZE_FAIL_RET_VAL; + } + else + { + if(pid > 0) + { + syslog(LOG_ERR, "PAS >> Child(daemon) process created successfully with PID=%d.", pid); + + sRetVal = DAEMONIZE_PARENT_RET_VAL; + } + } + if(DAEMONIZE_SUCCESS_RET_VAL == sRetVal) + { + /* Ignore or perform the default action for some of the signals in the child process */ + (void)signal(SIGCHLD,SIG_DFL); /* A child process dies */ + (void)signal(SIGTSTP,SIG_IGN); /* Various TTY signals */ + (void)signal(SIGTTOU,SIG_IGN); + (void)signal(SIGTTIN,SIG_IGN); + (void)signal(SIGHUP, SIG_IGN); /* Ignore hangup signal */ + (void)signal(SIGTERM,SIG_DFL); /* Die on SIGTERM */ + + syslog(LOG_INFO, "PAS >> Child signals ignored."); + + /* Change the file mode mask */ + (void)umask(0); + + syslog(LOG_INFO, "PAS >> File mode mask changed."); + + /* Get a unique Session ID from the kernel */ + sid = setsid(); + if (OS_ERROR_CODE == sid) + { + syslog(LOG_ERR, "PAS >> Unable to get a unique session id. Error code %d (%s).", errno, strerror(errno));/*DG C8MR2R-MISRA-C:2004 Rule 20.5-SSW_Administrator_0003*/ + + sRetVal = DAEMONIZE_FAIL_RET_VAL; + } + else + { + syslog(LOG_INFO, "PAS >> New SID for child process: %d.", sid); + } + } -static sint_t persadmin_DaemonizeProcess (pstr_t pProcessName) -{ - pid_t pid, sid; - sint_t sRetVal = DAEMONIZE_SUCCESS_RET_VAL; - - if(NIL == pProcessName) - { - syslog(LOG_ERR, "PAS >> Invalid argument in persadmin_DaemonizeProcess call."); - - sRetVal = DAEMONIZE_FAIL_RET_VAL; - } - - if(DAEMONIZE_SUCCESS_RET_VAL == sRetVal) - { - syslog(LOG_INFO, "PAS >> Daemon process %s starting.", pProcessName); - - /* Fork off the parent process */ - pid = fork(); - if (pid < 0) - { - syslog(LOG_ERR, "PAS >> Unable to fork, code=%d (%s).", errno, strerror(errno));/*DG C8MR2R-MISRA-C:2004 Rule 20.5-SSW_Administrator_0003*/ - - sRetVal = DAEMONIZE_FAIL_RET_VAL; - } - else - { - if(pid > 0) - { - syslog(LOG_ERR, "PAS >> Child(daemon) process created successfully with PID=%d.", pid); - - sRetVal = DAEMONIZE_PARENT_RET_VAL; - } - } - - if(DAEMONIZE_SUCCESS_RET_VAL == sRetVal) - { - /* Ignore or perform the default action for some of the signals in the child process */ - (void)signal(SIGCHLD,SIG_DFL); /* A child process dies */ - (void)signal(SIGTSTP,SIG_IGN); /* Various TTY signals */ - (void)signal(SIGTTOU,SIG_IGN); - (void)signal(SIGTTIN,SIG_IGN); - (void)signal(SIGHUP, SIG_IGN); /* Ignore hangup signal */ - (void)signal(SIGTERM,SIG_DFL); /* Die on SIGTERM */ - - syslog(LOG_INFO, "PAS >> Child signals ignored."); - - /* Change the file mode mask */ - (void)umask(0); - - syslog(LOG_INFO, "PAS >> File mode mask changed."); - - /* Get a unique Session ID from the kernel */ - sid = setsid(); - if (OS_ERROR_CODE == sid) - { - syslog(LOG_ERR, "PAS >> Unable to get a unique session id. Error code %d (%s).", errno, strerror(errno));/*DG C8MR2R-MISRA-C:2004 Rule 20.5-SSW_Administrator_0003*/ - - sRetVal = DAEMONIZE_FAIL_RET_VAL; - } - else - { - syslog(LOG_INFO, "PAS >> New SID for child process: %d.", sid); - } - } - - if(DAEMONIZE_SUCCESS_RET_VAL == sRetVal) - { - /* Change the current working directory. - * This prevents the current directory from being locked; hence not being able to remove it. - * The root directory cannot be unmounted. - */ - if ((chdir("/")) < 0) - { - syslog(LOG_ERR, "PAS >> Unable to change directory to root path. Error code %d (%s)", errno, strerror(errno));/*DG C8MR2R-MISRA-C:2004 Rule 20.5-SSW_Administrator_0003*/ - - sRetVal = DAEMONIZE_FAIL_RET_VAL; - } - else - { - syslog(LOG_INFO, "PAS >> Current working directory changed for child process."); - } - } - - if(DAEMONIZE_SUCCESS_RET_VAL == sRetVal) - { - /* Redirect standard files to /dev/null */ - (void)freopen( "/dev/null", "r", stdin); - (void)freopen( "/dev/null", "w", stdout); - (void)freopen( "/dev/null", "w", stderr); - - syslog(LOG_INFO, "PAS >> Standard file descriptors redirected to /dev/null."); - } - } - - return sRetVal; + if(DAEMONIZE_SUCCESS_RET_VAL == sRetVal) + { + /* Change the current working directory. + * This prevents the current directory from being locked; hence not being able to remove it. + * The root directory cannot be unmounted. + */ + if ((chdir("/")) < 0) + { + syslog(LOG_ERR, "PAS >> Unable to change directory to root path. Error code %d (%s)", errno, strerror(errno));/*DG C8MR2R-MISRA-C:2004 Rule 20.5-SSW_Administrator_0003*/ + + sRetVal = DAEMONIZE_FAIL_RET_VAL; + } + else + { + syslog(LOG_INFO, "PAS >> Current working directory changed for child process."); + } + } + + if(DAEMONIZE_SUCCESS_RET_VAL == sRetVal) + { + /* Redirect standard files to /dev/null */ + (void)freopen( "/dev/null", "r", stdin); + (void)freopen( "/dev/null", "w", stdout); + (void)freopen( "/dev/null", "w", stderr); + + syslog(LOG_INFO, "PAS >> Standard file descriptors redirected to /dev/null."); + } + } + + return sRetVal; }/*DG C8ISQP-ISQP Metric 10-SSW_Administrator_0001*/ static sint_t persadmin_RunDaemon(void) { - sint_t sRetVal = EXIT_SUCCESS; - sint_t retVal = PERS_COM_SUCCESS; - bool_t bSyncObjInitialized = false; - bool_t bLockedPIDFile = false; - struct sigaction action; - - /* Initialize the logging interface */ - DLT_REGISTER_APP("PERS", "Persistence Administration Service"); - DLT_REGISTER_CONTEXT(persAdminSvcDLTCtx, "PADM", "Persistence Administration Service Context"); - - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(PERSISTENCE_ADMIN_PROC_NAME); - DLT_STRING(" starting...")); - - /* Set SIGTERM handler */ - (void)memset(&action, 0, sizeof(struct sigaction)); - action.sa_handler = &persadmin_HandleTerm; - (void)sigaction(SIGTERM, &action, NULL); - - /* Lock the PID file */ - if(false == persadmin_LockPidFile()) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to lock the PID file.")); - - sRetVal = EXIT_FAILURE; - } - else - { - bLockedPIDFile = true; - } - - if(EXIT_FAILURE != sRetVal) - { - /* Initialize synchronization objects */ - if(OS_SUCCESS_CODE == pthread_mutex_init (&shutdownMtx, NULL)) - { - if(OS_SUCCESS_CODE == pthread_cond_init (&shutdownCond, NULL)) - { - bSyncObjInitialized = true; - } - else - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to init shutdown sync. obj. (cond)")); - - (void)pthread_mutex_destroy(&shutdownMtx); - - sRetVal = EXIT_FAILURE; - } - } - else - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to init shutdown sync. obj. (mtx)")); - - sRetVal = EXIT_FAILURE; - } - - if(true == bSyncObjInitialized) - { - pthread_t g_hAccessLibThread = 0; - - /* Create the AccessLib thread */ - if(OS_SUCCESS_CODE != pthread_create(&g_hAccessLibThread, NIL, &persadmin_AccessLibThread, NIL)) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to create AccessLib thread.")); - } - else - { - /* Init PAS IPC protocol */ - retVal = persadmin_InitIpc(); - if(PERS_COM_SUCCESS != retVal) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to init PAS IPC component.")); - - sRetVal = EXIT_FAILURE; - } - else - { - /* Notify systemd that PAS is ready */ - (void)sd_notify(0, "READY=1"); - - /* Init DBus connection and run the PAS main loop */ - persadmin_RunDBusMainLoop(); - } - - /* signal the AccessLib thread to stop */ - g_bRunAccessLibThread = false; - - /* Wait for the AccessLib thread */ - (void)pthread_join(g_hAccessLibThread, NIL); - - /* Close synchronization objects */ - (void)pthread_mutex_destroy(&shutdownMtx); - (void)pthread_cond_destroy(&shutdownCond); - } - } - } - - if(true == bLockedPIDFile) - { - /* Unlock PID file and close handles */ - persadmin_EndPASProcess(); - } - - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(PERSISTENCE_ADMIN_PROC_NAME); - DLT_STRING(" stopped.")); - DLT_UNREGISTER_CONTEXT(persAdminSvcDLTCtx); - DLT_UNREGISTER_APP(); - - return sRetVal; + sint_t sRetVal = EXIT_SUCCESS; + sint_t retVal = PERS_COM_SUCCESS; + bool_t bSyncObjInitialized = false; + bool_t bLockedPIDFile = false; + struct sigaction action; + + /* Initialize the logging interface */ + DLT_REGISTER_APP("PERS", "Persistence Administration Service"); + DLT_REGISTER_CONTEXT(persAdminSvcDLTCtx, "PADM", "Persistence Administration Service Context"); + + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(PERSISTENCE_ADMIN_PROC_NAME); + DLT_STRING(" starting...")); + + /* Set SIGTERM handler */ + memset(&action, 0, sizeof(struct sigaction)); + action.sa_handler = &persadmin_HandleTerm; + sigaction(SIGTERM, &action, NULL); + + /* Lock the PID file */ + if(false == persadmin_LockPidFile()) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to lock the PID file.")); -}/*DG C8ISQP-ISQP Metric 10-SSW_Administrator_0001*/ + sRetVal = EXIT_FAILURE; + } + else + { + bLockedPIDFile = true; + } + + if(EXIT_FAILURE != sRetVal) + { + /* Initialize synchronization objects */ + if(OS_SUCCESS_CODE == pthread_mutex_init (&g_shutdownMtx, NULL)) + { + if(OS_SUCCESS_CODE == pthread_cond_init (&g_shutdownCond, NULL)) + { + bSyncObjInitialized = true; + } + else + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to init shutdown sync. obj. (cond)")); + + pthread_mutex_destroy(&g_shutdownMtx); + + sRetVal = EXIT_FAILURE; + } + } + else + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to init shutdown sync. obj. (mtx)")); + + sRetVal = EXIT_FAILURE; + } + + if(true == bSyncObjInitialized) + { + pthread_t g_hAccessLibThread = 0; + + /* Create the AccessLib thread */ + if(OS_SUCCESS_CODE != pthread_create(&g_hAccessLibThread, NIL, &persadmin_AccessLibThread, NIL)) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to create AccessLib thread.")); + } + else + { + /* Init PAS IPC protocol */ + retVal = persadmin_InitIpc(); + if(PERS_COM_SUCCESS != retVal) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to init PAS IPC component.")); + + sRetVal = EXIT_FAILURE; + } + else + { + /* Notify systemd that PAS is ready */ + (void)sd_notify(0, "READY=1"); + + /* Init DBus connection and run the PAS main loop */ + persadmin_RunDBusMainLoop(); + } + + /* signal the AccessLib thread to stop */ + g_bRunAccessLibThread = false; + + /* Wait for the AccessLib thread */ + pthread_join(g_hAccessLibThread, NIL); + + /* Close synchronization objects */ + pthread_mutex_destroy(&g_shutdownMtx); + pthread_cond_destroy(&g_shutdownCond); + } + } + } + + if(true == bLockedPIDFile) + { + /* Unlock PID file and close handles */ + persadmin_EndPASProcess(); + } + + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(PERSISTENCE_ADMIN_PROC_NAME); + DLT_STRING(" stopped.")); + DLT_UNREGISTER_CONTEXT(persAdminSvcDLTCtx); + DLT_UNREGISTER_APP(); + + return sRetVal; + +} static bool_t persadmin_LockPidFile(void) { - str_t strPid[PAS_PID_MAX_SIZE]; - bool_t bRetVal = true; - - g_hPASPidFile = open(PAS_PID_FILE_PATH, O_RDWR|O_CREAT, 0640); - if (OS_INVALID_HANDLE == g_hPASPidFile) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to create PID file:"); - DLT_STRING(PAS_PID_FILE_PATH)); - bRetVal = false; - } - else - { - if (OS_INVALID_HANDLE == lockf(g_hPASPidFile, F_TLOCK, 0)) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to lock PID file:"); - DLT_STRING(PAS_PID_FILE_PATH)); - bRetVal = false; - } - else - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Locked PID file:"); - DLT_STRING(PAS_PID_FILE_PATH)); - - /* write PID to be used by systemd */ - (void)sprintf(strPid, "%d", getpid()); - (void)write(g_hPASPidFile, strPid, strlen(strPid)); - } - } - - return bRetVal; -}/*DG C8ISQP-ISQP Metric 10-SSW_Administrator_0001*/ + str_t strPid[PAS_PID_MAX_SIZE]; + bool_t bRetVal = true; + + g_hPASPidFile = open(PAS_PID_FILE_PATH, (uint_t)O_RDWR | (uint_t)O_CREAT, 0640); + if (OS_INVALID_HANDLE == g_hPASPidFile) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to create PID file:"); + DLT_STRING(PAS_PID_FILE_PATH)); + bRetVal = false; + } + else + { + if (OS_INVALID_HANDLE == lockf(g_hPASPidFile, F_TLOCK, 0)) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to lock PID file:"); + DLT_STRING(PAS_PID_FILE_PATH)); + bRetVal = false; + } + else + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Locked PID file:"); + DLT_STRING(PAS_PID_FILE_PATH)); + + /* write PID to be used by systemd */ + snprintf(strPid, sizeof(strPid), "%d", getpid()); + write(g_hPASPidFile, strPid, strlen(strPid)); + } + } + + return bRetVal; +} static void persadmin_EndPASProcess(void) { - /* unlock PID file */ - if(OS_INVALID_HANDLE != g_hPASPidFile) - { - if(OS_INVALID_HANDLE == lockf(g_hPASPidFile, F_ULOCK, 0)) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to unlock PID file:"); - DLT_STRING(PAS_PID_FILE_PATH)); - } - else - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Unlocked PID file:"); - DLT_STRING(PAS_PID_FILE_PATH)); - } - } - - /* close PID file */ - if(OS_INVALID_HANDLE == close(g_hPASPidFile)) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to close PID file:"); - DLT_STRING(PAS_PID_FILE_PATH)); - } - - g_hPASPidFile = OS_INVALID_HANDLE; - - /* remove PID file */ - if(OS_INVALID_HANDLE == remove(PAS_PID_FILE_PATH)) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to remove PID file:"); - DLT_STRING(PAS_PID_FILE_PATH)); - } + /* unlock PID file */ + if(OS_INVALID_HANDLE != g_hPASPidFile) + { + if(OS_INVALID_HANDLE == lockf(g_hPASPidFile, F_ULOCK, 0)) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to unlock PID file:"); + DLT_STRING(PAS_PID_FILE_PATH)); + } + else + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Unlocked PID file:"); + DLT_STRING(PAS_PID_FILE_PATH)); + } + } + + /* close PID file */ + if(OS_INVALID_HANDLE == close(g_hPASPidFile)) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to close PID file:"); + DLT_STRING(PAS_PID_FILE_PATH)); + } + + g_hPASPidFile = OS_INVALID_HANDLE; + + /* remove PID file */ + if(OS_INVALID_HANDLE == remove(PAS_PID_FILE_PATH)) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to remove PID file:"); + DLT_STRING(PAS_PID_FILE_PATH)); + } } static bool_t persadmin_IsAlreadyRunning(void) { - sint32_t hFile = OS_INVALID_HANDLE; - struct stat sStat; - str_t strPid[PAS_PID_MAX_SIZE]; - str_t strProcPath[PAS_PID_PROC_PATH_MAX_SIZE]; - uint32_t u32PidVal = 0; - bool_t bRetVal = true; - - /* check PID file */ - hFile = stat(PAS_PID_FILE_PATH, &sStat); - if (OS_INVALID_HANDLE == hFile) - { - /* PAS process not running. The PID file does not exists */ - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Failed to open PAS PID file. Process is not running already. errno ="); - DLT_INT(errno));/*DG C8MR2R-MISRA-C:2004 Rule 20.5-SSW_Administrator_0003*/ - bRetVal = false; - } - else - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Found PAS PID file"); - DLT_STRING(PAS_PID_FILE_PATH)); - - /* PID file exists, check if the process with the specified PID is running */ - hFile = open(PAS_PID_FILE_PATH, O_RDONLY); - if(OS_INVALID_HANDLE == hFile) - { - /* the process might be running */ - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to open file"); - DLT_STRING(PAS_PID_FILE_PATH)); - } - else - { - /* read PID and check process status */ - (void)memset(strPid, 0, sizeof(strPid)); - (void)read(hFile, strPid, (PAS_PID_MAX_SIZE - 1)); - (void)sscanf(strPid, "%d", &u32PidVal); - (void)close(hFile); - - (void)sprintf(strProcPath, "%s/%d", PAS_SYSPROC_PATH, u32PidVal); - - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Checking status for process"); - DLT_STRING(strProcPath)); - - hFile = stat(strProcPath, &sStat); - if (OS_INVALID_HANDLE == hFile) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("File '"); - DLT_STRING(strProcPath); - DLT_STRING("' exists, but process with PID:"); - DLT_STRING(strPid); - DLT_STRING(" is not running.")); - bRetVal = false; - } - } - } - - return bRetVal; + sint32_t hFile = OS_INVALID_HANDLE; + struct stat sStat; + str_t strPid[PAS_PID_MAX_SIZE]; + str_t strProcPath[PAS_PID_PROC_PATH_MAX_SIZE]; + uint32_t u32PidVal = 0; + bool_t bRetVal = true; + + /* check PID file */ + hFile = stat(PAS_PID_FILE_PATH, &sStat); + if (OS_INVALID_HANDLE == hFile) + { + /* PAS process not running. The PID file does not exists */ + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Failed to open PAS PID file. Process is not running already. Error :"); + DLT_STRING(strerror(errno))); + bRetVal = false; + } + else + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Found PAS PID file"); + DLT_STRING(PAS_PID_FILE_PATH)); -}/*DG C8ISQP-ISQP Metric 10-SSW_Administrator_0001*/ + /* PID file exists, check if the process with the specified PID is running */ + hFile = open(PAS_PID_FILE_PATH, O_RDONLY); + if(OS_INVALID_HANDLE == hFile) + { + /* the process might be running */ + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("Failed to open file"); + DLT_STRING(PAS_PID_FILE_PATH)); + } + } + if(OS_INVALID_HANDLE != hFile) + { + /* read PID and check process status */ + memset(strPid, 0, sizeof(strPid)); + read(hFile, strPid, (PAS_PID_MAX_SIZE - 1)); + close(hFile); -static uint32_t persadmin_GetWdogRetriggerRate(void) -{ - const char *sWdogUSec = NIL; - uint32_t u32WdogUSec = 0; - - sWdogUSec = getenv("WATCHDOG_USEC"); - if(NIL == sWdogUSec) - { - /* use default watchdog re-trigger rate */ - u32WdogUSec = PAS_WATCHDOG_USEC_DEFAULT_VALUE; - - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); - DLT_STRING("Using default watchdog re-trigger rate :"); - DLT_UINT32(u32WdogUSec / 1000); - DLT_STRING("ms.")); - } - else - { - u32WdogUSec = strtoul(sWdogUSec, NULL, 10); - - /* The min. valid value for systemd is 1 s => WATCHDOG_USEC at least needs to contain 1.000.000 us */ - if(u32WdogUSec < ONE_SEC_IN_US) - { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING(LT_HDR); - DLT_STRING("Error: Invalid WDOG config: WATCHDOG_USEC:"); - DLT_STRING(sWdogUSec); - DLT_STRING(".Using default watchdog re-trigger rate :"); - DLT_UINT32(PAS_WATCHDOG_USEC_DEFAULT_VALUE / 1000); - DLT_STRING("ms")); - - u32WdogUSec = PAS_WATCHDOG_USEC_DEFAULT_VALUE; - } - else - { - u32WdogUSec /= 2; - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); - DLT_STRING("WDOG retrigger rate [ms]:"); - DLT_UINT32(u32WdogUSec/1000)); - } - } - - return u32WdogUSec; + if(strlen(strPid) > 0) + { + sscanf(strPid, "%d", &u32PidVal); + + snprintf(strProcPath, sizeof(strProcPath), "%s/%d", PAS_SYSPROC_PATH, u32PidVal); + + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("Checking status for process"); + DLT_STRING(strProcPath)); + + hFile = stat(strProcPath, &sStat); + if (OS_INVALID_HANDLE == hFile) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING("File '"); + DLT_STRING(strProcPath); + DLT_STRING("' exists, but process with PID:"); + DLT_STRING(strPid); + DLT_STRING(" is not running.")); + bRetVal = false; + } + } + } + + return bRetVal; } -void persadmin_RetriggerWatchdog(void) +static void persadmin_HandleTerm(int signum) { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); + DLT_STRING("SIGTERM received...")); - (void) sd_notify(0, "WATCHDOG=1"); - - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); - DLT_STRING("Triggered systemd WDOG")); + /* quit DBus main loop */ + persadmin_QuitDBusMainLoop(); } -static void persadmin_HandleTerm(int signum) +static sint_t persadmin_ReadMsgFromQueue(mqd_t mqdes, + uint8_t *msg_ptr, + size_t msg_len) { - DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_INFO, DLT_STRING(LT_HDR); - DLT_STRING("SIGTERM received...")); + sint_t sRetVal = PERS_COM_SUCCESS; + fd_set readFds; - /* quit DBus main loop */ - (void)persadmin_QuitDBusMainLoop(); + struct timeval tvTimeout = {PAS_ACCESS_LIB_REQ_QUEUE_TIMEOUT_US / ONE_SEC_IN_US, PAS_ACCESS_LIB_REQ_QUEUE_TIMEOUT_US % ONE_SEC_IN_US}; + + /* build the read fd list */ + FD_ZERO(&readFds); + FD_SET(mqdes, &readFds); + + /* wait (at most until the timeout occurs) for a message to be available */ + sRetVal = select(mqdes + (sint_t)1, &readFds, NIL, NIL, &tvTimeout); + if(sRetVal > 0) + { + /* message available in the queue */ + if(!FD_ISSET(mqdes, &readFds)) + { + sRetVal = PERS_COM_FAILURE; + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("ERROR - FD_ISSET")); + } + else + { + /* extract the message from the queue */ + sRetVal = mq_receive(mqdes, (char *)msg_ptr, msg_len, NIL); + if(sRetVal < 0) + { + sRetVal = PERS_COM_FAILURE; + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("mq_receive() call failed with error :"); + DLT_STRING(strerror(errno))); + } + } + } + else + { + if(sRetVal < 0) + { + DLT_LOG(persAdminSvcDLTCtx, DLT_LOG_ERROR, DLT_STRING("select() call failed with error:"); + DLT_STRING(strerror(errno))); + sRetVal = PERS_COM_FAILURE; + } + } + + return sRetVal; } int main(void) { - sint_t sRetVal = EXIT_SUCCESS; - sint_t sTmpRetVal; - - /* Initialize syslog */ - (void)setlogmask (LOG_UPTO (LOG_DEBUG)); - openlog("PAS", LOG_PID, LOG_USER); - - /* Check if the process is already running */ - if(true == persadmin_IsAlreadyRunning()) - { - syslog(LOG_INFO, "PAS >> PAS process is already running! Only one instance allowed!"); - - sRetVal = EXIT_FAILURE; - } - - if(EXIT_FAILURE != sRetVal) - { - /* Daemonize the current process */ - sTmpRetVal = persadmin_DaemonizeProcess((str_t*)PERSISTENCE_ADMIN_PROC_NAME); - if(DAEMONIZE_FAIL_RET_VAL == sTmpRetVal) - { - syslog(LOG_INFO, "PAS >> persadmin_DaemonizeProcess call failed."); - - sRetVal = EXIT_FAILURE; - - }else - { - if(DAEMONIZE_SUCCESS_RET_VAL == sTmpRetVal) - { - /* Run daemon actions */ - sRetVal = persadmin_RunDaemon(); - - }/* exit with success for parent process */ - } - } - - /* De-initialize syslog */ - closelog(); + sint_t sRetVal = EXIT_SUCCESS; + sint_t sTmpRetVal; + + /* Initialize syslog */ + (void)setlogmask (LOG_UPTO (LOG_DEBUG)); + openlog("PAS", LOG_PID, LOG_USER); + + /* Check if the process is already running */ + if(true == persadmin_IsAlreadyRunning()) + { + syslog(LOG_INFO, "PAS >> PAS process is already running! Only one instance allowed!"); + + sRetVal = EXIT_FAILURE; + } + + if(EXIT_FAILURE != sRetVal) + { + /* Daemonize the current process */ + sTmpRetVal = persadmin_DaemonizeProcess((str_t*)PERSISTENCE_ADMIN_PROC_NAME); + if(DAEMONIZE_FAIL_RET_VAL == sTmpRetVal) + { + syslog(LOG_INFO, "PAS >> persadmin_DaemonizeProcess call failed."); + + sRetVal = EXIT_FAILURE; + + }else + { + if(DAEMONIZE_SUCCESS_RET_VAL == sTmpRetVal) + { + /* Run daemon actions */ + sRetVal = persadmin_RunDaemon(); + + }/* exit with success for parent process */ + } + } + + /* De-initialize syslog */ + closelog(); return sRetVal; } diff --git a/ChangeLog b/ChangeLog index 136db23..e720aff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,21 +1,33 @@ +####################################################################################################################### +# +# Copyright (C) 2016 Continental Automotive Systems, Inc. +# +# Author: cosmin.cernat@continental-corporation.com +# +####################################################################################################################### + persistence-administrator ChangeLog =================================== +Version 1.0.8 02.06.2016 + +1. Fixed issue http://bugs.genivi.org/show_bug.cgi?id=437 + Version 1.0.7 13.10.2015 -1 Fixed Bug 299 - Link to shared group data is missing +1. Fixed issue http://bugs.genivi.org/show_bug.cgi?id=299 Version 1.0.6 9.10.2015 ------------------------ -1. Fixed Bug 295 - further calls of persadmin_tool install return with exit code: -1310719 +1. Fixed issue http://bugs.genivi.org/show_bug.cgi?id=295 Version 1.0.4 16.09.2014 ------------------------ -1. Fixed format for the access lib version info. +1. Fixed format for the access lib version info. Version 1.0.3 12.09.2014 ------------------------ -1. Fixed issue http://bugs.genivi.org/show_bug.cgi?id=263 +1. Fixed issue http://bugs.genivi.org/show_bug.cgi?id=263 diff --git a/configure.ac b/configure.ac index c9065d7..0112c1f 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # # Copyright (C) 2012 Continental Automotive Systems, Inc. # -# Author: Ana.Chisca@continental-corporation.com +# Author: cosmin.cernat@continental-corporation.com # # Configure template for the Persistence Administration Service # @@ -18,7 +18,7 @@ dnl ************************************************************************** dnl *** First, define all of the version numbers up front *** dnl *** In particular, this allows the version macro to be used in AC_INIT *** dnl ************************************************************************** -m4_define([PERS_PACKAGE_VERSION_S],[1.0.7]) +m4_define([PERS_PACKAGE_VERSION_S],[1.0.8]) m4_define([PERS_ADMINACCESSLIB_VERSION_N],[1000000]) dnl *************************** -- cgit v1.2.1