the systemd integration was moved to an optional plugins.
this way LayerManagerService has no dependencies on systemd.
health monitoring plugins implement the interface IHealthMonitor.
Currently there's only one avialable that uses systemd watchdog to
report health status to the system.
Signed-off-by: Timo Lotterbach <timo.lotterbach@bmw-carit.de>
include_directories (".")
# build systemd reference client library
-if (WITH_SYSTEMD)
+if (WITH_SYSTEMD_HEALTH_MONITOR)
add_library(systemd systemd/sd-daemon.c)
-endif (WITH_SYSTEMD)
+endif (WITH_SYSTEMD_HEALTH_MONITOR)
# build unit test frameworks, if tests are enabled
if (WITH_TESTS)
option (WITH_CLIENT_LIB "Build LayerManagement Client Lib" ON)
option (WITH_COMMUNICATOR_GEN "Build Generic Communicator Plugin" ON)
-option (WITH_SYSTEMD "Build with native systemd integration" OFF)
+option (WITH_PLUGIN_SYSTEMD_HEALTH_MONITOR "Build plugin for systemd health monitoring" OFF)
option (WITH_TEXT_RENDERER "Build renderer renderer (only logging)" OFF)
#set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
#==============================================================================
+if (WITH_PLUGIN_SYSTEMD_HEALTH_MONITOR)
+ add_subdirectory (LayerManagerPlugins/HealthMonitor/SystemdHealthMonitor)
+endif(WITH_PLUGIN_SYSTEMD_HEALTH_MONITOR)
+
if (WITH_COMMUNICATOR_GEN)
add_subdirectory (LayerManagerCommands)
add_subdirectory (LayerManagerPlugins/Communicators/GenericCommunicator)
if (WITH_TESTS)
enable_testing()
endif(WITH_TESTS)
-
-
--- /dev/null
+############################################################################
+#
+# Copyright 2012 BMW Car IT GmbH
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+############################################################################
+
+cmake_minimum_required (VERSION 2.6)
+
+project(SystemdHealthMonitor)
+
+find_package(Threads)
+
+include_directories(
+ include
+ ${CMAKE_SOURCE_DIR}/LayerManagerClient/ilmClient/include
+ ${CMAKE_SOURCE_DIR}/LayerManagerService/include
+ ${CMAKE_SOURCE_DIR}/LayerManagerUtils/include
+)
+
+set(LIBS
+ ${LIBS}
+ LayerManagerUtils
+ systemd
+)
+
+add_library(${PROJECT_NAME} SHARED
+ src/SystemdHealthMonitor.cpp
+)
+
+target_link_libraries(${PROJECT_NAME}
+ ${LIBS}
+)
+
+add_dependencies(${PROJECT_NAME}
+ LayerManagerService
+ LayerManagerUtils
+)
+
+install (TARGETS ${PROJECT_NAME}
+ LIBRARY DESTINATION lib/layermanager/health)
#ifndef __HEALTHSYSTEMD_H__
#define __HEALTHSYSTEMD_H__
-#include "IHealth.h"
+#include "IHealthMonitor.h"
#include "ThreadBase.h"
-class HealthSystemd : public IHealth, protected ThreadBase
+class SystemdHealthMonitor : public IHealthMonitor, protected ThreadBase
{
public:
- HealthSystemd(ICommandExecutor& executor, Configuration& config);
+ SystemdHealthMonitor(ICommandExecutor* executor);
// from IHealth
virtual t_ilm_bool start();
*
****************************************************************************/
-#include "HealthSystemd.h"
+#include "SystemdHealthMonitor.h"
#include "Configuration.h"
#include "Log.h"
#include "ICommandExecutor.h"
#include <unistd.h>
#include <stdlib.h>
-#ifdef WITH_SYSTEMD
-
#include <systemd/sd-daemon.h>
-HealthSystemd::HealthSystemd(ICommandExecutor& executor, Configuration& config)
-: IHealth(executor, config)
+SystemdHealthMonitor::SystemdHealthMonitor(ICommandExecutor* executor)
+: IHealthMonitor(executor)
, mIntervalInMs(-1)
{
char* envVar = getenv("WATCHDOG_USEC");
{
// to ms, watchdog should trigger twice the frequency
mIntervalInMs = atoi(envVar) / 2000;
- LOG_INFO("HealthSystemd", "Watchdog interval is " << mIntervalInMs << "ms");
+ LOG_INFO("SystemdHealthMonitor", "Watchdog interval is " << mIntervalInMs << "ms");
}
else
{
- LOG_INFO("HealthSystemd", "Watchdog interval not defined, watchdog disabled");
+ LOG_INFO("SystemdHealthMonitor", "Watchdog interval not defined, watchdog disabled");
}
}
-t_ilm_bool HealthSystemd::start()
+t_ilm_bool SystemdHealthMonitor::start()
{
- LOG_INFO("HealthSystemd", "starting");
+ LOG_INFO("SystemdHealthMonitor", "starting");
t_ilm_bool result = ILM_TRUE;
if (watchdogEnabled())
{
return result;
}
-t_ilm_bool HealthSystemd::stop()
+t_ilm_bool SystemdHealthMonitor::stop()
{
- LOG_INFO("HealthSystemd", "stopping");
+ LOG_INFO("SystemdHealthMonitor", "stopping");
t_ilm_bool result = ILM_TRUE;
if (watchdogEnabled())
{
return result;
}
-void HealthSystemd::reportStartupComplete()
+void SystemdHealthMonitor::reportStartupComplete()
{
- LOG_INFO("HealthSystemd", "reporting startup complete");
+ LOG_INFO("SystemdHealthMonitor", "reporting startup complete");
sd_notify(0, "READY=1");
}
-void HealthSystemd::signalWatchdog()
+void SystemdHealthMonitor::signalWatchdog()
{
- LOG_DEBUG("HealthSystemd", "Watchdog fired");
+ LOG_DEBUG("SystemdHealthMonitor", "Watchdog fired");
sd_notify(0, "WATCHDOG=1");
}
-bool HealthSystemd::watchdogEnabled()
+bool SystemdHealthMonitor::watchdogEnabled()
{
return (mIntervalInMs > 0);
}
-t_ilm_bool HealthSystemd::threadMainLoop()
+t_ilm_bool SystemdHealthMonitor::threadMainLoop()
{
- if (watchdogEnabled() && mExecutor.getHealth())
+ if (watchdogEnabled() && mExecutor->getHealth())
{
signalWatchdog();
usleep(mIntervalInMs * 1000);
return ILM_TRUE;
}
-#endif // WITH_SYSTEMD
+extern "C" IHealthMonitor* createSystemdHealthMonitor(ICommandExecutor* executor)
+{
+ return new SystemdHealthMonitor(executor);
+}
+
+extern "C" void destroyGenericCommunicator(SystemdHealthMonitor* p)
+{
+ delete p;
+}
${CMAKE_THREAD_LIBS_INIT}
${DLT_LIBRARY})
-if (WITH_SYSTEMD)
- set(LIBS ${LIBS} systemd rt)
-endif (WITH_SYSTEMD)
-
target_link_libraries(LayerManagerService ${LIBS})
install (TARGETS LayerManagerService DESTINATION bin)
src/GraphicalSurface.cpp
src/Layermanager.cpp
src/InputManager.cpp
- src/HealthSystemd.cpp
src/PluginBase.cpp
src/PluginManager.cpp
src/Scene.cpp
--- /dev/null
+/***************************************************************************
+ *
+ * Copyright 2010,2011 BMW Car IT GmbH
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ****************************************************************************/
+#ifndef __HEALTHMONITORLIST_H__
+#define __HEALTHMONITORLIST_H__
+
+#include <list>
+#include "IHealthMonitor.h"
+
+typedef std::list<IHealthMonitor*> HealthMonitorList;
+typedef std::list<IHealthMonitor*>::iterator HealthMonitorListIterator;
+typedef std::list<IHealthMonitor*>::const_iterator HealthMonitorListConstIterator;
+
+#endif // __HEALTHMONITORLIST_H__
#include "RendererList.h"
#include "CommunicatorList.h"
#include "SceneProviderList.h"
+#include "HealthMonitorList.h"
#include "ApplicationReferenceMap.h"
#include "LayerType.h"
#include "ObjectType.h"
virtual void removeCommunicator(ICommunicator* communicator) = 0;
// scene provider management
-
+
/**
* \brief get list of scene provider plugins currently used
* \ingroup ServiceAPI
* \return Pointer to internal list of communicators
*/
virtual SceneProviderList* getSceneProviderList(void) = 0;
-
+
/**
- *
+ *
* \brief add a scene provider to be used for layer management
* \ingroup ServiceAPI
* \param[in] sceneProvider pointer to scene provider object
*/
virtual void addSceneProvider(ISceneProvider* sceneProvider) = 0;
-
+
/**
- *
+ *
* \brief remove scene provider from layer management
* \ingroup ServiceAPI
* \param[in] sceneProvider pointer to scene provider object
*/
virtual void removeSceneProvider(ISceneProvider* sceneProvider) = 0;
-
+
+ // health monitor management
+
+ /**
+ * \brief get list of health monitor plugins currently used
+ * \ingroup ServiceAPI
+ * \return Pointer to internal list of health monitors
+ */
+ virtual HealthMonitorList* getHealthMonitorList(void) = 0;
+
+ /**
+ *
+ * \brief add a health monitor to be used for layer management
+ * \ingroup ServiceAPI
+ * \param[in] healthMonitor pointer to health monitor object
+ */
+ virtual void addHealthMonitor(IHealthMonitor* healthMonitor) = 0;
+
+ /**
+ *
+ * \brief remove health monitor from layer management
+ * \ingroup ServiceAPI
+ * \param[in] healthMonitor pointer to health monitor object
+ */
+ virtual void removeHealthMonitor(IHealthMonitor* healthMonitor) = 0;
+
// client application management
/**
class ICommandExecutor;
class Configuration;
-class IHealth
+class IHealthMonitor
{
public:
- IHealth(ICommandExecutor& executor, Configuration& config);
- virtual ~IHealth() {};
+ IHealthMonitor(ICommandExecutor* executor);
+ virtual ~IHealthMonitor() {};
virtual t_ilm_bool start() = 0;
virtual t_ilm_bool stop() = 0;
protected:
- ICommandExecutor& mExecutor;
- Configuration& mConfiguration;
+ ICommandExecutor* mExecutor;
};
inline
-IHealth::IHealth(ICommandExecutor& executor, Configuration& config)
+IHealthMonitor::IHealthMonitor(ICommandExecutor* executor)
: mExecutor(executor)
-, mConfiguration(config)
{
}
class ICommunicator;
class ISceneProvider;
class IApplicationReference;
-class IHealth;
+class IHealthMonitor;
class IPlugin;
class Configuration;
class PluginManager;
virtual void addSceneProvider(ISceneProvider* sceneProvider);
virtual void removeSceneProvider(ISceneProvider* sceneProvider);
+ virtual void addHealthMonitor(IHealthMonitor* healthMonitor);
+ virtual void removeHealthMonitor(IHealthMonitor* healthMonitor);
+
virtual void addApplicationReference(t_ilm_client_handle client, IApplicationReference* reference);
virtual void removeApplicationReference(t_ilm_client_handle client);
virtual t_ilm_uint getSenderPid(t_ilm_client_handle client);
virtual RendererList* getRendererList(void);
virtual CommunicatorList* getCommunicatorList(void);
virtual SceneProviderList* getSceneProviderList(void);
+ virtual HealthMonitorList* getHealthMonitorList(void);
virtual void addClientNotification(GraphicalObject* object, t_ilm_notification_mask mask);
virtual NotificationQueue& getClientNotificationQueue();
void printDebugInformation() const;
bool startAllRenderers(const int width, const int height, const char *displayName);
bool startAllCommunicators();
+ bool startAllHealthMonitors();
bool delegateScene();
+ void stopAllHealthMonitors();
void stopAllRenderers();
void stopAllCommunicators();
bool executeCommand(ICommand* commandToBeExecuted);
RendererList* m_pRendererList;
CommunicatorList* m_pCommunicatorList;
SceneProviderList* m_pSceneProviderList;
+ HealthMonitorList* m_pHealthMonitorList;
NotificationQueue m_clientNotificationQueue;
ApplicationReferenceMap* m_pApplicationReferenceMap;
PidToProcessNameTable m_pidToProcessNameTable;
CommandListMap m_EnqueuedCommands;
- IHealth* m_pHealth;
pthread_t m_pWatchdogThread;
bool mHealthState;
PluginList mMonitoredPlugins;
return m_pSceneProviderList;
}
+inline HealthMonitorList* Layermanager::getHealthMonitorList(void)
+{
+ return m_pHealthMonitorList;
+}
+
inline ApplicationReferenceMap* Layermanager::getApplicationReferenceMap(void)
{
return m_pApplicationReferenceMap;
#include "RendererList.h"
#include "CommunicatorList.h"
#include "SceneProviderList.h"
+#include "HealthMonitorList.h"
class ICommandExecutor;
class Configuration;
RendererList* getRendererList();
CommunicatorList* getCommunicatorList();
SceneProviderList* getSceneProviderList();
+ HealthMonitorList* getHealthMonitorList();
private:
void createAndStartAllPlugins();
RendererList mRendererList;
CommunicatorList mCommunicatorList;
SceneProviderList mSceneProviderList;
+ HealthMonitorList mHealthMonitorList;
};
#endif // __PLUGINMANAGER_H__
#include "CommandList.h"
#include "LayerList.h"
#include "ICommand.h"
-#include "IHealth.h"
+#include "IHealthMonitor.h"
#include "ICommunicator.h"
#include "IRenderer.h"
#include "ISceneProvider.h"
#include <pthread.h>
#include <signal.h>
-#ifdef WITH_SYSTEMD
- #include "HealthSystemd.h"
-#endif
-
static const char* NO_SENDER_NAME = "unknown";
Layermanager::Layermanager(Configuration& config)
-: m_pHealth(NULL)
-, mConfiguration(config)
+:mConfiguration(config)
{
m_pScene = new Scene();
m_pPluginManager = new PluginManager(*this, mConfiguration);
m_pApplicationReferenceMap = new ApplicationReferenceMap();
-#ifdef WITH_SYSTEMD
- m_pHealth = new HealthSystemd(*this, mConfiguration);
-#endif
-
m_pRendererList = m_pPluginManager->getRendererList();
m_pCommunicatorList = m_pPluginManager->getCommunicatorList();
m_pSceneProviderList = m_pPluginManager->getSceneProviderList();
+ m_pHealthMonitorList = m_pPluginManager->getHealthMonitorList();
mHealthState = true;
}
Layermanager::~Layermanager()
{
- if (m_pHealth)
- {
- delete m_pHealth;
- }
-
if (m_pApplicationReferenceMap)
{
delete m_pApplicationReferenceMap;
{
m_pSceneProviderList->push_back(sceneProvider);
}
-
}
void Layermanager::removeSceneProvider(ISceneProvider* sceneProvider)
m_pSceneProviderList->remove(sceneProvider);
}
}
+
+void Layermanager::addHealthMonitor(IHealthMonitor* healthMonitor)
+{
+ if (healthMonitor)
+ {
+ m_pHealthMonitorList->push_back(healthMonitor);
+ }
+}
+
+void Layermanager::removeHealthMonitor(IHealthMonitor* healthMonitor)
+{
+ if (healthMonitor)
+ {
+ m_pHealthMonitorList->remove(healthMonitor);
+ }
+}
+
void Layermanager::addApplicationReference(t_ilm_client_handle client, IApplicationReference* reference)
{
if (client && reference)
bool Layermanager::startAllCommunicators()
{
bool allStarted = true;
-
+
CommunicatorListIterator communicatorIter = m_pCommunicatorList->begin();
CommunicatorListIterator communicatorIterEnd = m_pCommunicatorList->end();
-
+
for (; communicatorIter != communicatorIterEnd; ++communicatorIter)
{
ICommunicator *communicator = *communicatorIter;
return allStarted;
}
+bool Layermanager::startAllHealthMonitors()
+{
+ bool allStarted = true;
+
+ HealthMonitorListIterator iter = m_pHealthMonitorList->begin();
+ HealthMonitorListIterator iterEnd = m_pHealthMonitorList->end();
+
+ for (; iter != iterEnd; ++iter)
+ {
+ IHealthMonitor* healthMonitor = *iter;
+ if (healthMonitor)
+ {
+ allStarted &= healthMonitor->start();
+ }
+ else
+ {
+ allStarted = false;
+ }
+ }
+ if (!allStarted)
+ {
+ LOG_ERROR("LayerManagerService","Could not start Health Monitors");
+ }
+ return allStarted;
+}
+
bool Layermanager::startManagement()
{
bool result = false;
// 3. start communication (after scene is ready to use)
result = startAllRenderers(width, height, displayName)
&& delegateScene()
- && startAllCommunicators();
-
-#ifdef WITH_SYSTEMD
- result &= m_pHealth->start();
-#endif
+ && startAllCommunicators()
+ && startAllHealthMonitors();
return result;
}
+void Layermanager::stopAllHealthMonitors()
+{
+ HealthMonitorListIterator iter = m_pHealthMonitorList->begin();
+ HealthMonitorListIterator iterEnd = m_pHealthMonitorList->end();
+ for (; iter != iterEnd; ++iter)
+ {
+ IHealthMonitor* healthMonitor = *iter;
+ if (healthMonitor)
+ {
+ healthMonitor->stop();
+ }
+ }
+}
+
void Layermanager::stopAllRenderers()
{
RendererListIterator iter = m_pRendererList->begin();
bool Layermanager::stopManagement()
{
-#ifdef WITH_SYSTEMD
- m_pHealth->stop();
-#endif
+ stopAllHealthMonitors();
stopAllRenderers();
stopAllCommunicators();
return true; // TODO
uint gScenePluginDirectoriesCount = sizeof(gScenePluginDirectories) / sizeof(gScenePluginDirectories[0]);
+const char* gHealthPluginDirectories[] = { "/health" };
+
+uint gHealthPluginDirectoriesCount = sizeof(gHealthPluginDirectories) / sizeof(gHealthPluginDirectories[0]);
+
//===========================================================================
// global functions for loading plugins
//===========================================================================
closedir(directory);
}
+void loadHealthPlugins(HealthMonitorList& healthMonitorList, ICommandExecutor* executor)
+{
+ tFileList sharedLibraryNameList;
+
+ // search sceneprovider plugins in configured directories
+ for (uint dirIndex = 0; dirIndex < gScenePluginDirectoriesCount; ++dirIndex)
+ {
+ char directoryName[1024];
+ strncpy(directoryName, gPluginLookupPath, sizeof(directoryName) - 1);
+ strncat(directoryName, gHealthPluginDirectories[dirIndex], sizeof(directoryName) - 1 - strlen(directoryName));
+ LOG_DEBUG("LayerManagerService", "Searching for HealthMonitors in: " << directoryName);
+ getSharedLibrariesFromDirectory(sharedLibraryNameList, directoryName);
+ }
+
+ LOG_DEBUG("LayerManagerService", sharedLibraryNameList.size() << " HealthMonitor plugins found");
+
+ // iterate all communicator plugins and start them
+ tFileListIterator iter = sharedLibraryNameList.begin();
+ tFileListIterator iterEnd = sharedLibraryNameList.end();
+
+ for (; iter != iterEnd; ++iter)
+ {
+ LOG_INFO("LayerManagerService", "Loading HealthMonitor plugin " << *iter);
+
+ IHealthMonitor* (*createFunc)(ICommandExecutor* executor);
+ createFunc = getCreateFunction<IHealthMonitor*(ICommandExecutor* executor)>(*iter);
+
+ if (!createFunc)
+ {
+ LOG_DEBUG("LayerManagerService", "Entry point of HealthMonitor not found");
+ continue;
+ }
+
+ LOG_DEBUG("LayerManagerService", "Creating HealthMonitor instance");
+ IHealthMonitor* newHealthMonitor = createFunc(executor);
+
+ if (!newHealthMonitor)
+ {
+ LOG_ERROR("LayerManagerService","HealthMonitor initialization failed. Entry Function not callable");
+ continue;
+ }
+
+ healthMonitorList.push_back(newHealthMonitor);
+ }
+}
+
+
void loadScenePlugins(SceneProviderList& sceneProviderList, ICommandExecutor* executor)
{
tFileList sharedLibraryNameList;
return &mSceneProviderList;
}
+HealthMonitorList* PluginManager::getHealthMonitorList()
+{
+ return &mHealthMonitorList;
+}
+
void PluginManager::createAndStartAllPlugins()
{
gPluginLookupPath = mConfiguration.getPluginPath().c_str();
LOG_INFO("LayerManagerService", "Used plugin directory is " << gPluginLookupPath);
- // Create and load Renderer plugins
LOG_DEBUG("LayerManagerService", "Loading renderer plugins.");
loadRendererPlugins(mRendererList, mExecutor.getScene());
- // Create and load communicator plugins
LOG_DEBUG("LayerManagerService", "Loading communicator plugins.");
loadCommunicatorPlugins(mCommunicatorList, &mExecutor);
LOG_DEBUG("LayerManagerService", "Loading scene provider plugins.");
loadScenePlugins(mSceneProviderList, &mExecutor);
+
+ LOG_DEBUG("LayerManagerService", "Loading health monitor plugins.");
+ loadHealthPlugins(mHealthMonitorList, &mExecutor);
}
void PluginManager::stopAndDestroyAllPlugins()
// build tcp/ip ipc module
#cmakedefine WITH_IPC_MODULE_TCP
-// build with native systemd support
-#cmakedefine WITH_SYSTEMD
+// build plugin for systemd health monitoring
+#cmakedefine WITH_PLUGIN_SYSTEMD_HEALTH_MONITOR
//-----------------------------------------------------------------------------
{ DEBUG_FLAG, "WITH_WAYLAND_X11 = ${WITH_WAYLAND_X11}" },
{ DEBUG_FLAG, "WITH_WL_EXAMPLE = ${WITH_WL_EXAMPLE}" },
{ DEBUG_FLAG, "WITH_X11_GLES = ${WITH_X11_GLES}" },
- { DEBUG_FLAG, "WITH_SYSTEMD = ${WITH_SYSTEMD}" }
+ { DEBUG_FLAG, "WITH_PLUGIN_SYSTEMD.. = ${WITH_PLUGIN_SYSTEMD_HEALTH_MONITOR}" }
};
const int gBuildFlagCount = sizeof(gBuildFlags) / sizeof(gBuildFlags[0]);