]> SALOME platform Git repositories - modules/kernel.git/blob - src/Container/SALOME_ContainerManager.cxx
Salome HOME
7e19bed50d3afc2705a5e4d560bd0366104d05a8
[modules/kernel.git] / src / Container / SALOME_ContainerManager.cxx
1 #include "SALOME_ContainerManager.hxx"
2 #include "SALOME_NamingService.hxx"
3 #include "OpUtil.hxx"
4 #include <sys/types.h>
5 #ifndef WNT
6 #include <unistd.h>
7 #endif
8 #include <vector>
9 #include "Utils_CorbaException.hxx"
10
11 #define TIME_OUT_TO_LAUNCH_CONT 21
12
13 using namespace std;
14
15 const char *SALOME_ContainerManager::_ContainerManagerNameInNS = 
16   "/ContainerManager";
17
18 //=============================================================================
19 /*! 
20  *  Constructor
21  *  \param orb
22  *  Define a CORBA single thread policy for the server, which avoid to deal
23  *  with non thread-safe usage like Change_Directory in SALOME naming service
24  */
25 //=============================================================================
26
27 SALOME_ContainerManager::SALOME_ContainerManager(CORBA::ORB_ptr orb)
28 {
29   MESSAGE("constructor");
30   _NS = new SALOME_NamingService(orb);
31   _ResManager = new SALOME_ResourcesManager(orb);
32   _id=0;
33   PortableServer::POA_var root_poa = PortableServer::POA::_the_root_poa();
34   PortableServer::POAManager_var pman = root_poa->the_POAManager();
35   PortableServer::POA_var my_poa;
36
37   CORBA::PolicyList policies;
38   policies.length(1);
39   PortableServer::ThreadPolicy_var threadPol = 
40     root_poa->create_thread_policy(PortableServer::SINGLE_THREAD_MODEL);
41   policies[0] = PortableServer::ThreadPolicy::_duplicate(threadPol);
42
43   my_poa = 
44     root_poa->create_POA("SThreadPOA",pman,policies);
45   threadPol->destroy();
46   PortableServer::ObjectId_var id = my_poa->activate_object(this);
47   CORBA::Object_var obj = my_poa->id_to_reference(id);
48   Engines::ContainerManager_var refContMan =
49     Engines::ContainerManager::_narrow(obj);
50
51   _NS->Register(refContMan,_ContainerManagerNameInNS);
52   MESSAGE("constructor end");
53 }
54
55 //=============================================================================
56 /*! 
57  * destructor
58  */
59 //=============================================================================
60
61 SALOME_ContainerManager::~SALOME_ContainerManager()
62 {
63   MESSAGE("destructor");
64   delete _NS;
65   delete _ResManager;
66 }
67
68 //=============================================================================
69 /*! CORBA method:
70  *  shutdown all the containers, then the ContainerManager servant
71  */
72 //=============================================================================
73
74 void SALOME_ContainerManager::Shutdown()
75 {
76   MESSAGE("Shutdown");
77   ShutdownContainers();
78   PortableServer::ObjectId_var oid = _default_POA()->servant_to_id(this);
79   _default_POA()->deactivate_object(oid);
80   _remove_ref();
81   
82 }
83
84 //=============================================================================
85 /*! CORBA Method:
86  *  Loop on all the containers listed in naming service, ask shutdown on each
87  */
88 //=============================================================================
89
90 void SALOME_ContainerManager::ShutdownContainers()
91 {
92   MESSAGE("ShutdownContainers");
93   _NS->Change_Directory("/Containers");
94   vector<string> vec = _NS->list_directory_recurs();
95   for(vector<string>::iterator iter = vec.begin();iter!=vec.end();iter++)
96     {
97       SCRUTE((*iter));
98       CORBA::Object_var obj=_NS->Resolve((*iter).c_str());
99       Engines::Container_var cont=Engines::Container::_narrow(obj);
100       if(!CORBA::is_nil(cont))
101         {
102           MESSAGE("ShutdownContainers: " << (*iter));
103           cont->Shutdown();
104         }
105       else MESSAGE("ShutdownContainers: no container ref for " << (*iter));
106     }
107 }
108
109 //=============================================================================
110 /*! CORBA Method:
111  *  Find a suitable Container in a list of machines, or start one
112  *  \param params            Machine Parameters required for the container
113  *  \param possibleComputers list of machines usable for find or start
114  */
115 //=============================================================================
116
117 Engines::Container_ptr
118 SALOME_ContainerManager::
119 FindOrStartContainer(const Engines::MachineParameters& params,
120                      const Engines::MachineList& possibleComputers)
121 {
122   long id;
123   string containerNameInNS;
124   char idc[3*sizeof(long)];
125
126   Engines::Container_ptr ret = FindContainer(params,possibleComputers);
127   if(!CORBA::is_nil(ret))
128     return ret;
129   MESSAGE("Container doesn't exist try to launch it ...");
130   MESSAGE("SALOME_ContainerManager::FindOrStartContainer " <<
131           possibleComputers.length());
132   //vector<string> vector;
133   string theMachine=_ResManager->FindBest(possibleComputers);
134   MESSAGE("try to launch it on " << theMachine);
135
136   // Get Id for container: a parallel container registers in Naming Service
137   // on the machine where is process 0. ContainerManager does'nt know the name
138   // of this machine before the launch of the parallel container. So to get
139   // the IOR of the parallel container in Naming Service, ContainerManager
140   // gives a unique Id. The parallel container registers his name under
141   // /ContainerManager/Id directory in NamingService
142
143   id = GetIdForContainer();
144
145   string command;
146   if(theMachine=="")
147     {
148       MESSAGE("SALOME_ContainerManager::FindOrStartContainer : " <<
149               "no possible computer");
150       return Engines::Container::_nil();
151     }
152   else if(theMachine==GetHostname())
153     {
154       command=_ResManager->BuildCommandToLaunchLocalContainer(params,id);
155     }
156   else
157     command =
158       _ResManager->BuildCommandToLaunchRemoteContainer(theMachine,params,id);
159
160   _ResManager->RmTmpFile();
161   int status=system(command.c_str());
162   if (status == -1)
163     {
164       MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed " <<
165               "(system command status -1)");
166       return Engines::Container::_nil();
167     }
168   else if (status == 217)
169     {
170       MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed " <<
171               "(system command status 217)");
172       return Engines::Container::_nil();
173     }
174   else
175     {
176       int count=TIME_OUT_TO_LAUNCH_CONT;
177       while ( CORBA::is_nil(ret) && count )
178         {
179 #ifndef WNT
180           sleep( 1 ) ;
181 #else
182           Sleep(1000);
183 #endif
184           count-- ;
185           if ( count != 10 )
186             MESSAGE( count << ". Waiting for FactoryServer on " << theMachine);
187           if(params.isMPI)
188             {
189               containerNameInNS = "/ContainerManager/id";
190               sprintf(idc,"%ld",id);
191               containerNameInNS += idc;
192             }
193           else
194             containerNameInNS =
195               _NS->BuildContainerNameForNS(params,theMachine.c_str());
196           SCRUTE(containerNameInNS);
197           CORBA::Object_var obj = _NS->Resolve(containerNameInNS.c_str());
198           ret=Engines::Container::_narrow(obj);
199         }
200       if ( CORBA::is_nil(ret) )
201         {
202           MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed");
203         }
204       return ret;
205     }
206 }
207
208 //=============================================================================
209 /*! 
210  * 
211  */
212 //=============================================================================
213
214 Engines::MachineList *
215 SALOME_ContainerManager::
216 GetFittingResources(const Engines::MachineParameters& params,
217                     const char *componentName)
218 {
219   MESSAGE("SALOME_ContainerManager::GetFittingResources");
220   Engines::MachineList *ret=new Engines::MachineList;
221   vector<string> vec;
222   try
223     {
224       vec = _ResManager->GetFittingResources(params,componentName);
225     }
226   catch(const SALOME_Exception &ex)
227     {
228       INFOS("Caught exception.");
229       THROW_SALOME_CORBA_EXCEPTION(ex.what(),SALOME::BAD_PARAM);
230       //return ret;
231     }
232
233   MESSAGE("Machine list length "<<vec.size());
234   ret->length(vec.size());
235   for(unsigned int i=0;i<vec.size();i++)
236     {
237       (*ret)[i]=(vec[i]).c_str();
238     }
239   return ret;
240 }
241
242 //=============================================================================
243 /*! 
244  * 
245  */
246 //=============================================================================
247
248 char*
249 SALOME_ContainerManager::
250 FindBest(const Engines::MachineList& possibleComputers)
251 {
252   string theMachine=_ResManager->FindBest(possibleComputers);
253   return CORBA::string_dup(theMachine.c_str());
254 }
255
256 //=============================================================================
257 /*! 
258  * 
259  */
260 //=============================================================================
261
262 Engines::Container_ptr
263 SALOME_ContainerManager::
264 FindContainer(const Engines::MachineParameters& params,
265               const char *theMachine)
266 {
267   string containerNameInNS(_NS->BuildContainerNameForNS(params,theMachine));
268   CORBA::Object_var obj = _NS->Resolve(containerNameInNS.c_str());
269   if( !CORBA::is_nil(obj) )
270     return Engines::Container::_narrow(obj);
271   else
272     return Engines::Container::_nil();
273 }
274
275 //=============================================================================
276 /*! 
277  * 
278  */
279 //=============================================================================
280
281 Engines::Container_ptr
282 SALOME_ContainerManager::
283 FindContainer(const Engines::MachineParameters& params,
284               const Engines::MachineList& possibleComputers)
285 {
286   MESSAGE("FindContainer "<<possibleComputers.length());
287   for(unsigned int i=0;i<possibleComputers.length();i++)
288     {
289       MESSAGE("FindContainer possible " << possibleComputers[i]);
290       Engines::Container_ptr cont = FindContainer(params,possibleComputers[i]);
291       if( !CORBA::is_nil(cont) )
292         return cont;
293     }
294   MESSAGE("FindContainer: not found");
295   return Engines::Container::_nil();
296 }
297
298 //=============================================================================
299 /*! 
300  * Get Id for container: a parallel container registers in Naming Service
301  * on the machine where is process 0. ContainerManager does'nt know the name
302  * of this machine before the launch of the parallel container. So to get
303  * the IOR of the parallel container in Naming Service, ContainerManager
304  * gives a unique Id. The parallel container registers his name under
305  * /ContainerManager/Id directory in NamingService
306  */
307 //=============================================================================
308
309
310 long SALOME_ContainerManager::GetIdForContainer(void)
311 {
312   _id++;
313   return _id;
314 }
315