1ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard/* 2b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * Copyright (c) 2011-2014, Intel Corporation 3b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * All rights reserved. 4ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard * 5b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * Redistribution and use in source and binary forms, with or without modification, 6b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * are permitted provided that the following conditions are met: 7ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard * 8b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 1. Redistributions of source code must retain the above copyright notice, this 9b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * list of conditions and the following disclaimer. 10ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard * 11b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 2. Redistributions in binary form must reproduce the above copyright notice, 12b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * this list of conditions and the following disclaimer in the documentation and/or 13b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * other materials provided with the distribution. 14b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 15b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 3. Neither the name of the copyright holder nor the names of its contributors 16b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * may be used to endorse or promote products derived from this software without 17b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * specific prior written permission. 18b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 19b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 23b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2968a912857707864bbaaff9808717813105072a6ePatrick Benavoli */ 3068a912857707864bbaaff9808717813105072a6ePatrick Benavoli#include <dlfcn.h> 3168a912857707864bbaaff9808717813105072a6ePatrick Benavoli#include <dirent.h> 32ec0f84e3f601ac4ffb029b903c06007956c4b02aPatrick Benavoli#include <algorithm> 33ec0f84e3f601ac4ffb029b903c06007956c4b02aPatrick Benavoli#include <ctype.h> 3468a912857707864bbaaff9808717813105072a6ePatrick Benavoli#include "SystemClass.h" 3568a912857707864bbaaff9808717813105072a6ePatrick Benavoli#include "SubsystemLibrary.h" 3668a912857707864bbaaff9808717813105072a6ePatrick Benavoli#include "AutoLog.h" 376ccab9d382c08323fb1f000d859a696f05719c92Patrick Benavoli#include "VirtualSubsystem.h" 386ccab9d382c08323fb1f000d859a696f05719c92Patrick Benavoli#include "NamedElementBuilderTemplate.h" 399bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli#include <assert.h> 40a4ec15d5d5e84fbee3faa46a66e7b1eb90816ce2Guillaume Denneulin#include "PluginLocation.h" 41ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard#include "Utility.h" 4268a912857707864bbaaff9808717813105072a6ePatrick Benavoli 4368a912857707864bbaaff9808717813105072a6ePatrick Benavoli#define base CConfigurableElement 4468a912857707864bbaaff9808717813105072a6ePatrick Benavoli 45d9526499d6ab53b7d13d1434f748f6f2161c2e0aSebastien Gonzalveusing std::list; 46d9526499d6ab53b7d13d1434f748f6f2161c2e0aSebastien Gonzalveusing std::string; 47d9526499d6ab53b7d13d1434f748f6f2161c2e0aSebastien Gonzalve 48d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnard/** 49d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnard * A plugin file name is of the form: 50d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnard * lib<type>-subsystem.so or lib<type>-subsystem._host.so 51d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnard * 52d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnard * The plugin symbol is of the form: 53d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnard * get<TYPE>SubsystemBuilder 54d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnard*/ 55ec0f84e3f601ac4ffb029b903c06007956c4b02aPatrick Benavoli// Plugin file naming 56d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnardconst char* gpcPluginSuffix = "-subsystem"; 57d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnardconst char* gpcPluginPrefix = "lib"; 58ec0f84e3f601ac4ffb029b903c06007956c4b02aPatrick Benavoli 59ec0f84e3f601ac4ffb029b903c06007956c4b02aPatrick Benavoli// Plugin symbol naming 60ec0f84e3f601ac4ffb029b903c06007956c4b02aPatrick Benavoliconst char* gpcPluginSymbolPrefix = "get"; 61487ce850cc5f884f7689a2bfd55a7e1cf6eb3053Frédéric Boisnardconst char* gpcPluginSymbolSuffix = "SubsystemBuilder"; 62ec0f84e3f601ac4ffb029b903c06007956c4b02aPatrick Benavoli 6368a912857707864bbaaff9808717813105072a6ePatrick Benavoli// Used by subsystem plugins 64487ce850cc5f884f7689a2bfd55a7e1cf6eb3053Frédéric Boisnardtypedef void (*GetSubsystemBuilder)(CSubsystemLibrary*); 6568a912857707864bbaaff9808717813105072a6ePatrick Benavoli 6695ac034b72580306e9246f7efa3f7ba709a02183Patrick BenavoliCSystemClass::CSystemClass() : _pSubsystemLibrary(new CSubsystemLibrary) 6768a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 6868a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 6968a912857707864bbaaff9808717813105072a6ePatrick Benavoli 7068a912857707864bbaaff9808717813105072a6ePatrick BenavoliCSystemClass::~CSystemClass() 7168a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 7268a912857707864bbaaff9808717813105072a6ePatrick Benavoli delete _pSubsystemLibrary; 731b8b3ca093ecd7dc8c1877352625508ca4a81728Renaud de Chivre 7479694d5d0a632ed4ca04ea42f19fb09c3fba0cdbPatrick Benavoli // Destroy child subsystems *before* unloading the libraries (otherwise crashes will occur 7579694d5d0a632ed4ca04ea42f19fb09c3fba0cdbPatrick Benavoli // as unmapped code will be referenced) 7679694d5d0a632ed4ca04ea42f19fb09c3fba0cdbPatrick Benavoli clean(); 7779694d5d0a632ed4ca04ea42f19fb09c3fba0cdbPatrick Benavoli 7879694d5d0a632ed4ca04ea42f19fb09c3fba0cdbPatrick Benavoli // Close all previously opened subsystem libraries 7979694d5d0a632ed4ca04ea42f19fb09c3fba0cdbPatrick Benavoli list<void*>::const_iterator it; 8079694d5d0a632ed4ca04ea42f19fb09c3fba0cdbPatrick Benavoli 8179694d5d0a632ed4ca04ea42f19fb09c3fba0cdbPatrick Benavoli for (it = _subsystemLibraryHandleList.begin(); it != _subsystemLibraryHandleList.end(); ++it) { 8279694d5d0a632ed4ca04ea42f19fb09c3fba0cdbPatrick Benavoli 8379694d5d0a632ed4ca04ea42f19fb09c3fba0cdbPatrick Benavoli dlclose(*it); 841b8b3ca093ecd7dc8c1877352625508ca4a81728Renaud de Chivre } 8568a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 8668a912857707864bbaaff9808717813105072a6ePatrick Benavoli 8768a912857707864bbaaff9808717813105072a6ePatrick Benavolibool CSystemClass::childrenAreDynamic() const 8868a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 8968a912857707864bbaaff9808717813105072a6ePatrick Benavoli return true; 9068a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 9168a912857707864bbaaff9808717813105072a6ePatrick Benavoli 9268a912857707864bbaaff9808717813105072a6ePatrick Benavolistring CSystemClass::getKind() const 9368a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 9468a912857707864bbaaff9808717813105072a6ePatrick Benavoli return "SystemClass"; 9568a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 9668a912857707864bbaaff9808717813105072a6ePatrick Benavoli 97ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocardbool CSystemClass::loadSubsystems(string& strError, 986be8035935a21661833bddd3803e279652e81416Kevin Rocard const CSubsystemPlugins* pSubsystemPlugins, 996be8035935a21661833bddd3803e279652e81416Kevin Rocard bool bVirtualSubsystemFallback) 10068a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 101ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard CAutoLog autoLog_info(this, "Loading subsystem plugins"); 10268a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1036be8035935a21661833bddd3803e279652e81416Kevin Rocard // Start clean 1046be8035935a21661833bddd3803e279652e81416Kevin Rocard _pSubsystemLibrary->clean(); 1056be8035935a21661833bddd3803e279652e81416Kevin Rocard 1066be8035935a21661833bddd3803e279652e81416Kevin Rocard // Add virtual subsystem builder 1076be8035935a21661833bddd3803e279652e81416Kevin Rocard _pSubsystemLibrary->addElementBuilder("Virtual", 1086be8035935a21661833bddd3803e279652e81416Kevin Rocard new TNamedElementBuilderTemplate<CVirtualSubsystem>()); 1096be8035935a21661833bddd3803e279652e81416Kevin Rocard // Set virtual subsytem as builder fallback if required 1106be8035935a21661833bddd3803e279652e81416Kevin Rocard _pSubsystemLibrary->enableDefaultMechanism(bVirtualSubsystemFallback); 1116be8035935a21661833bddd3803e279652e81416Kevin Rocard 1126be8035935a21661833bddd3803e279652e81416Kevin Rocard // Add subsystem defined in shared libraries 1136be8035935a21661833bddd3803e279652e81416Kevin Rocard list<string> lstrError; 1146be8035935a21661833bddd3803e279652e81416Kevin Rocard bool bLoadPluginsSuccess = loadSubsystemsFromSharedLibraries(lstrError, pSubsystemPlugins); 1156be8035935a21661833bddd3803e279652e81416Kevin Rocard 1166be8035935a21661833bddd3803e279652e81416Kevin Rocard if (bLoadPluginsSuccess) { 1176be8035935a21661833bddd3803e279652e81416Kevin Rocard log_info("All subsystem plugins successfully loaded"); 1186be8035935a21661833bddd3803e279652e81416Kevin Rocard } else { 1196be8035935a21661833bddd3803e279652e81416Kevin Rocard // Log plugin as warning if no fallback available 1206be8035935a21661833bddd3803e279652e81416Kevin Rocard log_table(!bVirtualSubsystemFallback, lstrError); 1216be8035935a21661833bddd3803e279652e81416Kevin Rocard } 1226be8035935a21661833bddd3803e279652e81416Kevin Rocard 1236be8035935a21661833bddd3803e279652e81416Kevin Rocard if (!bVirtualSubsystemFallback) { 1246be8035935a21661833bddd3803e279652e81416Kevin Rocard // Any problem reported is an error as there is no fallback. 1256be8035935a21661833bddd3803e279652e81416Kevin Rocard // Fill strError for caller. 1266be8035935a21661833bddd3803e279652e81416Kevin Rocard CUtility::asString(lstrError, strError); 1276be8035935a21661833bddd3803e279652e81416Kevin Rocard } 1286be8035935a21661833bddd3803e279652e81416Kevin Rocard 1296be8035935a21661833bddd3803e279652e81416Kevin Rocard return bLoadPluginsSuccess || bVirtualSubsystemFallback; 1306be8035935a21661833bddd3803e279652e81416Kevin Rocard} 1316be8035935a21661833bddd3803e279652e81416Kevin Rocard 1326be8035935a21661833bddd3803e279652e81416Kevin Rocardbool CSystemClass::loadSubsystemsFromSharedLibraries(list<string>& lstrError, 1336be8035935a21661833bddd3803e279652e81416Kevin Rocard const CSubsystemPlugins* pSubsystemPlugins) 1346be8035935a21661833bddd3803e279652e81416Kevin Rocard{ 13568a912857707864bbaaff9808717813105072a6ePatrick Benavoli // Plugin list 1369bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli list<string> lstrPluginFiles; 13768a912857707864bbaaff9808717813105072a6ePatrick Benavoli 138a4ec15d5d5e84fbee3faa46a66e7b1eb90816ce2Guillaume Denneulin uint32_t uiPluginLocation; 13968a912857707864bbaaff9808717813105072a6ePatrick Benavoli 140a4ec15d5d5e84fbee3faa46a66e7b1eb90816ce2Guillaume Denneulin for (uiPluginLocation = 0; uiPluginLocation < pSubsystemPlugins->getNbChildren(); uiPluginLocation++) { 14168a912857707864bbaaff9808717813105072a6ePatrick Benavoli 142a4ec15d5d5e84fbee3faa46a66e7b1eb90816ce2Guillaume Denneulin // Get Folder for current Plugin Location 143a4ec15d5d5e84fbee3faa46a66e7b1eb90816ce2Guillaume Denneulin const CPluginLocation* pPluginLocation = static_cast<const CPluginLocation*>(pSubsystemPlugins->getChild(uiPluginLocation)); 144a4ec15d5d5e84fbee3faa46a66e7b1eb90816ce2Guillaume Denneulin 145fdcbfb9476ce68a5b899a61775ed9b168c3232a0Louis Le Gall string strFolder(pPluginLocation->getFolder()); 146fdcbfb9476ce68a5b899a61775ed9b168c3232a0Louis Le Gall if (!strFolder.empty()) { 147fdcbfb9476ce68a5b899a61775ed9b168c3232a0Louis Le Gall strFolder += "/"; 148fdcbfb9476ce68a5b899a61775ed9b168c3232a0Louis Le Gall } 149a4ec15d5d5e84fbee3faa46a66e7b1eb90816ce2Guillaume Denneulin // Iterator on Plugin List: 150a4ec15d5d5e84fbee3faa46a66e7b1eb90816ce2Guillaume Denneulin list<string>::const_iterator it; 151a4ec15d5d5e84fbee3faa46a66e7b1eb90816ce2Guillaume Denneulin 152a4ec15d5d5e84fbee3faa46a66e7b1eb90816ce2Guillaume Denneulin const list<string>& pluginList = pPluginLocation->getPluginList(); 153a4ec15d5d5e84fbee3faa46a66e7b1eb90816ce2Guillaume Denneulin 154a4ec15d5d5e84fbee3faa46a66e7b1eb90816ce2Guillaume Denneulin for (it = pluginList.begin(); it != pluginList.end(); ++it) { 155a4ec15d5d5e84fbee3faa46a66e7b1eb90816ce2Guillaume Denneulin 156a4ec15d5d5e84fbee3faa46a66e7b1eb90816ce2Guillaume Denneulin // Fill Plugin files list 157fdcbfb9476ce68a5b899a61775ed9b168c3232a0Louis Le Gall lstrPluginFiles.push_back(strFolder + *it); 158a4ec15d5d5e84fbee3faa46a66e7b1eb90816ce2Guillaume Denneulin } 15968a912857707864bbaaff9808717813105072a6ePatrick Benavoli } 16068a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1619bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli // Actually load plugins 1626be8035935a21661833bddd3803e279652e81416Kevin Rocard while (!lstrPluginFiles.empty()) { 163ec0f84e3f601ac4ffb029b903c06007956c4b02aPatrick Benavoli 1649bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli // Because plugins might depend on one another, loading will be done 1659bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli // as an iteration process that finishes successfully when the remaining 1669bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli // list of plugins to load gets empty or unsuccessfully if the loading 1679bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli // process failed to load at least one of them 16868a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1699bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli // Attempt to load the complete list 170ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard if (!loadPlugins(lstrPluginFiles, lstrError)) { 17168a912857707864bbaaff9808717813105072a6ePatrick Benavoli 172ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard // Unable to load at least one plugin 173ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard break; 17468a912857707864bbaaff9808717813105072a6ePatrick Benavoli } 17568a912857707864bbaaff9808717813105072a6ePatrick Benavoli } 176ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard 1776be8035935a21661833bddd3803e279652e81416Kevin Rocard if (!lstrPluginFiles.empty()) { 1786be8035935a21661833bddd3803e279652e81416Kevin Rocard // Unable to load at least one plugin 1796be8035935a21661833bddd3803e279652e81416Kevin Rocard string strPluginUnloaded; 1806be8035935a21661833bddd3803e279652e81416Kevin Rocard CUtility::asString(lstrPluginFiles, strPluginUnloaded, ", "); 1816ccab9d382c08323fb1f000d859a696f05719c92Patrick Benavoli 182ecddaa31a64a2f62f8685578faf3467dbdf5ffe5Frédéric Boisnard lstrError.push_back("Unable to load the following plugins: " + strPluginUnloaded + "."); 1836be8035935a21661833bddd3803e279652e81416Kevin Rocard return false; 1846be8035935a21661833bddd3803e279652e81416Kevin Rocard } 185ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard 1866be8035935a21661833bddd3803e279652e81416Kevin Rocard return true; 18768a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 18868a912857707864bbaaff9808717813105072a6ePatrick Benavoli 1899bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli// Plugin symbol computation 1909bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavolistring CSystemClass::getPluginSymbol(const string& strPluginPath) 1919bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli{ 1929bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli // Extract plugin type out of file name 193d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnard string strPluginSuffix = gpcPluginSuffix; 194d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnard string strPluginPrefix = gpcPluginPrefix; 195d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnard 196d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnard // Remove folder and library prefix 197d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnard size_t iPluginTypePos = strPluginPath.rfind('/') + 1 + strPluginPrefix.length(); 1989bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 199d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnard // Get index of -subsystem.so or -subsystem_host.so suffix 200d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnard size_t iSubsystemPos = strPluginPath.find(strPluginSuffix, iPluginTypePos); 2019bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 202d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnard // Get type (between iPluginTypePos and iSubsystemPos) 203d5679acf4b38db415bd25b0c3664d69cec5f43d4Frédéric Boisnard string strPluginType = strPluginPath.substr(iPluginTypePos, iSubsystemPos - iPluginTypePos); 2049bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 2059bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli // Make it upper case 2069bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli std::transform(strPluginType.begin(), strPluginType.end(), strPluginType.begin(), ::toupper); 2079bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 2089bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli // Get plugin symbol 2099bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli return gpcPluginSymbolPrefix + strPluginType + gpcPluginSymbolSuffix; 2109bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli} 2119bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 2129bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli// Plugin loading 213ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocardbool CSystemClass::loadPlugins(list<string>& lstrPluginFiles, list<string>& lstrError) 2149bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli{ 2159bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli assert(lstrPluginFiles.size()); 2169bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 217ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard bool bAtLeastOneSubsystemPluginSuccessfullyLoaded = false; 2189bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 2199bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli list<string>::iterator it = lstrPluginFiles.begin(); 2209bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 2219bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli while (it != lstrPluginFiles.end()) { 2229bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 2239bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli string strPluginFileName = *it; 2249bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 225ace81f873b910493ab884dc5a6a38ba6ec3d56d3Kevin Rocard log_info("Attempting to load subsystem plugin path \"%s\"", strPluginFileName.c_str()); 2269bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 2279bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli // Load attempt 2289bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli void* lib_handle = dlopen(strPluginFileName.c_str(), RTLD_LAZY); 2299bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 2309bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli if (!lib_handle) { 2319bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 23230095b3c0b84e85caf253a27e41254eaf35e4ca7Eduardo Mendi const char *err = dlerror(); 2339bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli // Failed 23430095b3c0b84e85caf253a27e41254eaf35e4ca7Eduardo Mendi if (err == NULL) { 23530095b3c0b84e85caf253a27e41254eaf35e4ca7Eduardo Mendi lstrError.push_back("dlerror failed"); 23630095b3c0b84e85caf253a27e41254eaf35e4ca7Eduardo Mendi } else { 23730095b3c0b84e85caf253a27e41254eaf35e4ca7Eduardo Mendi lstrError.push_back("Plugin load failed: " + string(err)); 23830095b3c0b84e85caf253a27e41254eaf35e4ca7Eduardo Mendi } 2399bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli // Next plugin 2409bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli ++it; 2419bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 2429bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli continue; 2439bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli } 2449bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 2451b8b3ca093ecd7dc8c1877352625508ca4a81728Renaud de Chivre // Store libraries handles 24679694d5d0a632ed4ca04ea42f19fb09c3fba0cdbPatrick Benavoli _subsystemLibraryHandleList.push_back(lib_handle); 2471b8b3ca093ecd7dc8c1877352625508ca4a81728Renaud de Chivre 2489bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli // Get plugin symbol 2499bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli string strPluginSymbol = getPluginSymbol(strPluginFileName); 2509bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 2519bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli // Load symbol from library 252487ce850cc5f884f7689a2bfd55a7e1cf6eb3053Frédéric Boisnard GetSubsystemBuilder pfnGetSubsystemBuilder = (GetSubsystemBuilder)dlsym(lib_handle, strPluginSymbol.c_str()); 2539bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 254487ce850cc5f884f7689a2bfd55a7e1cf6eb3053Frédéric Boisnard if (!pfnGetSubsystemBuilder) { 2559bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 256ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard lstrError.push_back("Subsystem plugin " + strPluginFileName + 257ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard " does not contain " + strPluginSymbol + " symbol."); 2589bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 259ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard continue; 2609bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli } 2619bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 262ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard // Account for this success 263ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard bAtLeastOneSubsystemPluginSuccessfullyLoaded = true; 264ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard 2659bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli // Fill library 266487ce850cc5f884f7689a2bfd55a7e1cf6eb3053Frédéric Boisnard pfnGetSubsystemBuilder(_pSubsystemLibrary); 2679bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 2689bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli // Remove successfully loaded plugin from list and select next 2699bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli lstrPluginFiles.erase(it++); 2709bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli } 2719bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 272ee7ceed5cca416718c70f3ca55fe41b8eb1e11a3Kevin Rocard return bAtLeastOneSubsystemPluginSuccessfullyLoaded; 2739bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli} 2749bed7cea60c371df60ab53c2e7ade186f04266f3Patrick Benavoli 27568a912857707864bbaaff9808717813105072a6ePatrick Benavoliconst CSubsystemLibrary* CSystemClass::getSubsystemLibrary() const 27668a912857707864bbaaff9808717813105072a6ePatrick Benavoli{ 27768a912857707864bbaaff9808717813105072a6ePatrick Benavoli return _pSubsystemLibrary; 27868a912857707864bbaaff9808717813105072a6ePatrick Benavoli} 27968a912857707864bbaaff9808717813105072a6ePatrick Benavoli 280f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulinvoid CSystemClass::checkForSubsystemsToResync(CSyncerSet& syncerSet) 281f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulin{ 282911844b16c6b627f421bc3368de427de3ca9f60cPatrick Benavoli size_t uiNbChildren = getNbChildren(); 283911844b16c6b627f421bc3368de427de3ca9f60cPatrick Benavoli size_t uiChild; 284f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulin 285f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulin for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { 286f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulin 287f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulin CSubsystem* pSubsystem = static_cast<CSubsystem*>(getChild(uiChild)); 288f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulin 289f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulin // Collect and consume the need for a resync 290f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulin if (pSubsystem->needResync(true)) { 291f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulin 292f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulin log_info("Resynchronizing subsystem: %s", pSubsystem->getName().c_str()); 293f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulin // get all subsystem syncers 294f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulin pSubsystem->fillSyncerSet(syncerSet); 295f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulin } 296f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulin } 297f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulin} 298f2fd15a331fd3b5b63f0dc6f492651330adcedf9Guillaume Denneulin 2992fbe6e8d585e3f4d1f9134f6954615f616bb7815Kevin Rocardvoid CSystemClass::cleanSubsystemsNeedToResync() 3002fbe6e8d585e3f4d1f9134f6954615f616bb7815Kevin Rocard{ 301911844b16c6b627f421bc3368de427de3ca9f60cPatrick Benavoli size_t uiNbChildren = getNbChildren(); 302911844b16c6b627f421bc3368de427de3ca9f60cPatrick Benavoli size_t uiChild; 3032fbe6e8d585e3f4d1f9134f6954615f616bb7815Kevin Rocard 3042fbe6e8d585e3f4d1f9134f6954615f616bb7815Kevin Rocard for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { 3052fbe6e8d585e3f4d1f9134f6954615f616bb7815Kevin Rocard 3062fbe6e8d585e3f4d1f9134f6954615f616bb7815Kevin Rocard CSubsystem* pSubsystem = static_cast<CSubsystem*>(getChild(uiChild)); 3072fbe6e8d585e3f4d1f9134f6954615f616bb7815Kevin Rocard 3082fbe6e8d585e3f4d1f9134f6954615f616bb7815Kevin Rocard // Consume the need for a resync 3092fbe6e8d585e3f4d1f9134f6954615f616bb7815Kevin Rocard pSubsystem->needResync(true); 3102fbe6e8d585e3f4d1f9134f6954615f616bb7815Kevin Rocard } 3112fbe6e8d585e3f4d1f9134f6954615f616bb7815Kevin Rocard} 312