+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()));
+ }
+ return thepids;
+}
+
+std::string SALOME_ContainerManager::getCommandToRunRemoteProcess(AccessProtocolType protocol,
+ const std::string & hostname,
+ const std::string & username)
+{
+ std::ostringstream command;
+ switch (protocol)
+ {
+ case rsh:
+ command << "rsh ";
+ if (username != "")
+ {
+ command << "-l " << username << " ";
+ }
+ command << hostname << " ";
+ break;
+ case ssh:
+ command << "ssh ";
+ if (username != "")
+ {
+ command << "-l " << username << " ";
+ }
+ command << hostname << " ";
+ break;
+ case srun:
+ // no need to redefine the user with srun, the job user is taken by default
+ // (note: for srun, user id can be specified with " --uid=<user>")
+ command << "srun -n 1 -N 1 --share --nodelist=" << hostname << " ";
+ break;
+ case pbsdsh:
+ command << "pbsdsh -o -h " << hostname << " ";
+ break;
+ case blaunch:
+ command << "blaunch -no-shell " << hostname << " ";
+ break;
+ default:
+ throw SALOME_Exception("Unknown protocol");
+ }
+
+ return command.str();
+}
+
+bool
+SALOME_ContainerManager::checkPaCOParameters(Engines::ContainerParameters & params, std::string resource_selected)
+{
+ bool result = true;
+
+ // Step 1 : check ContainerParameters
+ // Check container_name, has to be defined
+ if (std::string(params.container_name.in()) == "")
+ {
+ INFOS("[checkPaCOParameters] You must define a container_name to launch a PaCO++ container");
+ result = false;
+ }
+ // Check parallelLib
+ std::string parallelLib = params.parallelLib.in();
+ if (parallelLib != "Mpi" && parallelLib != "Dummy")
+ {
+ INFOS("[checkPaCOParameters] parallelLib is not correctly defined");
+ INFOS("[checkPaCOParameters] you can chosse between: Mpi and Dummy");
+ INFOS("[checkPaCOParameters] you entered: " << parallelLib);
+ result = false;
+ }
+ // Check nb_proc
+ if (params.nb_proc <= 0)
+ {
+ INFOS("[checkPaCOParameters] You must define a nb_proc > 0");
+ result = false;
+ }
+
+ // Step 2 : check resource_selected
+ const ParserResourcesType resource_definition = _resManager->GetResourceDefinition(resource_selected);
+ //std::string protocol = resource_definition->protocol.in();
+ std::string username = resource_definition.UserName;
+ std::string applipath = resource_definition.AppliPath;
+
+ //if (protocol == "" || username == "" || applipath == "")
+ if (username == "" || applipath == "")
+ {
+ INFOS("[checkPaCOParameters] resource selected is not well defined");
+ INFOS("[checkPaCOParameters] resource name: " << resource_definition.Name);
+ INFOS("[checkPaCOParameters] resource hostname: " << resource_definition.HostName);
+ INFOS("[checkPaCOParameters] resource protocol: " << resource_definition.getAccessProtocolTypeStr());
+ INFOS("[checkPaCOParameters] resource username: " << username);
+ INFOS("[checkPaCOParameters] resource applipath: " << applipath);
+ result = false;
+ }
+
+ return result;
+}
+
+/*
+ * :WARNING: Do not directly convert returned value to std::string
+ * This function may return NULL if env variable is not defined.
+ * And std::string(NULL) causes undefined behavior.
+ * Use GetenvThreadSafeAsString to properly get a std::string.
+*/
+char *SALOME_ContainerManager::GetenvThreadSafe(const char *name)
+{// getenv is not thread safe. See man 7 pthread.
+ Utils_Locker lock (&_getenvMutex);
+ return getenv(name);
+}
+
+/*
+ * Return env variable as a std::string.
+ * Return empty string if env variable is not set.
+ */
+std::string SALOME_ContainerManager::GetenvThreadSafeAsString(const char *name)
+{
+ char* var = GetenvThreadSafe(name);
+ return var ? std::string(var) : std::string();
+}
+
+int SALOME_ContainerManager::SystemThreadSafe(const char *command)
+{
+ Utils_Locker lock (&_systemMutex);
+ return system(command);
+}
+
+#ifdef WITH_PACO_PARALLEL
+