]> SALOME platform Git repositories - modules/kernel.git/blob - src/ResourcesManager/SALOME_ResourcesManager.cxx
Salome HOME
Copyrights update
[modules/kernel.git] / src / ResourcesManager / SALOME_ResourcesManager.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
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.
8 // 
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.
13 //
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
17 //
18 // See http://www.salome-platform.org/
19 //
20 #include "SALOME_ResourcesManager.hxx" 
21 //#include "SALOME_Container_i.hxx"
22 #include "Utils_ExceptHandlers.hxx"
23 #include "OpUtil.hxx"
24
25 #include <qdom.h>
26
27 #include <stdlib.h>
28 #ifndef WNT
29 #include <unistd.h>
30 #else
31 #include <io.h>
32 #include <process.h>
33 #endif
34 #include <fstream>
35 #include <iostream>
36 #include <sstream>
37 #include <string.h>
38 #include <map>
39 #include <list>
40
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include "utilities.h"
44
45 #define MAX_SIZE_FOR_HOSTNAME 256;
46
47 using namespace std;
48
49 //=============================================================================
50 /*!
51  * just for test
52  */ 
53 //=============================================================================
54
55 SALOME_ResourcesManager::
56 SALOME_ResourcesManager(CORBA::ORB_ptr orb,
57                         const char *xmlFilePath) :
58     _path_resources(xmlFilePath)
59 {
60   _NS = new SALOME_NamingService(orb);
61 }
62
63 //=============================================================================
64 /*!
65  *  Standard constructor, parse resource file.
66  *  - if ${APPLI} exists in environment,
67  *    look for ${HOME}/*{APPLI}/CatalogResources.xml
68  *  - else look for default:
69  *    ${KERNEL_ROOT_DIR}/share/salome/resources/CatalogResources.xml
70  *  - parse XML resource file.
71  */ 
72 //=============================================================================
73
74 SALOME_ResourcesManager::SALOME_ResourcesManager(CORBA::ORB_ptr orb)
75 {
76   _NS = new SALOME_NamingService(orb);
77   _isAppliSalomeDefined = (getenv("APPLI") != 0);
78
79   if (_isAppliSalomeDefined)
80     {
81       _path_resources = getenv("HOME");
82       _path_resources += "/";
83       _path_resources += getenv("APPLI");
84       _path_resources += "/CatalogResources.xml";
85     }
86
87   else
88     {
89       _path_resources = getenv("KERNEL_ROOT_DIR");
90       _path_resources += "/share/salome/resources/CatalogResources.xml";
91     }
92
93   ParseXmlFile();
94 }
95
96 //=============================================================================
97 /*!
98  *  Standard Destructor
99  */ 
100 //=============================================================================
101
102 SALOME_ResourcesManager::~SALOME_ResourcesManager()
103 {
104   delete _NS;
105 }
106
107 //=============================================================================
108 /*!
109  *  get the list of name of ressources fitting for the specified module.
110  *  If hostname specified, check it is local or known in resources catalog.
111  *
112  *  Else
113  *  - select first machines with corresponding OS (all machines if
114  *    parameter OS empty),
115  *  - then select the sublist of machines on witch the module is known
116  *    (if the result is empty, that probably means that the inventory of
117  *    modules is probably not done, so give complete list from previous step)
118  */ 
119 //=============================================================================
120
121 vector<string>
122 SALOME_ResourcesManager::
123 GetFittingResources(const Engines::MachineParameters& params,
124                     const char *moduleName)
125 throw(SALOME_Exception)
126 {
127   MESSAGE("ResourcesManager::GetFittingResources");
128   vector <std::string> ret;
129
130   // --- To be sure that we search in a correct list.
131   ParseXmlFile();
132
133   const char *hostname = (const char *)params.hostname;
134   MESSAGE("GetFittingResources " << hostname << " " << GetHostname().c_str());
135
136   if (hostname[0] != '\0')
137     {
138       MESSAGE("ResourcesManager::GetFittingResources : hostname specified" );
139
140       if ( strcmp(hostname, "localhost") == 0 ||
141            strcmp(hostname, GetHostname().c_str()) == 0 )
142         {
143           MESSAGE("ResourcesManager::GetFittingResources : localhost" );
144           ret.push_back(GetHostname().c_str());
145           MESSAGE("ResourcesManager::GetFittingResources : " << ret.size());
146         }
147
148       else if (_resourcesList.find(hostname) != _resourcesList.end())
149         {
150           // --- params.hostname is in the list of resources so return it.
151           ret.push_back(hostname);
152         }
153
154       else
155         {
156           // --- user specified an unknown hostame so notify him.
157           MESSAGE("ResourcesManager::GetFittingResources : SALOME_Exception");
158           throw SALOME_Exception("unknown host");
159         }
160     }
161
162   else
163     // --- Search for available resources sorted by priority
164     {
165       SelectOnlyResourcesWithOS(ret, params.OS);
166
167       KeepOnlyResourcesWithModule(ret, moduleName);
168
169       if (ret.size() == 0)
170         SelectOnlyResourcesWithOS(ret, params.OS);
171
172       // --- set wanted parameters
173       ResourceDataToSort::_nbOfNodesWanted = params.nb_node;
174
175       ResourceDataToSort::_nbOfProcPerNodeWanted = params.nb_proc_per_node;
176
177       ResourceDataToSort::_CPUFreqMHzWanted = params.cpu_clock;
178
179       ResourceDataToSort::_memInMBWanted = params.mem_mb;
180
181       // --- end of set
182
183       list<ResourceDataToSort> li;
184
185       for (vector<string>::iterator iter = ret.begin();
186            iter != ret.end();
187            iter++)
188         li.push_back(_resourcesList[(*iter)].DataForSort);
189
190       li.sort();
191
192       unsigned int i = 0;
193
194       for (list<ResourceDataToSort>::iterator iter2 = li.begin();
195            iter2 != li.end();
196            iter2++)
197         ret[i++] = (*iter2)._hostName;
198     }
199
200   MESSAGE("ResourcesManager::GetFittingResources : return" << ret.size());
201   return ret;
202 }
203
204 //=============================================================================
205 /*!
206  *  add an entry in the ressources catalog  xml file.
207  *  Return 0 if OK (KERNEL found in new resources modules) else throw exception
208  */ 
209 //=============================================================================
210
211 int
212 SALOME_ResourcesManager::
213 AddResourceInCatalog(const Engines::MachineParameters& paramsOfNewResources,
214                      const map<string, string>& modulesOnNewResources,
215                      const char *environPathOfPrerequired,
216                      const char *alias,
217                      const char *userName,
218                      AccessModeType mode,
219                      AccessProtocolType prot)
220 throw(SALOME_Exception)
221 {
222   map<string, string>::const_iterator iter =
223     modulesOnNewResources.find("KERNEL");
224
225   if (iter != modulesOnNewResources.end())
226     {
227       ParserResourcesType newElt;
228       newElt.DataForSort._hostName = paramsOfNewResources.hostname;
229       newElt.Alias = alias;
230       newElt.Protocol = prot;
231       newElt.Mode = mode;
232       newElt.UserName = userName;
233       newElt.ModulesPath = modulesOnNewResources;
234       newElt.PreReqFilePath = environPathOfPrerequired;
235       newElt.OS = paramsOfNewResources.OS;
236       newElt.DataForSort._memInMB = paramsOfNewResources.mem_mb;
237       newElt.DataForSort._CPUFreqMHz = paramsOfNewResources.cpu_clock;
238       newElt.DataForSort._nbOfNodes = paramsOfNewResources.nb_node;
239       newElt.DataForSort._nbOfProcPerNode =
240         paramsOfNewResources.nb_proc_per_node;
241       _resourcesList[newElt.DataForSort._hostName] = newElt;
242       return 0;
243     }
244
245   else
246     throw SALOME_Exception("KERNEL is not present in this resource");
247 }
248
249 //=============================================================================
250 /*!
251  *  Deletes a resource from the catalog
252  */ 
253 //=============================================================================
254
255 void SALOME_ResourcesManager::DeleteResourceInCatalog(const char *hostname)
256 {
257   _resourcesList.erase(hostname);
258 }
259
260 //=============================================================================
261 /*!
262  *  write the current data in memory in file.
263  */ 
264 //=============================================================================
265
266 void SALOME_ResourcesManager::WriteInXmlFile()
267 {
268   QDomDocument doc("ResourcesCatalog");
269   SALOME_ResourcesCatalog_Handler* handler =
270     new SALOME_ResourcesCatalog_Handler(_resourcesList);
271   handler->PrepareDocToXmlFile(doc);
272   delete handler;
273
274   QFile file( _path_resources );
275
276   if ( !file.open( IO_WriteOnly ) )
277     INFOS("WRITING ERROR !");
278
279   QTextStream ts( &file );
280
281   ts << doc.toString();
282
283   file.close();
284
285   MESSAGE("WRITING DONE!");
286 }
287
288 //=============================================================================
289 /*!
290  *  parse the data type catalog
291  */ 
292 //=============================================================================
293
294 const MapOfParserResourcesType& SALOME_ResourcesManager::ParseXmlFile()
295 {
296   SALOME_ResourcesCatalog_Handler* handler =
297     new SALOME_ResourcesCatalog_Handler(_resourcesList);
298   QFile xmlFile(_path_resources);
299
300   QXmlInputSource source(xmlFile);
301
302   QXmlSimpleReader reader;
303   reader.setContentHandler( handler );
304   reader.setErrorHandler( handler );
305   reader.parse( source );
306   xmlFile.close();
307   delete handler;
308   return _resourcesList;
309 }
310
311 //=============================================================================
312 /*!
313  *   consult the content of the list
314  */ 
315 //=============================================================================
316
317 const MapOfParserResourcesType& SALOME_ResourcesManager::GetList() const
318   {
319     return _resourcesList;
320   }
321
322
323 //=============================================================================
324 /*!
325  *  dynamically obtains the best machines
326  */ 
327 //=============================================================================
328
329 string
330 SALOME_ResourcesManager::FindBest(const Engines::MachineList& listOfMachines)
331 {
332   return _dynamicResourcesSelecter.FindBest(listOfMachines);
333 }
334
335
336 //=============================================================================
337 /*!
338  *  This is no longer valid (C++ container are also python containers)
339  */ 
340 //=============================================================================
341
342 bool isPythonContainer(const char* ContainerName)
343 {
344   bool ret = false;
345   int len = strlen(ContainerName);
346
347   if (len >= 2)
348     if (strcmp(ContainerName + len - 2, "Py") == 0)
349       ret = true;
350
351   return ret;
352 }
353
354
355 //=============================================================================
356 /*!
357  *  Builds the script to be launched
358  *
359  *  If SALOME Application not defined ($APPLI),
360  *  see BuildTempFileToLaunchRemoteContainer()
361  *
362  *  Else rely on distant configuration. Command is under the form (example):
363  *  ssh user@machine distantPath/runRemote.sh hostNS portNS \
364  *                   SALOME_Container containerName &"
365
366  *  - where user is ommited if not specified in CatalogResources,
367  *  - where distant path is always relative to user@machine $HOME, and
368  *    equal to $APPLI if not specified in CatalogResources,
369  *  - where hostNS is the hostname of CORBA naming server (set by scripts to
370  *    use to launch SALOME and servers in $APPLI: runAppli.sh, runRemote.sh)
371  *  - where portNS is the port used by CORBA naming server (set by scripts to
372  *    use to launch SALOME and servers in $APPLI: runAppli.sh, runRemote.sh)
373  */ 
374 //=============================================================================
375
376 string
377 SALOME_ResourcesManager::BuildCommandToLaunchRemoteContainer
378 (const string& machine,
379  const Engines::MachineParameters& params, const long id)
380 {
381   string command;
382   int nbproc;
383   char idc[3*sizeof(long)];
384           
385   if ( ! _isAppliSalomeDefined )
386     command = BuildTempFileToLaunchRemoteContainer(machine, params);
387
388   else
389     {
390       const ParserResourcesType& resInfo = _resourcesList[machine];
391
392       if (params.isMPI)
393         {
394           if ( (params.nb_node <= 0) && (params.nb_proc_per_node <= 0) )
395             nbproc = 1;
396           else if ( params.nb_node == 0 )
397             nbproc = params.nb_proc_per_node;
398           else if ( params.nb_proc_per_node == 0 )
399             nbproc = params.nb_node;
400           else
401             nbproc = params.nb_node * params.nb_proc_per_node;
402         }
403
404       // "ssh user@machine distantPath/runRemote.sh hostNS portNS \
405       //  SALOME_Container containerName &"
406
407       if (resInfo.Protocol == rsh)
408         command = "rsh ";
409       else if (resInfo.Protocol == ssh)
410         command = "ssh ";
411       else
412         throw SALOME_Exception("Unknown protocol");
413
414       if (resInfo.UserName != "")
415         {
416           command += resInfo.UserName;
417           command += "@";
418         }
419
420       command += machine;
421       command += " ";
422
423       if (resInfo.AppliPath != "")
424         command += resInfo.AppliPath; // path relative to user@machine $HOME
425       else
426         {
427           ASSERT(getenv("APPLI"));
428           command += getenv("APPLI"); // path relative to user@machine $HOME
429         }
430
431       command += "/runRemote.sh ";
432
433       ASSERT(getenv("NSHOST")); 
434       command += getenv("NSHOST"); // hostname of CORBA name server
435
436       command += " ";
437       ASSERT(getenv("NSPORT"));
438       command += getenv("NSPORT"); // port of CORBA name server
439
440       if(params.isMPI)
441         {
442           command += " mpirun -np ";
443           std::ostringstream o;
444           o << nbproc << " ";
445           command += o.str();
446 #ifdef WITHLAM
447           command += "-x PATH,LD_LIBRARY_PATH,OMNIORB_CONFIG,SALOME_trace ";
448 #endif  
449           command += " SALOME_MPIContainer ";
450         }
451       else
452         command += " SALOME_Container ";
453
454       command += _NS->ContainerName(params);
455       command += " -id ";
456       sprintf(idc,"%ld",id);
457       command += idc;
458       command += " -";
459       AddOmninamesParams(command);
460       command += " > /tmp/";
461       command += _NS->ContainerName(params);
462       command += "_";
463       command += GetHostname();
464       command += "_";
465       command += getenv( "USER" ) ;
466       command += ".log 2>&1 &" ;
467
468       MESSAGE("command =" << command);
469     }
470
471   return command;
472 }
473
474
475 //=============================================================================
476 /*!
477  *  builds the command to be launched.
478  */ 
479 //=============================================================================
480
481 string
482 SALOME_ResourcesManager::BuildCommandToLaunchLocalContainer
483 (const Engines::MachineParameters& params, const long id)
484 {
485   _TmpFileName = "";
486   string command;
487   int nbproc = 0;
488   char idc[3*sizeof(long)];
489
490   if (params.isMPI)
491     {
492       command = "mpirun -np ";
493
494       if ( (params.nb_node <= 0) && (params.nb_proc_per_node <= 0) )
495         nbproc = 1;
496       else if ( params.nb_node == 0 )
497         nbproc = params.nb_proc_per_node;
498       else if ( params.nb_proc_per_node == 0 )
499         nbproc = params.nb_node;
500       else
501         nbproc = params.nb_node * params.nb_proc_per_node;
502
503       std::ostringstream o;
504
505       o << nbproc << " ";
506
507       command += o.str();
508 #ifdef WITHLAM
509       command += "-x PATH,LD_LIBRARY_PATH,OMNIORB_CONFIG,SALOME_trace ";
510 #endif
511
512       if (isPythonContainer(params.container_name))
513         command += "pyMPI SALOME_ContainerPy.py ";
514       else
515         command += "SALOME_MPIContainer ";
516     }
517
518   else
519     {
520       if (isPythonContainer(params.container_name))
521         command = "SALOME_ContainerPy.py ";
522       else
523         command = "SALOME_Container ";
524     }
525
526   command += _NS->ContainerName(params);
527   command += " -id ";
528   sprintf(idc,"%ld",id);
529   command += idc;
530   command += " -";
531   AddOmninamesParams(command);
532   command += " > /tmp/";
533   command += _NS->ContainerName(params);
534   command += "_";
535   command += GetHostname();
536   command += "_";
537   command += getenv( "USER" ) ;
538   command += ".log 2>&1 &" ;
539   MESSAGE("Command is ... " << command);
540   return command;
541 }
542
543
544 //=============================================================================
545 /*!
546  *  removes the generated temporary file in case of a remote launch.
547  */ 
548 //=============================================================================
549
550 void SALOME_ResourcesManager::RmTmpFile()
551 {
552   if (_TmpFileName != "")
553     {
554       string command = "rm ";
555       command += _TmpFileName;
556       char *temp = strdup(command.c_str());
557       int lgthTemp = strlen(temp);
558       temp[lgthTemp - 3] = '*';
559       temp[lgthTemp - 2] = '\0';
560       system(temp);
561       free(temp);
562     }
563 }
564
565
566 //=============================================================================
567 /*!
568  *  builds the script to be launched
569  */ 
570 //=============================================================================
571
572 string
573 SALOME_ResourcesManager::BuildCommand
574 (const string& machine,
575  const char *containerName)
576 {
577   // rsh -n ikkyo /export/home/rahuel/SALOME_ROOT/bin/runSession SALOME_Container -ORBInitRef NameService=corbaname::dm2s0017:1515 &
578   const ParserResourcesType& resInfo = _resourcesList[machine];
579   bool pyCont = isPythonContainer(containerName);
580
581   string command;
582
583   if (resInfo.Protocol == rsh)
584     command = "rsh -n " ;
585   else if (resInfo.Protocol == ssh)
586     command = "ssh -f -n ";
587   else
588     throw SALOME_Exception("Not implemented yet...");
589
590   command += machine;
591   command += " ";
592   string path = (*(resInfo.ModulesPath.find("KERNEL"))).second;
593   command += path;
594   command += "/bin/salome/";
595
596   if ( pyCont )
597     command += "SALOME_ContainerPy.py ";
598   else
599     command += "SALOME_Container ";
600
601   command += containerName;
602   command += " -";
603   AddOmninamesParams(command);
604   command += " > /tmp/";
605   command += containerName;
606   command += "_";
607   command += machine;
608   command += ".log 2>&1 &" ;
609
610   SCRUTE( command );
611   return command;
612 }
613
614 //=============================================================================
615 /*!
616  *  Gives a sublist of machines with matching OS.
617  *  If parameter OS is empty, gives the complete list of machines
618  */ 
619 //=============================================================================
620
621 // Warning need an updated parsed list : _resourcesList
622 void
623 SALOME_ResourcesManager::SelectOnlyResourcesWithOS
624 ( vector<string>& hosts,
625   const char *OS) const
626 throw(SALOME_Exception)
627 {
628   string base(OS);
629
630   for (map<string, ParserResourcesType>::const_iterator iter =
631          _resourcesList.begin();
632        iter != _resourcesList.end();
633        iter++)
634     {
635       if ( (*iter).second.OS == base || base.size() == 0)
636         hosts.push_back((*iter).first);
637     }
638 }
639
640
641 //=============================================================================
642 /*!
643  *  Gives a sublist of machines on which the module is known.
644  */ 
645 //=============================================================================
646
647 //Warning need an updated parsed list : _resourcesList
648 void
649 SALOME_ResourcesManager::KeepOnlyResourcesWithModule
650 ( vector<string>& hosts,
651   const char *moduleName) const
652 throw(SALOME_Exception)
653 {
654   for (vector<string>::iterator iter = hosts.begin(); iter != hosts.end();)
655     {
656       MapOfParserResourcesType::const_iterator it = _resourcesList.find(*iter);
657       const map<string, string>& mapOfModulesOfCurrentHost =
658         (((*it).second).ModulesPath);
659
660       if (mapOfModulesOfCurrentHost.find(moduleName) ==
661           mapOfModulesOfCurrentHost.end())
662         hosts.erase(iter);
663       else
664         iter++;
665     }
666 }
667
668
669 //=============================================================================
670 /*!
671  *   add to command all options relative to naming service.
672  */ 
673 //=============================================================================
674
675 void SALOME_ResourcesManager::AddOmninamesParams(string& command) const
676   {
677     // If env variable OMNIORB_CONFIG is not defined or the file is more complex than one line
678     // does not work
679     // Even if we use it we have to check if env variable exists
680     //string omniORBcfg( getenv( "OMNIORB_CONFIG" ) ) ;
681     //ifstream omniORBfile( omniORBcfg.c_str() ) ;
682     //char ORBInitRef[11] ;
683     //char egal[3] ;
684     //char nameservice[132] ;
685     //omniORBfile >> ORBInitRef ;
686     //command += "ORBInitRef " ;
687     //omniORBfile >> egal ;
688     //omniORBfile >> nameservice ;
689     //omniORBfile.close() ;
690     //char * bsn = strchr( nameservice , '\n' ) ;
691     //if ( bsn ) {
692     //bsn[ 0 ] = '\0' ;
693     //}
694     //command += nameservice ;
695
696     char *iorstr = _NS->getIORaddr();
697     command += "ORBInitRef NameService=";
698     command += iorstr;
699   }
700
701
702 //=============================================================================
703 /*!
704  *  add to command all options relative to naming service.
705  */ 
706 //=============================================================================
707
708 void SALOME_ResourcesManager::AddOmninamesParams(ofstream& fileStream) const
709   {
710     string omniORBcfg( getenv( "OMNIORB_CONFIG" ) ) ;
711     ifstream omniORBfile( omniORBcfg.c_str() ) ;
712     char ORBInitRef[11] ;
713     char egal[3] ;
714     char nameservice[132] ;
715     omniORBfile >> ORBInitRef ;
716     fileStream << "ORBInitRef ";
717     omniORBfile >> egal ;
718     omniORBfile >> nameservice ;
719     omniORBfile.close() ;
720     char * bsn = strchr( nameservice , '\n' ) ;
721
722     if ( bsn )
723       {
724         bsn[ 0 ] = '\0' ;
725       }
726
727     fileStream << nameservice;
728   }
729
730
731 //=============================================================================
732 /*!
733  *  generate a file name in /tmp directory
734  */ 
735 //=============================================================================
736
737 string SALOME_ResourcesManager::BuildTemporaryFileName() const
738   {
739     //build more complex file name to support multiple salome session
740     char *temp = new char[19];
741     strcpy(temp, "/tmp/command");
742     strcat(temp, "XXXXXX");
743 #ifndef WNT
744
745     mkstemp(temp);
746 #else
747
748     char aPID[80];
749     itoa(getpid(), aPID, 10);
750     strcat(temp, aPID);
751 #endif
752
753     string command(temp);
754     delete [] temp;
755     command += ".sh";
756     return command;
757   }
758
759
760 //=============================================================================
761 /*!
762  *  Builds in a temporary file the script to be launched.
763  *  
764  *  Used if SALOME Application ($APPLI) is not defined.
765  *  The command is build with data from CatalogResources, in which every path
766  *  used on remote computer must be defined.
767  */ 
768 //=============================================================================
769
770 string
771 SALOME_ResourcesManager::BuildTempFileToLaunchRemoteContainer
772 (const string& machine,
773  const Engines::MachineParameters& params)
774 {
775   _TmpFileName = BuildTemporaryFileName();
776   ofstream tempOutputFile;
777   tempOutputFile.open(_TmpFileName.c_str(), ofstream::out );
778   const ParserResourcesType& resInfo = _resourcesList[machine];
779   tempOutputFile << "#! /bin/sh" << endl;
780
781   // --- set env vars
782
783   for (map<string, string>::const_iterator iter = resInfo.ModulesPath.begin();
784        iter != resInfo.ModulesPath.end();
785        iter++)
786     {
787       string curModulePath((*iter).second);
788       tempOutputFile << (*iter).first << "_ROOT_DIR=" << curModulePath << endl;
789       tempOutputFile << "export " << (*iter).first << "_ROOT_DIR" << endl;
790       tempOutputFile << "LD_LIBRARY_PATH=" << curModulePath
791                      << "/lib/salome" << ":${LD_LIBRARY_PATH}" << endl;
792       tempOutputFile << "PYTHONPATH=" << curModulePath << "/bin/salome:"
793                      << curModulePath << "/lib/salome:" << curModulePath
794                      << "/lib/python2.2/site-packages/salome:";
795       tempOutputFile << curModulePath
796       << "/lib/python2.2/site-packages/salome/shared_modules:${PYTHONPATH}"
797       << endl;
798     }
799
800   tempOutputFile << "export LD_LIBRARY_PATH" << endl;
801   tempOutputFile << "export PYTHONPATH" << endl;
802   tempOutputFile << "source " << resInfo.PreReqFilePath << endl;
803
804   // ! env vars
805
806   if (params.isMPI)
807     {
808       tempOutputFile << "mpirun -np ";
809       int nbproc;
810
811       if ( (params.nb_node <= 0) && (params.nb_proc_per_node <= 0) )
812         nbproc = 1;
813       else if ( params.nb_node == 0 )
814         nbproc = params.nb_proc_per_node;
815       else if ( params.nb_proc_per_node == 0 )
816         nbproc = params.nb_node;
817       else
818         nbproc = params.nb_node * params.nb_proc_per_node;
819
820       std::ostringstream o;
821
822       tempOutputFile << nbproc << " ";
823 #ifdef WITHLAM
824       tempOutputFile << "-x PATH,LD_LIBRARY_PATH,OMNIORB_CONFIG,SALOME_trace ";
825 #endif
826     }
827
828   tempOutputFile << (*(resInfo.ModulesPath.find("KERNEL"))).second
829                  << "/bin/salome/";
830
831   if (params.isMPI)
832     {
833       if (isPythonContainer(params.container_name))
834         tempOutputFile << "pyMPI SALOME_ContainerPy.py ";
835       else
836         tempOutputFile << "SALOME_MPIContainer ";
837     }
838
839   else
840     {
841       if (isPythonContainer(params.container_name))
842         tempOutputFile << "SALOME_ContainerPy.py ";
843       else
844         tempOutputFile << "SALOME_Container ";
845     }
846
847   tempOutputFile << _NS->ContainerName(params) << " -";
848   AddOmninamesParams(tempOutputFile);
849   tempOutputFile << " &" << endl;
850   tempOutputFile.flush();
851   tempOutputFile.close();
852   chmod(_TmpFileName.c_str(), 0x1ED);
853
854   // --- Build command
855
856   string command;
857
858   if (resInfo.Protocol == rsh)
859     {
860       command = "rsh ";
861       string commandRcp = "rcp ";
862       commandRcp += _TmpFileName;
863       commandRcp += " ";
864       commandRcp += machine;
865       commandRcp += ":";
866       commandRcp += _TmpFileName;
867       system(commandRcp.c_str());
868     }
869
870   else if (resInfo.Protocol == ssh)
871     command = "ssh ";
872   else
873     throw SALOME_Exception("Unknown protocol");
874
875   command += machine;
876   _CommandForRemAccess = command;
877   command += " ";
878   command += _TmpFileName;
879   command += " > ";
880   command += "/tmp/";
881   command += _NS->ContainerName(params);
882   command += "_";
883   command += machine;
884   command += ".log 2>&1 &";
885   SCRUTE(command);
886
887   return command;
888
889 }
890
891
892
893