+
+ command += "/runRemote.sh ";
+
+ ASSERT(GetenvThreadSafe("NSHOST"));
+ command += GetenvThreadSafeAsString("NSHOST"); // hostname of CORBA name server
+
+ command += " ";
+ ASSERT(GetenvThreadSafe("NSPORT"));
+ command += GetenvThreadSafeAsString("NSPORT"); // port of CORBA name server
+
+ std::string wdir = params.workingdir.in();
+ if(wdir != "")
+ {
+ command += " WORKINGDIR ";
+ command += " '";
+ if(wdir == "$TEMPDIR")
+ wdir="\\$TEMPDIR";
+ command += wdir; // requested working directory
+ command += "'";
+ }
+
+ if(params.isMPI)
+ {
+ command += " mpirun -np ";
+ std::ostringstream o;
+ o << nbproc << " ";
+ command += o.str();
+#ifdef LAM_MPI
+ command += "-x PATH,LD_LIBRARY_PATH,OMNIORB_CONFIG,SALOME_trace ";
+#elif defined(OPEN_MPI)
+ if( GetenvThreadSafe("OMPI_URI_FILE") == NULL )
+ command += "-x PATH -x LD_LIBRARY_PATH -x OMNIORB_CONFIG -x SALOME_trace";
+ else{
+ command += "-x PATH -x LD_LIBRARY_PATH -x OMNIORB_CONFIG -x SALOME_trace -ompi-server file:";
+ command += GetenvThreadSafeAsString("OMPI_URI_FILE");
+ }
+#elif defined(MPICH)
+ command += "-nameserver " + Kernel_Utils::GetHostname();
+#endif
+ command += " SALOME_MPIContainer ";
+ }
+ else
+ command += " " +container_exe+ " ";
+
+ command += _NS->ContainerName(params);
+ command += " -";
+ AddOmninamesParams(command);
+
+ MESSAGE("command =" << command);
+ }
+
+ return command;
+}
+
+//=============================================================================
+/*!
+ * builds the command to be launched.
+ */
+//=============================================================================
+std::string SALOME_ContainerManager::BuildCommandToLaunchLocalContainer(const Engines::ContainerParameters& params, const std::string& machinesFile, const std::string& container_exe, std::string& tmpFileName) const
+{
+ tmpFileName = BuildTemporaryFileName();
+ std::string command;
+ int nbproc = 0;
+
+ std::ostringstream o;
+
+ if (params.isMPI)
+ {
+ o << "mpirun -np ";
+
+ if ( params.nb_proc <= 0 )
+ nbproc = 1;
+ else
+ nbproc = params.nb_proc;
+
+ o << nbproc << " ";
+
+ if( GetenvThreadSafe("LIBBATCH_NODEFILE") != NULL )
+ o << "-machinefile " << machinesFile << " ";
+
+#ifdef LAM_MPI
+ o << "-x PATH,LD_LIBRARY_PATH,OMNIORB_CONFIG,SALOME_trace ";
+#elif defined(OPEN_MPI)
+ if( GetenvThreadSafe("OMPI_URI_FILE") == NULL )
+ o << "-x PATH -x LD_LIBRARY_PATH -x OMNIORB_CONFIG -x SALOME_trace";
+ else
+ {
+ o << "-x PATH -x LD_LIBRARY_PATH -x OMNIORB_CONFIG -x SALOME_trace -ompi-server file:";
+ o << GetenvThreadSafeAsString("OMPI_URI_FILE");
+ }
+#elif defined(MPICH)
+ o << "-nameserver " + Kernel_Utils::GetHostname();
+#endif
+
+ if (isPythonContainer(params.container_name))
+ o << " pyMPI SALOME_ContainerPy.py ";
+ else
+ o << " SALOME_MPIContainer ";
+ }
+
+ else
+ {
+ std::string wdir=params.workingdir.in();
+ if(wdir != "")
+ {
+ // a working directory is requested
+ if(wdir == "$TEMPDIR")
+ {
+ // a new temporary directory is requested
+ std::string dir = Kernel_Utils::GetTmpDir();
+#ifdef WIN32
+ o << "cd /d " << dir << std::endl;
+#else
+ o << "cd " << dir << ";";
+#endif
+
+ }
+ else
+ {
+ // a permanent directory is requested use it or create it
+#ifdef WIN32
+ o << "mkdir " + wdir << std::endl;
+ o << "cd /D " + wdir << std::endl;
+#else
+ o << "mkdir -p " << wdir << " && cd " << wdir + ";";
+#endif
+ }
+ }
+
+ if (isPythonContainer(params.container_name))
+ o << "SALOME_ContainerPy.py ";
+ else
+ o << container_exe + " ";
+
+ }
+
+ o << _NS->ContainerName(params);
+ o << " -";
+ AddOmninamesParams(o);
+
+ std::ofstream command_file( tmpFileName.c_str() );
+ command_file << o.str();
+ command_file.close();
+
+#ifndef WIN32
+ chmod(tmpFileName.c_str(), 0x1ED);
+#endif
+ command = tmpFileName;
+
+ MESSAGE("Command is file ... " << command);
+ MESSAGE("Command is ... " << o.str());
+ return command;
+}
+
+
+//=============================================================================
+/*!
+ * removes the generated temporary file in case of a remote launch.
+ * This method is thread safe
+ */
+//=============================================================================
+
+void SALOME_ContainerManager::RmTmpFile(std::string& tmpFileName)
+{
+ int lenght = tmpFileName.size();
+ if ( lenght > 0)
+ {
+#ifdef WIN32
+ std::string command = "del /F ";
+#else
+ std::string command = "rm ";
+#endif
+ if ( lenght > 4 )
+ command += tmpFileName.substr(0, lenght - 3 );
+ else
+ command += tmpFileName;
+ command += '*';
+ SystemThreadSafe(command.c_str());
+ //if dir is empty - remove it
+ std::string tmp_dir = Kernel_Utils::GetDirByPath( tmpFileName );
+ if ( Kernel_Utils::IsEmptyDir( tmp_dir ) )
+ {
+#ifdef WIN32
+ command = "del /F " + tmp_dir;
+#else
+ command = "rmdir " + tmp_dir;
+#endif
+ SystemThreadSafe(command.c_str());
+ }
+ }
+}
+
+//=============================================================================
+/*!
+ * add to command all options relative to naming service.
+ */
+//=============================================================================
+
+void SALOME_ContainerManager::AddOmninamesParams(std::string& command) const
+{
+ std::ostringstream oss;
+ AddOmninamesParams(oss);
+ command+=oss.str();
+}
+
+//=============================================================================
+/*!
+ * add to command all options relative to naming service.
+ */
+//=============================================================================
+
+void SALOME_ContainerManager::AddOmninamesParams(std::ostream& fileStream) const
+{
+ AddOmninamesParams(fileStream,_NS);
+}
+
+//=============================================================================
+/*!
+ * add to command all options relative to naming service.
+ */
+//=============================================================================
+
+void SALOME_ContainerManager::AddOmninamesParams(std::ostream& fileStream, SALOME_NamingService *ns)
+{
+ CORBA::String_var iorstr(ns->getIORaddr());
+ fileStream << "ORBInitRef NameService=";
+ fileStream << iorstr;
+}
+
+void SALOME_ContainerManager::MakeTheCommandToBeLaunchedASync(std::string& command)
+{
+#ifdef WIN32
+ command = "%PYTHONBIN% -c \"import subprocess ; subprocess.Popen(command).pid\"";
+#else
+ command += " &";
+#endif
+}
+
+int SALOME_ContainerManager::GetTimeOutToLoaunchServer()
+{
+ int count(TIME_OUT_TO_LAUNCH_CONT);
+ if (GetenvThreadSafe("TIMEOUT_TO_LAUNCH_CONTAINER") != 0)
+ {
+ std::string new_count_str(GetenvThreadSafeAsString("TIMEOUT_TO_LAUNCH_CONTAINER"));
+ int new_count;
+ std::istringstream ss(new_count_str);
+ if (!(ss >> new_count))
+ {
+ INFOS("[LaunchContainer] TIMEOUT_TO_LAUNCH_CONTAINER should be an int");
+ }
+ else
+ count = new_count;
+ }
+ return count;
+}
+
+void SALOME_ContainerManager::SleepInSecond(int ellapseTimeInSecond)
+{
+#ifndef WIN32
+ sleep( ellapseTimeInSecond ) ;
+#else
+ int timeInMS(1000*ellapseTimeInSecond);
+ Sleep(timeInMS);
+#endif
+}
+
+//=============================================================================
+/*!
+ * generate a file name in /tmp directory
+ */
+//=============================================================================
+
+std::string SALOME_ContainerManager::BuildTemporaryFileName()
+{
+ //build more complex file name to support multiple salome session
+ std::string aFileName = Kernel_Utils::GetTmpFileName();
+#ifndef WIN32
+ aFileName += ".sh";
+#else
+ aFileName += ".bat";
+#endif
+ return aFileName;
+}
+
+//=============================================================================
+/*!
+ * Builds in a temporary file the script to be launched.
+ *
+ * Used if SALOME Application ($APPLI) is not defined.
+ * The command is build with data from CatalogResources, in which every path
+ * used on remote computer must be defined.
+ */
+//=============================================================================
+
+std::string SALOME_ContainerManager::BuildTempFileToLaunchRemoteContainer (const std::string& resource_name, const Engines::ContainerParameters& params, std::string& tmpFileName) const
+{
+ int status;
+
+ tmpFileName = BuildTemporaryFileName();
+ std::ofstream tempOutputFile;
+ tempOutputFile.open(tmpFileName.c_str(), std::ofstream::out );
+ const ParserResourcesType resInfo(_resManager->GetResourceDefinition(resource_name));
+ tempOutputFile << "#! /bin/sh" << std::endl;
+
+ // --- set env vars
+
+ tempOutputFile << "export SALOME_trace=local" << std::endl; // mkr : 27.11.2006 : PAL13967 - Distributed supervision graphs - Problem with "SALOME_trace"
+ //tempOutputFile << "source " << resInfo.PreReqFilePath << endl;
+
+ // ! env vars
+
+ if (params.isMPI)
+ {
+ tempOutputFile << "mpirun -np ";
+ int nbproc;
+
+ if ( params.nb_proc <= 0 )
+ nbproc = 1;
+ else
+ nbproc = params.nb_proc;
+
+ std::ostringstream o;
+
+ tempOutputFile << nbproc << " ";
+#ifdef LAM_MPI
+ tempOutputFile << "-x PATH,LD_LIBRARY_PATH,OMNIORB_CONFIG,SALOME_trace ";
+#elif defined(OPEN_MPI)
+ if( GetenvThreadSafe("OMPI_URI_FILE") == NULL )
+ tempOutputFile << "-x PATH -x LD_LIBRARY_PATH -x OMNIORB_CONFIG -x SALOME_trace";
+ else{
+ tempOutputFile << "-x PATH -x LD_LIBRARY_PATH -x OMNIORB_CONFIG -x SALOME_trace -ompi-server file:";
+ tempOutputFile << GetenvThreadSafeAsString("OMPI_URI_FILE");
+ }
+#elif defined(MPICH)
+ tempOutputFile << "-nameserver " + Kernel_Utils::GetHostname();
+#endif
+ }
+
+ tempOutputFile << GetenvThreadSafeAsString("KERNEL_ROOT_DIR") << "/bin/salome/";
+
+ if (params.isMPI)
+ {
+ if (isPythonContainer(params.container_name))
+ tempOutputFile << " pyMPI SALOME_ContainerPy.py ";
+ else
+ tempOutputFile << " SALOME_MPIContainer ";
+ }
+
+ else
+ {
+ if (isPythonContainer(params.container_name))
+ tempOutputFile << "SALOME_ContainerPy.py ";
+ else
+ tempOutputFile << "SALOME_Container ";
+ }
+
+ tempOutputFile << _NS->ContainerName(params) << " -";
+ AddOmninamesParams(tempOutputFile);
+ tempOutputFile << " &" << std::endl;
+ tempOutputFile.flush();
+ tempOutputFile.close();
+#ifndef WIN32
+ chmod(tmpFileName.c_str(), 0x1ED);
+#endif
+
+ // --- Build command
+
+ std::string command;
+
+ if (resInfo.Protocol == rsh)
+ {
+ command = "rsh ";
+ std::string commandRcp = "rcp ";
+ commandRcp += tmpFileName;
+ commandRcp += " ";
+ commandRcp += resInfo.HostName;
+ commandRcp += ":";
+ commandRcp += tmpFileName;
+ status = SystemThreadSafe(commandRcp.c_str());
+ }
+
+ else if (resInfo.Protocol == ssh)
+ {
+ command = "ssh ";
+ std::string commandRcp = "scp ";
+ commandRcp += tmpFileName;
+ commandRcp += " ";
+ commandRcp += resInfo.HostName;
+ commandRcp += ":";
+ commandRcp += tmpFileName;
+ status = SystemThreadSafe(commandRcp.c_str());
+ }
+
+ else if (resInfo.Protocol == srun)
+ {
+ command = "srun -n 1 -N 1 --share --nodelist=";
+ std::string commandRcp = "rcp ";
+ commandRcp += tmpFileName;
+ commandRcp += " ";
+ commandRcp += resInfo.HostName;
+ commandRcp += ":";
+ commandRcp += tmpFileName;
+ status = SystemThreadSafe(commandRcp.c_str());
+ }
+ else
+ throw SALOME_Exception("Unknown protocol");
+
+ if(status)
+ throw SALOME_Exception("Error of connection on remote host");
+
+ command += resInfo.HostName;
+ command += " ";
+ command += tmpFileName;
+
+ SCRUTE(command);
+
+ return command;
+
+}
+
+std::string SALOME_ContainerManager::GetMPIZeroNode(const std::string machine, const std::string machinesFile) const
+{
+ int status;
+ std::string zeronode;
+ std::string command;
+ std::string tmpFile = BuildTemporaryFileName();
+
+ if( GetenvThreadSafe("LIBBATCH_NODEFILE") == NULL )
+ {
+ if (_isAppliSalomeDefined)
+ {
+ const ParserResourcesType resInfo(_resManager->GetResourceDefinition(machine));
+
+ if (resInfo.Protocol == rsh)
+ command = "rsh ";
+ else if (resInfo.Protocol == ssh)
+ command = "ssh ";
+ else if (resInfo.Protocol == srun)
+ command = "srun -n 1 -N 1 --share --nodelist=";
+ else
+ throw SALOME_Exception("Unknown protocol");
+
+ if (resInfo.UserName != "")
+ {
+ command += "-l ";
+ command += resInfo.UserName;
+ command += " ";
+ }
+
+ command += resInfo.HostName;
+ command += " ";
+
+ if (resInfo.AppliPath != "")
+ command += resInfo.AppliPath; // path relative to user@machine $HOME
+ else
+ {
+ ASSERT(GetenvThreadSafe("APPLI"));
+ command += GetenvThreadSafeAsString("APPLI"); // path relative to user@machine $HOME
+ }
+
+ command += "/runRemote.sh ";
+
+ ASSERT(GetenvThreadSafe("NSHOST"));
+ command += GetenvThreadSafeAsString("NSHOST"); // hostname of CORBA name server
+
+ command += " ";
+ ASSERT(GetenvThreadSafe("NSPORT"));
+ command += GetenvThreadSafeAsString("NSPORT"); // port of CORBA name server
+
+ command += " mpirun -np 1 hostname -s > " + tmpFile;
+ }
+ else
+ command = "mpirun -np 1 hostname -s > " + tmpFile;
+ }
+ else
+ command = "mpirun -np 1 -machinefile " + machinesFile + " hostname -s > " + tmpFile;
+
+ status = SystemThreadSafe(command.c_str());
+ if( status == 0 ){
+ std::ifstream fp(tmpFile.c_str(),std::ios::in);
+ while(fp >> zeronode);
+ }
+
+ RmTmpFile(tmpFile);
+
+ return zeronode;
+}
+
+std::string SALOME_ContainerManager::machinesFile(const int nbproc)
+{
+ std::string tmp;
+ std::string nodesFile = GetenvThreadSafeAsString("LIBBATCH_NODEFILE");
+ std::string machinesFile = Kernel_Utils::GetTmpFileName();
+ std::ifstream fpi(nodesFile.c_str(),std::ios::in);
+ std::ofstream fpo(machinesFile.c_str(),std::ios::out);
+
+ _numInstanceMutex.lock();
+
+ for(int i=0;i<_nbprocUsed;i++)
+ fpi >> tmp;
+
+ for(int i=0;i<nbproc;i++)
+ if( fpi >> tmp )
+ fpo << tmp << std::endl;
+ else
+ throw SALOME_Exception("You need more processors than batch session have allocated for you! Unable to launch the mpi container: ");
+
+ _nbprocUsed += nbproc;
+ fpi.close();
+ fpo.close();
+
+ _numInstanceMutex.unlock();
+
+ return machinesFile;
+
+}
+
+std::set<pid_t> SALOME_ContainerManager::getpidofprogram(const std::string program)
+{
+ std::set<pid_t> thepids;
+ std::string tmpFile = Kernel_Utils::GetTmpFileName();
+ std::string cmd;
+ std::string thepid;
+ cmd = "pidof " + program + " > " + tmpFile;
+ SystemThreadSafe(cmd.c_str());
+ std::ifstream fpi(tmpFile.c_str(),std::ios::in);
+ while(fpi >> thepid){
+ thepids.insert(atoi(thepid.c_str()));