1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "SALOME_ResourcesManager.hxx"
21 #include "Utils_ExceptHandlers.hxx"
22 #include "Utils_CorbaException.hxx"
39 #include <sys/types.h>
41 #include "utilities.h"
43 #define MAX_SIZE_FOR_HOSTNAME 256;
47 const char *SALOME_ResourcesManager::_ResourcesManagerNameInNS = "/ResourcesManager";
49 //=============================================================================
53 //=============================================================================
55 SALOME_ResourcesManager::
56 SALOME_ResourcesManager(CORBA::ORB_ptr orb,
57 PortableServer::POA_var poa,
58 SALOME_NamingService *ns,
59 const char *xmlFilePath) :
60 _path_resources(xmlFilePath)
62 MESSAGE("constructor");
64 _orb = CORBA::ORB::_duplicate(orb) ;
65 _poa = PortableServer::POA::_duplicate(poa) ;
66 PortableServer::ObjectId_var id = _poa->activate_object(this);
67 CORBA::Object_var obj = _poa->id_to_reference(id);
68 Engines::SalomeLauncher_var refContMan =
69 Engines::SalomeLauncher::_narrow(obj);
71 _NS->Register(refContMan,_ResourcesManagerNameInNS);
73 MESSAGE("constructor end");
76 //=============================================================================
78 * Standard constructor, parse resource file.
79 * - if ${APPLI} exists in environment,
80 * look for ${HOME}/${APPLI}/CatalogResources.xml
81 * - else look for default:
82 * ${KERNEL_ROOT_DIR}/share/salome/resources/kernel/CatalogResources.xml
83 * - parse XML resource file.
85 //=============================================================================
87 SALOME_ResourcesManager::SALOME_ResourcesManager(CORBA::ORB_ptr orb,
88 PortableServer::POA_var poa,
89 SALOME_NamingService *ns)
91 MESSAGE("constructor");
93 _orb = CORBA::ORB::_duplicate(orb) ;
94 _poa = PortableServer::POA::_duplicate(poa) ;
95 PortableServer::ObjectId_var id = _poa->activate_object(this);
96 CORBA::Object_var obj = _poa->id_to_reference(id);
97 Engines::ResourcesManager_var refContMan = Engines::ResourcesManager::_narrow(obj);
98 _NS->Register(refContMan,_ResourcesManagerNameInNS);
100 _isAppliSalomeDefined = (getenv("APPLI") != 0);
103 if (_isAppliSalomeDefined)
105 _path_resources = getenv("HOME");
106 _path_resources += "/";
107 _path_resources += getenv("APPLI");
108 _path_resources += "/CatalogResources.xml";
113 _path_resources = getenv("KERNEL_ROOT_DIR");
114 _path_resources += "/share/salome/resources/kernel/CatalogResources.xml";
118 MESSAGE("constructor end");
121 //=============================================================================
123 * Standard Destructor
125 //=============================================================================
127 SALOME_ResourcesManager::~SALOME_ResourcesManager()
129 MESSAGE("destructor");
133 //=============================================================================
135 * shutdown all the containers, then the ContainerManager servant
137 //=============================================================================
139 void SALOME_ResourcesManager::Shutdown()
142 _NS->Destroy_Name(_ResourcesManagerNameInNS);
143 PortableServer::ObjectId_var oid = _poa->servant_to_id(this);
144 _poa->deactivate_object(oid);
148 //=============================================================================
150 * get the list of name of ressources fitting for the specified module.
151 * If hostname specified, check it is local or known in resources catalog.
154 * - select first machines with corresponding OS (all machines if
155 * parameter OS empty),
156 * - then select the sublist of machines on witch the module is known
157 * (if the result is empty, that probably means that the inventory of
158 * modules is probably not done, so give complete list from previous step)
160 //=============================================================================
162 Engines::MachineList *
163 SALOME_ResourcesManager::GetFittingResources(const Engines::MachineParameters& params,
164 const Engines::CompoList& componentList)
165 //throw(SALOME_Exception)
167 // MESSAGE("ResourcesManager::GetFittingResources");
168 vector <std::string> vec;
169 Engines::MachineList *ret=new Engines::MachineList;
172 // --- To be sure that we search in a correct list.
175 const char *hostname = (const char *)params.hostname;
176 MESSAGE("GetFittingResources " << hostname << " " << GetHostname().c_str());
178 if (hostname[0] != '\0')
180 // MESSAGE("ResourcesManager::GetFittingResources : hostname specified" );
182 if ( strcmp(hostname, "localhost") == 0 ||
183 strcmp(hostname, GetHostname().c_str()) == 0 )
185 // MESSAGE("ResourcesManager::GetFittingResources : localhost" );
186 vec.push_back(GetHostname().c_str());
187 // MESSAGE("ResourcesManager::GetFittingResources : " << vec.size());
190 else if (_resourcesList.find(hostname) != _resourcesList.end())
192 // --- params.hostname is in the list of resources so return it.
193 vec.push_back(hostname);
198 // Cas d'un cluster: nombre de noeuds > 1
200 for (map<string, ParserResourcesType>::const_iterator iter = _resourcesList.begin(); iter != _resourcesList.end(); iter++){
201 if( (*iter).second.DataForSort._nbOfNodes > 1 ){
202 if( strncmp(hostname,(*iter).first.c_str(),strlen(hostname)) == 0 ){
203 vec.push_back((*iter).first.c_str());
204 //cout << "SALOME_ResourcesManager::GetFittingResources vector["
205 // << cpt << "] = " << (*iter).first.c_str() << endl ;
211 // --- user specified an unknown hostame so notify him.
212 MESSAGE("ResourcesManager::GetFittingResources : SALOME_Exception");
213 throw SALOME_Exception("unknown host");
219 // --- Search for available resources sorted by priority
221 SelectOnlyResourcesWithOS(vec, params.OS);
223 KeepOnlyResourcesWithModule(vec, componentList);
226 SelectOnlyResourcesWithOS(vec, params.OS);
228 // --- set wanted parameters
229 ResourceDataToSort::_nbOfNodesWanted = params.nb_node;
231 ResourceDataToSort::_nbOfProcPerNodeWanted = params.nb_proc_per_node;
233 ResourceDataToSort::_CPUFreqMHzWanted = params.cpu_clock;
235 ResourceDataToSort::_memInMBWanted = params.mem_mb;
239 list<ResourceDataToSort> li;
241 for (vector<string>::iterator iter = vec.begin();
244 li.push_back(_resourcesList[(*iter)].DataForSort);
250 for (list<ResourceDataToSort>::iterator iter2 = li.begin();
253 vec[i++] = (*iter2)._hostName;
256 // MESSAGE("ResourcesManager::GetFittingResources : return" << ret.size());
257 ret->length(vec.size());
258 for(unsigned int i=0;i<vec.size();i++)
259 (*ret)[i]=(vec[i]).c_str();
262 catch(const SALOME_Exception &ex)
264 INFOS("Caught exception.");
265 THROW_SALOME_CORBA_EXCEPTION(ex.what(),SALOME::BAD_PARAM);
272 //=============================================================================
274 * add an entry in the ressources catalog xml file.
275 * Return 0 if OK (KERNEL found in new resources modules) else throw exception
277 //=============================================================================
280 SALOME_ResourcesManager::
281 AddResourceInCatalog(const Engines::MachineParameters& paramsOfNewResources,
282 const vector<string>& modulesOnNewResources,
284 const char *userName,
286 AccessProtocolType prot)
287 throw(SALOME_Exception)
289 vector<string>::const_iterator iter = find(modulesOnNewResources.begin(),
290 modulesOnNewResources.end(),
293 if (iter != modulesOnNewResources.end())
295 ParserResourcesType newElt;
296 newElt.DataForSort._hostName = paramsOfNewResources.hostname;
297 newElt.Alias = alias;
298 newElt.Protocol = prot;
300 newElt.UserName = userName;
301 newElt.ModulesList = modulesOnNewResources;
302 newElt.OS = paramsOfNewResources.OS;
303 newElt.DataForSort._memInMB = paramsOfNewResources.mem_mb;
304 newElt.DataForSort._CPUFreqMHz = paramsOfNewResources.cpu_clock;
305 newElt.DataForSort._nbOfNodes = paramsOfNewResources.nb_node;
306 newElt.DataForSort._nbOfProcPerNode =
307 paramsOfNewResources.nb_proc_per_node;
308 _resourcesList[newElt.DataForSort._hostName] = newElt;
313 throw SALOME_Exception("KERNEL is not present in this resource");
316 //=============================================================================
318 * Deletes a resource from the catalog
320 //=============================================================================
322 void SALOME_ResourcesManager::DeleteResourceInCatalog(const char *hostname)
324 _resourcesList.erase(hostname);
327 //=============================================================================
329 * write the current data in memory in file.
331 //=============================================================================
333 void SALOME_ResourcesManager::WriteInXmlFile()
335 const char* aFilePath = _path_resources.c_str();
337 FILE* aFile = fopen(aFilePath, "w");
341 INFOS("Error opening file !");
345 xmlDocPtr aDoc = xmlNewDoc(BAD_CAST "1.0");
346 xmlNewDocComment(aDoc, BAD_CAST "ResourcesCatalog");
348 SALOME_ResourcesCatalog_Handler* handler =
349 new SALOME_ResourcesCatalog_Handler(_resourcesList);
350 handler->PrepareDocToXmlFile(aDoc);
353 int isOk = xmlSaveFile(aFilePath, aDoc);
356 INFOS("Error while XML file saving.");
363 MESSAGE("WRITING DONE!");
366 //=============================================================================
368 * parse the data type catalog
370 //=============================================================================
372 const MapOfParserResourcesType& SALOME_ResourcesManager::ParseXmlFile()
374 SALOME_ResourcesCatalog_Handler* handler =
375 new SALOME_ResourcesCatalog_Handler(_resourcesList);
377 const char* aFilePath = _path_resources.c_str();
378 FILE* aFile = fopen(aFilePath, "r");
382 xmlDocPtr aDoc = xmlReadFile(aFilePath, NULL, 0);
385 handler->ProcessXmlDocument(aDoc);
387 INFOS("ResourcesManager: could not parse file "<<aFilePath);
395 INFOS("ResourcesManager: file "<<aFilePath<<" is not readable.");
399 return _resourcesList;
402 //=============================================================================
404 * consult the content of the list
406 //=============================================================================
408 const MapOfParserResourcesType& SALOME_ResourcesManager::GetList() const
410 return _resourcesList;
414 //=============================================================================
416 * dynamically obtains the first machines
418 //=============================================================================
421 SALOME_ResourcesManager::FindFirst(const Engines::MachineList& listOfMachines)
423 return CORBA::string_dup(_dynamicResourcesSelecter.FindFirst(listOfMachines).c_str());
426 //=============================================================================
428 * dynamically obtains the best machines
430 //=============================================================================
433 SALOME_ResourcesManager::FindNext(const Engines::MachineList& listOfMachines)
435 return _dynamicResourcesSelecter.FindNext(listOfMachines,_resourcesList,_NS);
437 //=============================================================================
439 * dynamically obtains the best machines
441 //=============================================================================
444 SALOME_ResourcesManager::FindBest(const Engines::MachineList& listOfMachines)
446 return _dynamicResourcesSelecter.FindBest(listOfMachines);
449 //=============================================================================
451 * This is no longer valid (C++ container are also python containers)
453 //=============================================================================
455 bool isPythonContainer(const char* ContainerName)
458 int len = strlen(ContainerName);
461 if (strcmp(ContainerName + len - 2, "Py") == 0)
468 //=============================================================================
470 * Builds the script to be launched
472 * If SALOME Application not defined ($APPLI),
473 * see BuildTempFileToLaunchRemoteContainer()
475 * Else rely on distant configuration. Command is under the form (example):
476 * ssh user@machine distantPath/runRemote.sh hostNS portNS workingdir \
477 * SALOME_Container containerName &"
479 * - where user is ommited if not specified in CatalogResources,
480 * - where distant path is always relative to user@machine $HOME, and
481 * equal to $APPLI if not specified in CatalogResources,
482 * - where hostNS is the hostname of CORBA naming server (set by scripts to
483 * use to launch SALOME and servers in $APPLI: runAppli.sh, runRemote.sh)
484 * - where portNS is the port used by CORBA naming server (set by scripts to
485 * use to launch SALOME and servers in $APPLI: runAppli.sh, runRemote.sh)
486 * - where workingdir is the requested working directory for the container
488 //=============================================================================
491 SALOME_ResourcesManager::BuildCommandToLaunchRemoteContainer
492 (const string& machine,
493 const Engines::MachineParameters& params, const long id)
497 char idc[3*sizeof(long)];
499 if ( ! _isAppliSalomeDefined )
500 command = BuildTempFileToLaunchRemoteContainer(machine, params);
504 const ParserResourcesType& resInfo = _resourcesList[machine];
508 if ( (params.nb_node <= 0) && (params.nb_proc_per_node <= 0) )
510 else if ( params.nb_node == 0 )
511 nbproc = params.nb_proc_per_node;
512 else if ( params.nb_proc_per_node == 0 )
513 nbproc = params.nb_node;
515 nbproc = params.nb_node * params.nb_proc_per_node;
518 // "ssh user@machine distantPath/runRemote.sh hostNS portNS workingdir \
519 // SALOME_Container containerName &"
521 if (resInfo.Protocol == rsh)
523 else if (resInfo.Protocol == ssh)
526 throw SALOME_Exception("Unknown protocol");
528 if (resInfo.UserName != "")
530 command += resInfo.UserName;
537 if (resInfo.AppliPath != "")
538 command += resInfo.AppliPath; // path relative to user@machine $HOME
541 ASSERT(getenv("APPLI"));
542 command += getenv("APPLI"); // path relative to user@machine $HOME
545 command += "/runRemote.sh ";
547 ASSERT(getenv("NSHOST"));
548 command += getenv("NSHOST"); // hostname of CORBA name server
551 ASSERT(getenv("NSPORT"));
552 command += getenv("NSPORT"); // port of CORBA name server
555 std::string wdir=params.workingdir.in();
556 if(wdir == "$TEMPDIR")
558 command += wdir; // requested working directory
563 command += " mpirun -np ";
564 std::ostringstream o;
568 command += "-x PATH,LD_LIBRARY_PATH,OMNIORB_CONFIG,SALOME_trace ";
570 command += " SALOME_MPIContainer ";
573 command += " SALOME_Container ";
575 command += _NS->ContainerName(params);
577 sprintf(idc,"%ld",id);
580 AddOmninamesParams(command);
582 MESSAGE("command =" << command);
588 //=============================================================================
590 * builds the command to be launched.
592 //=============================================================================
595 SALOME_ResourcesManager::BuildCommandToLaunchLocalContainer
596 (const Engines::MachineParameters& params, const long id)
601 char idc[3*sizeof(long)];
605 command = "mpirun -np ";
607 if ( (params.nb_node <= 0) && (params.nb_proc_per_node <= 0) )
609 else if ( params.nb_node == 0 )
610 nbproc = params.nb_proc_per_node;
611 else if ( params.nb_proc_per_node == 0 )
612 nbproc = params.nb_node;
614 nbproc = params.nb_node * params.nb_proc_per_node;
616 std::ostringstream o;
622 command += "-x PATH,LD_LIBRARY_PATH,OMNIORB_CONFIG,SALOME_trace ";
625 if (isPythonContainer(params.container_name))
626 command += "pyMPI SALOME_ContainerPy.py ";
628 command += "SALOME_MPIContainer ";
634 std::string wdir=params.workingdir.in();
635 std::cerr << wdir << std::endl;
638 // a working directory is requested
639 if(wdir == "$TEMPDIR")
641 // a new temporary directory is requested
642 char dir[]="/tmp/salomeXXXXXX";
643 char* mdir=mkdtemp(dir);
645 std::cerr << "Problem in mkdtemp " << dir << " " << mdir << std::endl;
647 command="cd "+std::string(dir)+";";
651 // a permanent directory is requested use it or create it
652 command="mkdir -p " + wdir + " && cd " + wdir + ";";
655 if (isPythonContainer(params.container_name))
656 command += "SALOME_ContainerPy.py ";
658 command += "SALOME_Container ";
661 command += _NS->ContainerName(params);
663 sprintf(idc,"%ld",id);
666 AddOmninamesParams(command);
668 MESSAGE("Command is ... " << command);
673 //=============================================================================
675 * removes the generated temporary file in case of a remote launch.
677 //=============================================================================
679 void SALOME_ResourcesManager::RmTmpFile()
681 if (_TmpFileName != "")
684 string command = "rm ";
686 string command = "del /F ";
688 command += _TmpFileName;
689 char *temp = strdup(command.c_str());
690 int lgthTemp = strlen(temp);
691 temp[lgthTemp - 3] = '*';
692 temp[lgthTemp - 2] = '\0';
699 //=============================================================================
701 * builds the script to be launched
703 //=============================================================================
706 SALOME_ResourcesManager::BuildCommand
707 (const string& machine,
708 const char *containerName)
710 // rsh -n ikkyo /export/home/rahuel/SALOME_ROOT/bin/runSession SALOME_Container -ORBInitRef NameService=corbaname::dm2s0017:1515 &
711 const ParserResourcesType& resInfo = _resourcesList[machine];
712 bool pyCont = isPythonContainer(containerName);
716 if (resInfo.Protocol == rsh)
717 command = "rsh -n " ;
718 else if (resInfo.Protocol == ssh)
719 command = "ssh -f -n ";
721 throw SALOME_Exception("Not implemented yet...");
725 string path = getenv("KERNEL_ROOT_DIR");
727 command += "/bin/salome/";
730 command += "SALOME_ContainerPy.py ";
732 command += "SALOME_Container ";
734 command += containerName;
736 AddOmninamesParams(command);
742 //=============================================================================
744 * Gives a sublist of machines with matching OS.
745 * If parameter OS is empty, gives the complete list of machines
747 //=============================================================================
749 // Warning need an updated parsed list : _resourcesList
751 SALOME_ResourcesManager::SelectOnlyResourcesWithOS
752 ( vector<string>& hosts,
753 const char *OS) const
754 throw(SALOME_Exception)
758 for (map<string, ParserResourcesType>::const_iterator iter =
759 _resourcesList.begin();
760 iter != _resourcesList.end();
763 if ( (*iter).second.OS == base || base.size() == 0)
764 hosts.push_back((*iter).first);
769 //=============================================================================
771 * Gives a sublist of machines on which the module is known.
773 //=============================================================================
775 //Warning need an updated parsed list : _resourcesList
777 SALOME_ResourcesManager::KeepOnlyResourcesWithModule
778 ( vector<string>& hosts,
779 const Engines::CompoList& componentList) const
780 throw(SALOME_Exception)
782 for (vector<string>::iterator iter = hosts.begin(); iter != hosts.end();)
784 MapOfParserResourcesType::const_iterator it = _resourcesList.find(*iter);
785 const vector<string>& mapOfModulesOfCurrentHost = (((*it).second).ModulesList);
787 bool erasedHost = false;
788 if( mapOfModulesOfCurrentHost.size() > 0 ){
789 for(int i=0;i<componentList.length();i++){
790 const char* compoi = componentList[i];
791 vector<string>::const_iterator itt = find(mapOfModulesOfCurrentHost.begin(),
792 mapOfModulesOfCurrentHost.end(),
794 // componentList[i]);
795 if (itt == mapOfModulesOfCurrentHost.end()){
809 //=============================================================================
811 * add to command all options relative to naming service.
813 //=============================================================================
815 void SALOME_ResourcesManager::AddOmninamesParams(string& command) const
817 // If env variable OMNIORB_CONFIG is not defined or the file is more complex than one line
819 // Even if we use it we have to check if env variable exists
820 //string omniORBcfg( getenv( "OMNIORB_CONFIG" ) ) ;
821 //ifstream omniORBfile( omniORBcfg.c_str() ) ;
822 //char ORBInitRef[11] ;
824 //char nameservice[132] ;
825 //omniORBfile >> ORBInitRef ;
826 //command += "ORBInitRef " ;
827 //omniORBfile >> egal ;
828 //omniORBfile >> nameservice ;
829 //omniORBfile.close() ;
830 //char * bsn = strchr( nameservice , '\n' ) ;
834 //command += nameservice ;
836 CORBA::String_var iorstr = _NS->getIORaddr();
837 command += "ORBInitRef NameService=";
842 //=============================================================================
844 * add to command all options relative to naming service.
846 //=============================================================================
848 void SALOME_ResourcesManager::AddOmninamesParams(ofstream& fileStream) const
850 CORBA::String_var iorstr = _NS->getIORaddr();
851 fileStream << "ORBInitRef NameService=";
852 fileStream << iorstr;
856 //=============================================================================
858 * generate a file name in /tmp directory
860 //=============================================================================
862 string SALOME_ResourcesManager::BuildTemporaryFileName() const
864 //build more complex file name to support multiple salome session
865 char *temp = new char[19];
866 strcpy(temp, "/tmp/command");
867 strcat(temp, "XXXXXX");
874 itoa(getpid(), aPID, 10);
878 string command(temp);
885 //=============================================================================
887 * Builds in a temporary file the script to be launched.
889 * Used if SALOME Application ($APPLI) is not defined.
890 * The command is build with data from CatalogResources, in which every path
891 * used on remote computer must be defined.
893 //=============================================================================
896 SALOME_ResourcesManager::BuildTempFileToLaunchRemoteContainer
897 (const string& machine,
898 const Engines::MachineParameters& params) throw(SALOME_Exception)
902 _TmpFileName = BuildTemporaryFileName();
903 ofstream tempOutputFile;
904 tempOutputFile.open(_TmpFileName.c_str(), ofstream::out );
905 const ParserResourcesType& resInfo = _resourcesList[machine];
906 tempOutputFile << "#! /bin/sh" << endl;
910 tempOutputFile << "export SALOME_trace=local" << endl; // mkr : 27.11.2006 : PAL13967 - Distributed supervision graphs - Problem with "SALOME_trace"
911 //tempOutputFile << "source " << resInfo.PreReqFilePath << endl;
917 tempOutputFile << "mpirun -np ";
920 if ( (params.nb_node <= 0) && (params.nb_proc_per_node <= 0) )
922 else if ( params.nb_node == 0 )
923 nbproc = params.nb_proc_per_node;
924 else if ( params.nb_proc_per_node == 0 )
925 nbproc = params.nb_node;
927 nbproc = params.nb_node * params.nb_proc_per_node;
929 std::ostringstream o;
931 tempOutputFile << nbproc << " ";
933 tempOutputFile << "-x PATH,LD_LIBRARY_PATH,OMNIORB_CONFIG,SALOME_trace ";
937 tempOutputFile << getenv("KERNEL_ROOT_DIR") << "/bin/salome/";
941 if (isPythonContainer(params.container_name))
942 tempOutputFile << "pyMPI SALOME_ContainerPy.py ";
944 tempOutputFile << "SALOME_MPIContainer ";
949 if (isPythonContainer(params.container_name))
950 tempOutputFile << "SALOME_ContainerPy.py ";
952 tempOutputFile << "SALOME_Container ";
955 tempOutputFile << _NS->ContainerName(params) << " -";
956 AddOmninamesParams(tempOutputFile);
957 tempOutputFile << " &" << endl;
958 tempOutputFile.flush();
959 tempOutputFile.close();
960 chmod(_TmpFileName.c_str(), 0x1ED);
966 if (resInfo.Protocol == rsh)
969 string commandRcp = "rcp ";
970 commandRcp += _TmpFileName;
972 commandRcp += machine;
974 commandRcp += _TmpFileName;
975 status = system(commandRcp.c_str());
978 else if (resInfo.Protocol == ssh)
981 string commandRcp = "scp ";
982 commandRcp += _TmpFileName;
984 commandRcp += machine;
986 commandRcp += _TmpFileName;
987 status = system(commandRcp.c_str());
990 throw SALOME_Exception("Unknown protocol");
993 throw SALOME_Exception("Error of connection on remote host");
996 _CommandForRemAccess = command;
998 command += _TmpFileName;
1006 //=============================================================================
1007 /*! Creates a command line that the container manager uses to launch
1008 * a parallel container.
1010 //=============================================================================
1012 SALOME_ResourcesManager::BuildCommandToLaunchLocalParallelContainer(const std::string& exe_name,
1013 const Engines::MachineParameters& params,
1014 const std::string& log)
1016 // This method knows the differences between the proxy and the nodes.
1017 // nb_component_nodes is not used in the same way if it is a proxy or
1021 string parallelLib(CORBA::string_dup(params.parallelLib));
1022 string hostname(CORBA::string_dup(params.hostname));
1023 int par = exe_name.find("Proxy");
1024 int nbproc = params.nb_component_nodes;
1026 sprintf(buffer,"%d",nbproc);
1028 Engines::MachineParameters_var rtn = new Engines::MachineParameters();
1029 rtn->container_name = params.container_name;
1030 rtn->hostname = params.hostname;
1031 rtn->OS = params.OS;
1032 rtn->mem_mb = params.mem_mb;
1033 rtn->cpu_clock = params.cpu_clock;
1034 rtn->nb_proc_per_node = params.nb_proc_per_node;
1035 rtn->nb_node = params.nb_node;
1036 rtn->isMPI = params.isMPI;
1038 string real_exe_name = exe_name + parallelLib;
1040 if (parallelLib == "Dummy")
1042 //command = "gdb --args ";
1043 //command = "valgrind --tool=memcheck --log-file=val_log ";
1044 //command += real_exe_name;
1046 command = real_exe_name;
1048 command += " " + _NS->ContainerName(rtn);
1049 command += " " + parallelLib;
1050 command += " " + hostname;
1052 AddOmninamesParams(command);
1055 else if (parallelLib == "Mpi")
1057 // Step 1 : check if MPI is started
1058 if (_MpiStarted == false)
1067 command = "mpiexec -np " + string(buffer) + " ";
1068 // command += "gdb --args ";
1069 command += real_exe_name;
1070 command += " " + _NS->ContainerName(rtn);
1071 command += " " + parallelLib;
1072 command += " " + hostname;
1074 AddOmninamesParams(command);
1079 command = "mpiexec -np 1 ";
1080 command += real_exe_name;
1081 command += " " + _NS->ContainerName(rtn);
1082 command += " " + string(buffer);
1083 command += " " + parallelLib;
1084 command += " " + hostname;
1086 AddOmninamesParams(command);
1091 std::string message("Unknown parallelLib" + parallelLib);
1092 throw SALOME_Exception(message.c_str());
1096 if (log == "default")
1098 command += " > /tmp/";
1099 command += _NS->ContainerName(rtn);
1101 command += GetHostname();
1103 command += getenv( "USER" ) ;
1104 command += ".log 2>&1 &" ;
1108 command = "/usr/X11R6/bin/xterm -e \"export LD_LIBRARY_PATH=$LD_LIBRARY_PATH; export PATH=$PATH; "
1109 + command + " \" &";
1110 // + command + "; echo $LD_LIBRARY_PATH; cat \" &";
1114 /* if (log == "xterm")
1116 command = "/usr/X11R6/bin/xterm -e \"export LD_LIBRARY_PATH=$LD_LIBRARY_PATH; export PATH=$PATH; echo $LD_LIBRARY_PATH; echo $PATH; " + command + "; cat \" &";
1119 /* command = "cd ; rm " + fichier_commande + "; touch " + \
1120 fichier_commande + "; echo \" export LD_LIBRARY_PATH=$LD_LIBRARY_PATH; " + \
1121 command + " >& /tmp/ribes_" + fichier_commande + " & \" > " + fichier_commande + ";";
1122 command += "ssh cn01 sh " + fichier_commande + " &";
1123 cerr << "La commande : " << command << endl;
1127 void SALOME_ResourcesManager::startMPI()
1129 cerr << "----------------------------------------------" << endl;
1130 cerr << "----------------------------------------------" << endl;
1131 cerr << "----------------------------------------------" << endl;
1132 cerr << "-Only Lam on Localhost is currently supported-" << endl;
1133 cerr << "----------------------------------------------" << endl;
1134 cerr << "----------------------------------------------" << endl;
1135 cerr << "----------------------------------------------" << endl;
1137 int status = system("lamboot");
1140 INFOS("lamboot failed : system command status -1");
1142 else if (status == 217)
1144 INFOS("lamboot failed : system command status 217");
1152 Engines::MachineParameters* SALOME_ResourcesManager::GetMachineParameters(const char *hostname)
1154 ParserResourcesType resource = _resourcesList[string(hostname)];
1155 Engines::MachineParameters *p_ptr = new Engines::MachineParameters;
1156 p_ptr->container_name = CORBA::string_dup("");
1157 p_ptr->hostname = CORBA::string_dup("hostname");
1158 p_ptr->alias = CORBA::string_dup(resource.Alias.c_str());
1159 if( resource.Protocol == rsh )
1160 p_ptr->protocol = "rsh";
1161 else if( resource.Protocol == ssh )
1162 p_ptr->protocol = "ssh";
1163 p_ptr->username = CORBA::string_dup(resource.UserName.c_str());
1164 p_ptr->applipath = CORBA::string_dup(resource.AppliPath.c_str());
1165 p_ptr->modList.length(resource.ModulesList.size());
1166 for(int i=0;i<resource.ModulesList.size();i++)
1167 p_ptr->modList[i] = CORBA::string_dup(resource.ModulesList[i].c_str());
1168 p_ptr->OS = CORBA::string_dup(resource.OS.c_str());
1169 p_ptr->mem_mb = resource.DataForSort._memInMB;
1170 p_ptr->cpu_clock = resource.DataForSort._CPUFreqMHz;
1171 p_ptr->nb_proc_per_node = resource.DataForSort._nbOfProcPerNode;
1172 p_ptr->nb_node = resource.DataForSort._nbOfNodes;
1173 if( resource.mpi == indif )
1174 p_ptr->mpiImpl = "indif";
1175 else if( resource.mpi == lam )
1176 p_ptr->mpiImpl = "lam";
1177 else if( resource.mpi == mpich1 )
1178 p_ptr->mpiImpl = "mpich1";
1179 else if( resource.mpi == mpich2 )
1180 p_ptr->mpiImpl = "mpich2";
1181 else if( resource.mpi == openmpi )
1182 p_ptr->mpiImpl = "openmpi";
1183 if( resource.Batch == pbs )
1184 p_ptr->batch = "pbs";
1185 else if( resource.Batch == lsf )
1186 p_ptr->batch = "lsf";
1187 else if( resource.Batch == slurm )
1188 p_ptr->batch = "slurm";