X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FLifeCycleCORBA%2FSALOME_LifeCycleCORBA.cxx;h=2afca3b7f4efe1a69ded3a74b3be8f59e249f54f;hb=54c311c4540ce9169bcb2d291f27d222162a04f0;hp=af5848155456dab9d351cc21659f2bee223306c6;hpb=238f9ea97c32572bd12b176ab6bdcb52f810d1de;p=modules%2Fkernel.git diff --git a/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx b/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx index af5848155..2afca3b7f 100644 --- a/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx +++ b/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx @@ -1,324 +1,933 @@ -// SALOME LifeCycleCORBA : implementation of containers and engines life cycle both in Python and C++ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SALOME LifeCycleCORBA : implementation of containers and engines life cycle both in Python and C++ // File : SALOME_LifeCycleCORBA.cxx // Author : Paul RASCLE, EDF // Module : SALOME -// $Header$ #include #include #include #include -#include "OpUtil.hxx" +#include +#ifndef WIN32 + #include + #include +#endif + +#include "Basics_Utils.hxx" #include "utilities.h" -#include "Launchers.hxx" #include #include "SALOME_LifeCycleCORBA.hxx" #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog) +#include CORBA_CLIENT_HEADER(SALOME_Session) +#include CORBA_CLIENT_HEADER(DSC_Engines) +#include CORBA_CLIENT_HEADER(SALOME_Registry) +#include CORBA_CLIENT_HEADER(SALOMEDS) +#include CORBA_CLIENT_HEADER(Logger) + #include "SALOME_ContainerManager.hxx" #include "SALOME_Component_i.hxx" #include "SALOME_NamingService.hxx" -using namespace std; +#include "SALOME_FileTransferCORBA.hxx" + +IncompatibleComponent::IncompatibleComponent( void ): + SALOME_Exception( "IncompatibleComponent" ) +{ +} + +IncompatibleComponent::IncompatibleComponent(const IncompatibleComponent &ex): + SALOME_Exception( ex ) +{ +} + +/*! \class SALOME_LifeCycleCORBA + \brief A class to manage life cycle of SALOME components. + +*/ + +//============================================================================= +/*! + * Constructor + */ +//============================================================================= SALOME_LifeCycleCORBA::SALOME_LifeCycleCORBA(SALOME_NamingService *ns) { - _NS = ns; + // be sure to have an instance of traceCollector, when used via SWIG + // in a Python module + int argc = 0; + char *xargv = (char*)""; + char **argv = &xargv; + CORBA::ORB_var orb = CORBA::ORB_init(argc, argv); + // LocalTraceCollector *myThreadTrace = SALOMETraceCollector::instance(orb); + _NSnew=0; + if (!ns) + { + _NS = new SALOME_NamingService(orb); + _NSnew=_NS; + } + else _NS = ns; //add try catch - _NS->Change_Directory("/"); // mpv 250105: current directory may be not root (in SALOMEDS for an example) - CORBA::Object_var obj=_NS->Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS); + _NS->Change_Directory("/"); // mpv 250105: current directory may be not root + // (in SALOMEDS for an example) + // not enough: set a current directory in naming service is not thread safe + // if naming service instance is shared among several threads... + // ==> allways use absolute path and dot rely on current directory! + + CORBA::Object_var obj = + _NS->Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS); ASSERT( !CORBA::is_nil(obj)); _ContManager=Engines::ContainerManager::_narrow(obj); + + obj = _NS->Resolve(SALOME_ResourcesManager::_ResourcesManagerNameInNS); + ASSERT( !CORBA::is_nil(obj)); + _ResManager=Engines::ResourcesManager::_narrow(obj); } +//============================================================================= +/*! + * Destructor + */ +//============================================================================= + SALOME_LifeCycleCORBA::~SALOME_LifeCycleCORBA() { + if(_NSnew)delete _NSnew; } -string SALOME_LifeCycleCORBA::ContainerName( - const char * aComputerContainer , - string * theComputer , - string * theContainer ) { - char * ContainerName = new char [ strlen( aComputerContainer ) + 1 ] ; - strcpy( ContainerName , aComputerContainer ) ; - string theComputerContainer("/Containers/"); - char * slash = strchr( ContainerName , '/' ) ; - if ( !slash ) { - *theComputer = GetHostname() ; - theComputerContainer += *theComputer ; - theComputerContainer += "/" ; - *theContainer = ContainerName ; - theComputerContainer += *theContainer ; - } - else { - slash[ 0 ] = '\0' ; - slash += 1 ; - *theContainer = slash ; - if ( !strcmp( ContainerName , "localhost" ) ) { - *theComputer = GetHostname() ; +//============================================================================= +/*! \brief Find an already existing and registered component instance. + * + * \param params machine parameters like type or name... + * \param componentName the name of component class + * \param studyId default = 0 : multistudy instance + * \return a CORBA reference of the component instance, or _nil if not found + */ +//============================================================================= +Engines::EngineComponent_ptr +SALOME_LifeCycleCORBA::FindComponent(const Engines::MachineParameters& params, + const char *componentName, + int studyId) +{ + if (! isKnownComponentClass(componentName)) + return Engines::EngineComponent::_nil(); + + Engines::ContainerParameters new_params; + convert(params, new_params); + new_params.resource_params.componentList.length(1); + new_params.resource_params.componentList[0] = componentName; + Engines::ResourceList_var listOfResources; + try + { + listOfResources = _ResManager->GetFittingResources(new_params.resource_params); } - else { - *theComputer = ContainerName ; + catch( const SALOME::SALOME_Exception& ex ) + { + return Engines::EngineComponent::_nil(); } - theComputerContainer += *theComputer ; - theComputerContainer += "/" ; - theComputerContainer += *theContainer ; - } - delete [] ContainerName; - return theComputerContainer ; + + Engines::EngineComponent_var compo = _FindComponent(new_params, + componentName, + studyId, + listOfResources); + + return compo._retn(); } -bool SALOME_LifeCycleCORBA::isKnownComponentClass(const char *componentName) +//============================================================================= +/*! \brief Load a component instance on a container defined by machine parameters + * + * \param params machine parameters like type or name... + * \param componentName the name of component class + * \param studyId default = 0 : multistudy instance + * \return a CORBA reference of the component instance, or _nil if problem + */ +//============================================================================= + +Engines::EngineComponent_ptr +SALOME_LifeCycleCORBA::LoadComponent(const Engines::MachineParameters& params, + const char *componentName, + int studyId) { + // --- Check if Component Name is known in ModuleCatalog + + if (! isKnownComponentClass(componentName)) + return Engines::EngineComponent::_nil(); + Engines::ContainerParameters new_params; + convert(params, new_params); + new_params.resource_params.componentList.length(1); + new_params.resource_params.componentList[0] = componentName; + + Engines::ResourceList_var listOfResources; try { - CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog"); - SALOME_ModuleCatalog::ModuleCatalog_var Catalog = - SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ; - SALOME_ModuleCatalog::Acomponent_ptr compoInfo = - Catalog->GetComponent(componentName); - if (CORBA::is_nil (compoInfo)) - { - INFOS("Catalog Error : Component not found in the catalog"); - return false; - } - else return true; + listOfResources = _ResManager->GetFittingResources(new_params.resource_params); } - catch (ServiceUnreachable&) + catch( const SALOME::SALOME_Exception& ex ) { - INFOS("Caught exception: Naming Service Unreachable"); + return Engines::EngineComponent::_nil(); } - catch (...) - { - INFOS("Caught unknown exception."); - } - return false; + new_params.resource_params.resList = listOfResources; + + Engines::EngineComponent_var compo = _LoadComponent(new_params, + componentName, + studyId); + + return compo._retn(); } -string SALOME_LifeCycleCORBA::ComputerPath( - const char * theComputer ) { - CORBA::String_var path; - CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog"); - SALOME_ModuleCatalog::ModuleCatalog_var Catalog = - SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ; - try { - path = Catalog->GetPathPrefix( theComputer ); +//============================================================================= +/*! \brief Find an already existing and registered component instance or load a new + * component instance on a container defined by machine parameters. + * + * \param params machine parameters like type or name... + * \param componentName the name of component class + * \param studyId default = 0 : multistudy instance + * \return a CORBA reference of the component instance, or _nil if problem + */ +//============================================================================= + +Engines::EngineComponent_ptr +SALOME_LifeCycleCORBA:: +FindOrLoad_Component(const Engines::MachineParameters& params, + const char *componentName, + int studyId) +{ + // --- Check if Component Name is known in ModuleCatalog + + if (! isKnownComponentClass(componentName)) + return Engines::EngineComponent::_nil(); + + Engines::ContainerParameters new_params; + convert(params, new_params); + new_params.resource_params.componentList.length(1); + new_params.resource_params.componentList[0] = componentName; + + // For Compatibility -> if hostname == localhost put name == hostname + if (std::string(new_params.resource_params.hostname.in()) == "localhost") + { + new_params.resource_params.hostname = CORBA::string_dup(Kernel_Utils::GetHostname().c_str()); + new_params.resource_params.name = CORBA::string_dup(Kernel_Utils::GetHostname().c_str()); } - catch (SALOME_ModuleCatalog::NotFound&) { - INFOS("GetPathPrefix(" << theComputer << ") not found!"); - path = "" ; + + Engines::ResourceList_var listOfResources; + try + { + listOfResources = _ResManager->GetFittingResources(new_params.resource_params); + } + catch( const SALOME::SALOME_Exception& ex ) + { + return Engines::EngineComponent::_nil(); + } + + Engines::EngineComponent_var compo = _FindComponent(new_params, + componentName, + studyId, + listOfResources); + + if(CORBA::is_nil(compo)) + { + new_params.resource_params.resList = listOfResources; + compo = _LoadComponent(new_params, + componentName, + studyId); } - SCRUTE( path ) ; - return CORBA::string_dup( path ) ; + + return compo._retn(); } -Engines::Container_ptr SALOME_LifeCycleCORBA::FindContainer(const char *containerName) +Engines::EngineComponent_ptr +SALOME_LifeCycleCORBA:: +FindOrLoad_Component(const Engines::ContainerParameters& params, + const char *componentName, + int studyId) { - ASSERT(_NS != NULL); - string cont ; - if ( strncmp( containerName , "/Containers/" , 12 ) ) { // Compatibility ... - string theComputer ; - string theContainer ; - cont = ContainerName( containerName , &theComputer , &theContainer ) ; - } - else { - cont = containerName ; - } - try { + // --- Check if Component Name is known in ModuleCatalog - SCRUTE( cont ); + if (! isKnownComponentClass(componentName)) + return Engines::EngineComponent::_nil(); - CORBA::Object_var obj = _NS->Resolve( cont.c_str() ); - if( !CORBA::is_nil( obj ) ) { - return Engines::Container::_narrow( obj ) ; + Engines::ContainerParameters new_params(params); + new_params.resource_params.componentList.length(1); + new_params.resource_params.componentList[0] = componentName; + + Engines::ResourceList_var listOfResources; + try + { + listOfResources = _ResManager->GetFittingResources(new_params.resource_params); } + catch( const SALOME::SALOME_Exception& ex ) + { + return Engines::EngineComponent::_nil(); + } + + Engines::EngineComponent_var compo = _FindComponent(new_params, + componentName, + studyId, + listOfResources); + + if(CORBA::is_nil(compo)) + { + new_params.resource_params.resList = listOfResources; + compo = _LoadComponent(new_params, + componentName, + studyId); } - catch (ServiceUnreachable&) { - INFOS("Caught exception: Naming Service Unreachable"); - } - catch (...) { - INFOS("Caught unknown exception."); - } - return Engines::Container::_nil(); + + return compo._retn(); } -Engines::Component_ptr SALOME_LifeCycleCORBA::FindOrLoad_Component - (const char *containerName, - const char *componentName) +//============================================================================= +/*! \brief Find an already existing and registered component instance or load a new + * component instance on a container defined by name + * + * \param containerName the name of container, under one of the forms + * - 1 aContainer (local container) + * - 2 machine/aContainer (container on hostname = machine) + * \param componentName the name of component class + * \return a CORBA reference of the component instance, or _nil if problem + */ +//============================================================================= + +Engines::EngineComponent_ptr +SALOME_LifeCycleCORBA::FindOrLoad_Component(const char *containerName, + const char *componentName) { - if (! isKnownComponentClass(componentName)) return Engines::Component::_nil(); + MESSAGE("SALOME_LifeCycleCORBA::FindOrLoad_Component INTERACTIF " << containerName << " " << componentName ) ; + + // --- Check if Component Name is known in ModuleCatalog + if (! isKnownComponentClass(componentName)) + return Engines::EngineComponent::_nil(); + + // --- Check if containerName contains machine name (if yes: rg>0) char *stContainer=strdup(containerName); - string st2Container(stContainer); + std::string st2Container(stContainer); int rg=st2Container.find("/"); - if(rg>=0) - { - stContainer[rg]='\0'; - if(strcmp(stContainer,"localhost")==0) - { - Engines::Component_ptr ret=FindOrLoad_Component(stContainer+rg+1,componentName); - free(stContainer); - return ret; - } - } - if(rg<0) { - //containerName doesn't contain "/" => Local container - free(stContainer); - Engines::MachineList_var listOfMachine=new Engines::MachineList; - listOfMachine->length(1); - listOfMachine[0]=CORBA::string_dup(GetHostname().c_str()); - Engines::Component_ptr ret=FindComponent(containerName,componentName,listOfMachine.in()); - if(CORBA::is_nil(ret)) - return LoadComponent(containerName,componentName,listOfMachine); - else - return ret; + + Engines::MachineParameters_var params=new Engines::MachineParameters; + preSet(params); + if (rg<0) + { + // containerName doesn't contain "/" => Local container + params->container_name=CORBA::string_dup(stContainer); + params->hostname=""; } - else { - //containerName contains "/" => Remote container + else + { stContainer[rg]='\0'; - Engines::MachineParameters_var params=new Engines::MachineParameters; params->container_name=CORBA::string_dup(stContainer+rg+1); params->hostname=CORBA::string_dup(stContainer); - params->OS=CORBA::string_dup("LINUX"); - free(stContainer); - return FindOrLoad_Component(params,componentName); } + params->isMPI = false; + SCRUTE(params->container_name); + free(stContainer); + return FindOrLoad_Component(params, componentName); +} + +//============================================================================= +/*! \brief Check if the component class is known in module catalog + * + * \param componentName the name of component class + * \return true if found, false otherwise + */ +//============================================================================= + +bool SALOME_LifeCycleCORBA::isKnownComponentClass(const char *componentName) +{ + try + { + CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog"); + SALOME_ModuleCatalog::ModuleCatalog_var Catalog = + SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ; + ASSERT(! CORBA::is_nil(Catalog)); + SALOME_ModuleCatalog::Acomponent_var compoInfo = + Catalog->GetComponent(componentName); + if (CORBA::is_nil (compoInfo)) + { + MESSAGE("Catalog Error: Component not found in the catalog " << componentName); + return false; + } + else return true; + } + catch (ServiceUnreachable&) + { + INFOS("Caught exception: Naming Service Unreachable"); + } + catch (...) + { + INFOS("Caught unknown exception."); + } + return false; +} + +//============================================================================= +/*! + * Not so complex... useful ? + */ +//============================================================================= + +bool +SALOME_LifeCycleCORBA::isMpiContainer(const Engines::ContainerParameters& params) + throw(IncompatibleComponent) +{ + if( params.isMPI ) + return true; + else + return false; +} + + +//============================================================================= +/*! \brief Initialisation of a given Engines::MachineParameters with default values. + * + * - container_name = "" : not relevant + * - hostname = "" : not relevant + * - OS = "" : not relevant + * - nb_proc = 0 : not relevant + * - mem_mb = 0 : not relevant + * - cpu_clock = 0 : not relevant + * - nb_proc_per_node = 0 : not relevant + * - nb_node = 0 : not relevant + * - isMPI = false : standard components + */ +//============================================================================= + +void SALOME_LifeCycleCORBA::preSet(Engines::MachineParameters& params) +{ + params.container_name = ""; + params.hostname = ""; + params.OS = ""; + params.mem_mb = 0; + params.cpu_clock = 0; + params.nb_proc_per_node = 0; + params.nb_node = 0; + params.isMPI = false; + params.workingdir = ""; + params.mode = ""; + params.policy = ""; + params.parallelLib = ""; + params.nb_component_nodes = 0; +} + +void +SALOME_LifeCycleCORBA::preSet(Engines::ResourceParameters& params) +{ + params.name = ""; + params.hostname = ""; + params.OS = ""; + params.nb_proc = 0; + params.mem_mb = 0; + params.cpu_clock = 0; + params.nb_node = 0; + params.nb_proc_per_node = 0; + params.policy = ""; +} + +void SALOME_LifeCycleCORBA::preSet( Engines::ContainerParameters& params) +{ + params.container_name = ""; + params.mode = ""; + params.workingdir = ""; + params.nb_proc = 0; + params.isMPI = false; + params.parallelLib = ""; + SALOME_LifeCycleCORBA::preSet(params.resource_params); } -Engines::Component_ptr SALOME_LifeCycleCORBA::FindOrLoad_Component(const Engines::MachineParameters& params, - const char *componentName) +void +SALOME_LifeCycleCORBA::convert(const Engines::MachineParameters& params_in, + Engines::ContainerParameters& params_out) { - if (! isKnownComponentClass(componentName)) return Engines::Component::_nil(); - Engines::MachineList_var listOfMachine=_ContManager->GetFittingResources(params,componentName); - Engines::Component_ptr ret=FindComponent(params.container_name,componentName,listOfMachine); - if(CORBA::is_nil(ret)) - return LoadComponent(params.container_name,componentName,listOfMachine); + SALOME_LifeCycleCORBA::preSet(params_out); + + // Container part + params_out.container_name = params_in.container_name; + params_out.mode = params_in.mode; + params_out.workingdir = params_in.workingdir; + params_out.isMPI = params_in.isMPI; + params_out.parallelLib = params_in.parallelLib; + + // Resource part + params_out.resource_params.hostname = params_in.hostname; + params_out.resource_params.OS = params_in.OS; + params_out.resource_params.mem_mb = params_in.mem_mb; + params_out.resource_params.cpu_clock = params_in.cpu_clock; + params_out.resource_params.nb_node = params_in.nb_node; + params_out.resource_params.nb_proc_per_node = params_in.nb_proc_per_node; + params_out.resource_params.policy = params_in.policy; + params_out.resource_params.componentList = params_in.componentList; + + params_out.resource_params.resList.length(params_in.computerList.length()); + for (CORBA::ULong i = 0; i < params_in.computerList.length(); i++) + params_out.resource_params.resList[i] = params_in.computerList[i]; +} + +//============================================================================= +/*! + * \return a number of processors not 0, only for MPI containers + */ +//============================================================================= + +int SALOME_LifeCycleCORBA::NbProc(const Engines::ContainerParameters& params) +{ + if( !isMpiContainer(params) ) + return 0; + else if( params.nb_proc <= 0 ) + return 1; else - return ret; + return params.nb_proc; } -Engines::Component_ptr SALOME_LifeCycleCORBA::FindComponent(const char *containerName, - const char *componentName, - const Engines::MachineList& listOfMachines) +//============================================================================= +/*! \brief Get the container manager + * + * \return the container Manager + */ +//============================================================================= + +Engines::ContainerManager_ptr SALOME_LifeCycleCORBA::getContainerManager() { - if (! isKnownComponentClass(componentName)) return Engines::Component::_nil(); - if(containerName[0]!='\0') + Engines::ContainerManager_var contManager = + Engines::ContainerManager::_duplicate(_ContManager); + return contManager._retn(); +} + +//============================================================================= +/*! \brief Get the resources manager + * + * \return the container Manager + */ +//============================================================================= + +Engines::ResourcesManager_ptr SALOME_LifeCycleCORBA::getResourcesManager() +{ + Engines::ResourcesManager_var resManager = + Engines::ResourcesManager::_duplicate(_ResManager); + return resManager._retn(); +} + +//============================================================================= +/*! \brief shutdown all the SALOME servers except SALOME_Session_Server, omniNames and notifd + */ +//============================================================================= + +void SALOME_LifeCycleCORBA::shutdownServers() +{ + // get each Container from NamingService => shutdown it + // (the order is inverse to the order of servers initialization) + + SALOME::Session_var session = SALOME::Session::_nil(); + CORBA::Long pid = 0; + CORBA::Object_var objS = _NS->Resolve("/Kernel/Session"); + if (!CORBA::is_nil(objS)) + { + session = SALOME::Session::_narrow(objS); + if (!CORBA::is_nil(session)) { - Engines::MachineList_var machinesOK=new Engines::MachineList; - unsigned int lghtOfmachinesOK=0; - machinesOK->length(listOfMachines.length()); - for(unsigned int i=0;iResolve(componentNameForNS.c_str()); - if(!CORBA::is_nil(obj)) - { - machinesOK[lghtOfmachinesOK++]=CORBA::string_dup(currentMachine); - } - } - if(lghtOfmachinesOK!=0) - { - machinesOK->length(lghtOfmachinesOK); - CORBA::String_var bestMachine=_ContManager->FindBest(machinesOK); - string componentNameForNS=Engines_Component_i::BuildComponentNameForNS(componentName,containerName,bestMachine); - CORBA::Object_var obj=_NS->Resolve(componentNameForNS.c_str()); - return Engines::Component::_narrow(obj); - } - else - return Engines::Component::_nil(); + pid = session->getPID(); } - else + } + + std::string hostname = Kernel_Utils::GetHostname(); + + // 1) ConnectionManager + try + { + CORBA::Object_var objCnM=_NS->Resolve("/ConnectionManager"); + Engines::ConnectionManager_var connMan=Engines::ConnectionManager::_narrow(objCnM); + if ( !CORBA::is_nil(connMan) && ( pid != connMan->getPID() ) ) + connMan->ShutdownWithExit(); + } + catch(const CORBA::Exception& e) + { + // ignore and continue + } + + timespec ts_req; + ts_req.tv_nsec=100000000; + ts_req.tv_sec=0; + +//Wait some time so that ConnectionManager be completely shutdown +#ifndef WIN32 + nanosleep(&ts_req,0); +#endif + + // 2) SALOMEDS + try + { + CORBA::Object_var objSDS = _NS->Resolve("/myStudyManager"); + SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow(objSDS) ; + if ( !CORBA::is_nil(studyManager) && ( pid != studyManager->getPID() ) ) + studyManager->Shutdown(); + } + catch(const CORBA::Exception& e) + { + // ignore and continue + } + +//Wait some time so that study be completely shutdown +#ifndef WIN32 + nanosleep(&ts_req,0); +#endif + + // 3) ModuleCatalog + try + { + CORBA::Object_var objMC=_NS->Resolve("/Kernel/ModulCatalog"); + SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(objMC); + if ( !CORBA::is_nil(catalog) && ( pid != catalog->getPID() ) ) + catalog->shutdown(); + } + catch(const CORBA::Exception& e) + { + // ignore and continue + } + +//Wait some time so that ModulCatalog be completely shutdown +#ifndef WIN32 + nanosleep(&ts_req,0); +#endif + + // 4) SalomeLauncher + try + { + CORBA::Object_var objSL = _NS->Resolve("/SalomeLauncher"); + Engines::SalomeLauncher_var launcher = Engines::SalomeLauncher::_narrow(objSL); + if (!CORBA::is_nil(launcher) && (pid != launcher->getPID())) + launcher->Shutdown(); + } + catch(const CORBA::Exception& e) + { + // ignore and continue + } + +//Wait some time so that launcher be completely shutdown +#ifndef WIN32 + nanosleep(&ts_req,0); +#endif + + // 5) Registry + try + { + CORBA::Object_var objR = _NS->Resolve("/Registry"); + Registry::Components_var registry = Registry::Components::_narrow(objR); + if ( !CORBA::is_nil(registry) && ( pid != registry->getPID() ) ) + registry->Shutdown(); + } + catch(const CORBA::Exception& e) + { + // ignore and continue + } + + // 6) Session + if ( !CORBA::is_nil( session ) ) { + try + { + session->Shutdown(); + } + catch(const CORBA::Exception& e) + { + // ignore and continue + } + } + + // 7) Logger + int argc = 0; + char *xargv = (char*)""; + char **argv = &xargv; + CORBA::ORB_var orb = CORBA::ORB_init(argc, argv); + + CORBA::Object_var objLog = CORBA::Object::_nil(); + CosNaming::NamingContext_var inc; + CORBA::Object_var theObj = CORBA::Object::_nil(); + std::string stdname = "Logger"; + CosNaming::Name name; + name.length(1); + name[0].id = CORBA::string_dup(stdname.c_str()); + try + { + if(!CORBA::is_nil(orb)) + theObj = orb->resolve_initial_references("NameService"); + if (!CORBA::is_nil(theObj)) + inc = CosNaming::NamingContext::_narrow(theObj); + } + catch(...) + { + } + if(!CORBA::is_nil(inc)) + { + try + { + objLog = inc->resolve(name); + SALOME_Logger::Logger_var logger = SALOME_Logger::Logger::_narrow(objLog); + if ( !CORBA::is_nil(logger) ) + logger->shutdown(); + } + catch(...) { - //user specified no container name so trying to find a component in the best machine among listOfMachines - CORBA::String_var bestMachine=_ContManager->FindBest(listOfMachines); - //Normally look at all containers launched on bestMachine to see if componentName is already launched on one of them. To do.. - string componentNameForNS=Engines_Component_i::BuildComponentNameForNS(componentName,containerName,bestMachine); - CORBA::Object_var obj = _NS->Resolve(componentNameForNS.c_str()); - return Engines::Component::_narrow(obj); } + } } -Engines::Component_ptr SALOME_LifeCycleCORBA::LoadComponent(const char *containerName, const char *componentName, const Engines::MachineList& listOfMachines) +//============================================================================= +/*! \brief shutdown omniNames and notifd + */ +//============================================================================= + +void SALOME_LifeCycleCORBA::killOmniNames() { - Engines::Container_var cont=_ContManager->FindOrStartContainer(containerName,listOfMachines); - string implementation=Engines_Component_i::GetDynLibraryName(componentName); - return cont->load_impl(componentName, implementation.c_str()); + std::string portNumber (::getenv ("NSPORT") ); + if ( !portNumber.empty() ) + { +#ifdef WNT +#else + std::string cmd ; + cmd = std::string( "ps -eo pid,command | grep -v grep | grep -E \"omniNames.*") + + portNumber + + std::string("\" | awk '{cmd=sprintf(\"kill -9 %s\",$1); system(cmd)}'" ); + MESSAGE(cmd); + try { + system ( cmd.c_str() ); + } + catch ( ... ) { + } +#endif + } + + // NPAL 18309 (Kill Notifd) + if ( !portNumber.empty() ) + { + std::string cmd = ("from killSalomeWithPort import killNotifdAndClean; "); + cmd += std::string("killNotifdAndClean(") + portNumber + "); "; + cmd = std::string("python -c \"") + cmd +"\" > /dev/null 2> /dev/null"; + MESSAGE(cmd); + system( cmd.c_str() ); + } } +//============================================================================= +/*! \brief Find an already existing and registered component instance. + * + * - build a list of machines on which an instance of the component is running, + * - find the best machine among the list + * + * \param params machine parameters like type or name... + * \param componentName the name of component class + * \param studyId default = 0 : multistudy instance + * \param listOfMachines list of machine address + * \return a CORBA reference of the component instance, or _nil if not found + */ +//============================================================================= -Engines::Container_ptr SALOME_LifeCycleCORBA::FindOrStartContainer( - const string aComputerContainer , - const string theComputer , - const string theContainer ) { - SCRUTE( aComputerContainer ) ; - SCRUTE( theComputer ) ; - SCRUTE( theContainer ) ; - - Engines::Container_var aContainer = FindContainer( aComputerContainer.c_str() ) ; +Engines::EngineComponent_ptr +SALOME_LifeCycleCORBA:: +_FindComponent(const Engines::ContainerParameters& params, + const char *componentName, + int studyId, + const Engines::ResourceList& listOfResources) +{ + // --- build the list of machines on which the component is already running + const char *containerName = params.container_name; + int nbproc = NbProc(params); - if ( !CORBA::is_nil( aContainer ) ) { - return aContainer ; - } + Engines::ResourceList_var resourcesOK = new Engines::ResourceList; - Engines::Container_var aFactoryServer ; + unsigned int lghtOfresourcesOK = 0; + resourcesOK->length(listOfResources.length()); - bool pyCont = false ; - int len = theContainer.length() ; - if ( !strcmp( &theContainer.c_str()[len-2] , "Py" ) ) { - pyCont = true ; + for(unsigned int i=0; i < listOfResources.length(); i++) + { + const char * currentResource = listOfResources[i]; + CORBA::Object_var obj = _NS->ResolveComponent(currentResource, + containerName, + componentName, + nbproc); + if (!CORBA::is_nil(obj)) + resourcesOK[lghtOfresourcesOK++] = CORBA::string_dup(currentResource); } - string addr=_NS->getIORaddr(); - string CMD="SALOME_Container"; - if ( pyCont ) { - CMD="SALOME_ContainerPy.py"; + // --- find the best machine among the list + if(lghtOfresourcesOK != 0) + { + resourcesOK->length(lghtOfresourcesOK); + CORBA::String_var bestResource = _ResManager->FindFirst(resourcesOK); + CORBA::Object_var obj = _NS->ResolveComponent(bestResource, + containerName, + componentName, + nbproc); + return Engines::EngineComponent::_narrow(obj); } - CMD=CMD + " " + theContainer; - CMD=CMD + " -ORBInitRef NameService="+addr; - - /* - * Get the appropriate launcher and ask to launch - */ - PyObject * launcher=getLauncher((char *)theComputer.c_str()); - Launcher_Slaunch(launcher,(char *)theComputer.c_str(),(char *)CMD.c_str()); - /* - * Wait until the container is registered in Naming Service - */ - int count = 5 ; - while ( CORBA::is_nil( aFactoryServer ) && count ) { - sleep( 1 ) ; - count-- ; - if ( count != 10 ) - MESSAGE( count << ". Waiting for FactoryServer on " << theComputer) - aFactoryServer = FindContainer( aComputerContainer.c_str() ) ; + else + return Engines::EngineComponent::_nil(); +} + +//============================================================================= +/*! \brief Load a component instance. + * + * - Finds a container in the list of machine or start one. + * - Try to load the component library in the container, + * - then create an instance of the component. + * + * \param params machine parameters like type or name... + * \param componentName the name of component class + * \param studyId default = 0 : multistudy instance + * \return a CORBA reference of the component instance, or _nil if problem + */ +//============================================================================= + +Engines::EngineComponent_ptr +SALOME_LifeCycleCORBA:: +_LoadComponent(const Engines::ContainerParameters& params, + const char *componentName, + int studyId) +{ + MESSAGE("_LoadComponent, required " << params.container_name << + " " << componentName << " " << NbProc(params)); + + Engines::ContainerParameters local_params(params); + local_params.mode = CORBA::string_dup("findorstart"); + Engines::Container_var cont = _ContManager->GiveContainer(local_params); + if (CORBA::is_nil(cont)) return Engines::EngineComponent::_nil(); + + char* reason; + bool isLoadable = cont->load_component_Library(componentName,reason); + if (!isLoadable) + { + //std::cerr << reason << std::endl; + CORBA::string_free(reason); + return Engines::EngineComponent::_nil(); + } + CORBA::string_free(reason); + + Engines::EngineComponent_var myInstance = + cont->create_component_instance(componentName, studyId); + return myInstance._retn(); +} + +//============================================================================= +/*! \brief Load a parallel component instance. + * + * \param params machine parameters like type or name... + * \param componentName the name of component class + * \param studyId default = 0 : multistudy instance + * \return a CORBA reference of the parallel component instance, or _nil if problem + */ +//============================================================================= +Engines::EngineComponent_ptr +SALOME_LifeCycleCORBA::Load_ParallelComponent(const Engines::ContainerParameters& params, + const char *componentName, + int studyId) +{ + MESSAGE("Entering LoadParallelComponent"); + +/*MESSAGE("Parameters : "); + MESSAGE("Container name : " << params.container_name); + MESSAGE("Number of component nodes : " << params.nb_component_nodes); + MESSAGE("Component Name : " << componentName);*/ + + Engines::ContainerParameters parms(params); + parms.resource_params.componentList.length(1); + parms.resource_params.componentList[0] = componentName; + parms.mode = CORBA::string_dup("findorstart"); + + MESSAGE("Starting Parallel Container"); + Engines::Container_var cont = _ContManager->GiveContainer(parms); + if (CORBA::is_nil(cont)) { + INFOS("FindOrStartParallelContainer() returns a NULL container !"); + return Engines::EngineComponent::_nil(); } - if ( !CORBA::is_nil( aFactoryServer ) ) { - return aFactoryServer; + + MESSAGE("Loading component library"); + char* reason; + bool isLoadable = cont->load_component_Library(componentName,reason); + if (!isLoadable) { + INFOS(componentName <<" library is not loadable !"); + //std::cerr << reason << std::endl; + CORBA::string_free(reason); + return Engines::EngineComponent::_nil(); } - MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed") ; - return Engines::Container::_nil(); + CORBA::string_free(reason); + + MESSAGE("Creating component instance"); + // @PARALLEL@ permits to identify that the component requested + // is a parallel component. + std::string name = std::string(componentName); + Engines::EngineComponent_var myInstance = cont->create_component_instance(name.c_str(), studyId); + if (CORBA::is_nil(myInstance)) + INFOS("create_component_instance returns a NULL component !"); + return myInstance._retn(); +} + +/*! \brief copy a file from a source host to a destination host + * \param hostSrc the source host + * \param fileSrc the file to copy from the source host to the destination host + * \param hostDest the destination host + * \param fileDest the destination file + */ +void SALOME_LifeCycleCORBA::copyFile(const char* hostSrc, const char* fileSrc, const char* hostDest, const char* fileDest) +{ + if(strcmp(hostDest,"localhost") == 0) + { + //if localhost use a shortcut + SALOME_FileTransferCORBA transfer(hostSrc,fileSrc); + transfer.getLocalFile(fileDest); + return; + } + + Engines::ContainerManager_var contManager = getContainerManager(); + + Engines::ContainerParameters params; + preSet(params); + + params.resource_params.hostname = hostDest; + params.mode = CORBA::string_dup("findorstart"); + Engines::Container_var containerDest = contManager->GiveContainer(params); + + params.resource_params.hostname = hostSrc; + Engines::Container_var containerSrc = contManager->GiveContainer(params); + + containerDest->copyFile(containerSrc,fileSrc,fileDest); +} + +/*! \brief get the naming service used by the life cycle + * + * \return the naming service + */ +SALOME_NamingService * SALOME_LifeCycleCORBA::namingService() +{ + return _NS; +} + +/*! \brief get the orb used by the life cycle + * + * \return the orb + */ +CORBA::ORB_ptr SALOME_LifeCycleCORBA::orb() +{ + return _NS->orb(); }