1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #include "ResourcesManager.hxx"
23 #include <Basics_Utils.hxx>
31 #include <sys/types.h>
33 #include <libxml/parser.h>
37 #define MAX_SIZE_FOR_HOSTNAME 256;
41 //=============================================================================
45 //=============================================================================
47 ResourcesManager_cpp::
48 ResourcesManager_cpp(const char *xmlFilePath) :
49 _path_resources(xmlFilePath)
51 #if defined(_DEBUG_) || defined(_DEBUG)
52 cerr << "ResourcesManager_cpp constructor" << endl;
56 //=============================================================================
58 * Standard constructor, parse resource file.
59 * - if ${APPLI} exists in environment,
60 * look for ${HOME}/${APPLI}/CatalogResources.xml
61 * - else look for default:
62 * ${KERNEL_ROOT_DIR}/share/salome/resources/kernel/CatalogResources.xml
63 * - parse XML resource file.
65 //=============================================================================
67 ResourcesManager_cpp::ResourcesManager_cpp() throw(ResourcesException)
69 #if defined(_DEBUG_) || defined(_DEBUG)
70 cerr << "ResourcesManager_cpp constructor" << endl;
72 _isAppliSalomeDefined = (getenv("APPLI") != 0);
73 if(!getenv("KERNEL_ROOT_DIR"))
74 throw ResourcesException("you must define KERNEL_ROOT_DIR environment variable!!");
76 if (_isAppliSalomeDefined)
78 _path_resources = getenv("HOME");
79 _path_resources += "/";
80 _path_resources += getenv("APPLI");
81 _path_resources += "/CatalogResources.xml";
86 _path_resources = getenv("KERNEL_ROOT_DIR");
87 _path_resources += "/share/salome/resources/kernel/CatalogResources.xml";
91 #if defined(_DEBUG_) || defined(_DEBUG)
92 cerr << "ResourcesManager_cpp constructor end";
96 //=============================================================================
100 //=============================================================================
102 ResourcesManager_cpp::~ResourcesManager_cpp()
104 #if defined(_DEBUG_) || defined(_DEBUG)
105 cerr << "ResourcesManager_cpp destructor" << endl;
109 //=============================================================================
111 * get the list of name of ressources fitting for the specified component.
112 * If hostname specified, check it is local or known in resources catalog.
115 * - select first machines with corresponding OS (all machines if
116 * parameter OS empty),
117 * - then select the sublist of machines on witch the component is known
118 * (if the result is empty, that probably means that the inventory of
119 * components is probably not done, so give complete list from previous step)
121 //=============================================================================
123 std::vector<std::string>
124 ResourcesManager_cpp::GetFittingResources(const machineParams& params,
125 const std::vector<std::string>& componentList) throw(ResourcesException)
127 vector <std::string> vec;
131 const char *hostname = params.hostname.c_str();
132 #if defined(_DEBUG_) || defined(_DEBUG)
133 cerr << "GetFittingResources " << hostname << " " << Kernel_Utils::GetHostname().c_str() << endl;
136 if (hostname[0] != '\0'){
138 if ( strcmp(hostname, "localhost") == 0 ||
139 strcmp(hostname, Kernel_Utils::GetHostname().c_str()) == 0 )
141 //#if defined(_DEBUG_) || defined(_DEBUG)
142 // cerr << "ResourcesManager_cpp::GetFittingResources : localhost" << endl;
144 vec.push_back(Kernel_Utils::GetHostname().c_str());
145 //#if defined(_DEBUG_) || defined(_DEBUG)
146 // cerr << "ResourcesManager_cpp::GetFittingResources : " << vec.size() << endl;
150 else if (_resourcesList.find(hostname) != _resourcesList.end())
152 // --- params.hostname is in the list of resources so return it.
153 vec.push_back(hostname);
156 else if (_resourcesBatchList.find(hostname) != _resourcesBatchList.end())
158 // --- params.hostname is in the list of resources so return it.
159 vec.push_back(hostname);
164 // Cas d'un cluster: nombre de noeuds > 1
166 for (map<string, ParserResourcesType>::const_iterator iter = _resourcesList.begin(); iter != _resourcesList.end(); iter++){
167 if( (*iter).second.DataForSort._nbOfNodes > 1 ){
168 if( strncmp(hostname,(*iter).first.c_str(),strlen(hostname)) == 0 ){
169 vec.push_back((*iter).first.c_str());
175 // --- user specified an unknown hostame so notify him.
176 #if defined(_DEBUG_) || defined(_DEBUG)
177 cerr << "ResourcesManager_cpp::GetFittingResources : SALOME_Exception" << endl;
179 throw ResourcesException("unknown host");
185 // --- Search for available resources sorted by priority
186 SelectOnlyResourcesWithOS(vec, params.OS.c_str());
188 KeepOnlyResourcesWithComponent(vec, componentList);
191 SelectOnlyResourcesWithOS(vec, params.OS.c_str());
193 // --- set wanted parameters
194 ResourceDataToSort::_nbOfNodesWanted = params.nb_node;
196 ResourceDataToSort::_nbOfProcPerNodeWanted = params.nb_proc_per_node;
198 ResourceDataToSort::_CPUFreqMHzWanted = params.cpu_clock;
200 ResourceDataToSort::_memInMBWanted = params.mem_mb;
204 list<ResourceDataToSort> li;
206 for (vector<string>::iterator iter = vec.begin();
209 li.push_back(_resourcesList[(*iter)].DataForSort);
215 for (list<ResourceDataToSort>::iterator iter2 = li.begin();
218 vec[i++] = (*iter2)._hostName;
225 //=============================================================================
227 * add an entry in the ressources catalog xml file.
228 * Return 0 if OK (KERNEL found in new resources components) else throw exception
230 //=============================================================================
233 ResourcesManager_cpp::
234 AddResourceInCatalog(const machineParams& paramsOfNewResources,
235 const vector<string>& componentsOnNewResources,
237 const char *userName,
239 AccessProtocolType prot)
240 throw(ResourcesException)
242 vector<string>::const_iterator iter = find(componentsOnNewResources.begin(),
243 componentsOnNewResources.end(),
246 if (iter != componentsOnNewResources.end())
248 ParserResourcesType newElt;
249 newElt.DataForSort._hostName = paramsOfNewResources.hostname;
250 newElt.Alias = alias;
251 newElt.Protocol = prot;
253 newElt.UserName = userName;
254 newElt.ComponentsList = componentsOnNewResources;
255 newElt.OS = paramsOfNewResources.OS;
256 newElt.DataForSort._memInMB = paramsOfNewResources.mem_mb;
257 newElt.DataForSort._CPUFreqMHz = paramsOfNewResources.cpu_clock;
258 newElt.DataForSort._nbOfNodes = paramsOfNewResources.nb_node;
259 newElt.DataForSort._nbOfProcPerNode =
260 paramsOfNewResources.nb_proc_per_node;
261 _resourcesList[newElt.DataForSort._hostName] = newElt;
266 throw ResourcesException("KERNEL is not present in this resource");
269 //=============================================================================
271 * Deletes a resource from the catalog
273 //=============================================================================
275 void ResourcesManager_cpp::DeleteResourceInCatalog(const char *hostname)
277 _resourcesList.erase(hostname);
280 //=============================================================================
282 * write the current data in memory in file.
284 //=============================================================================
286 void ResourcesManager_cpp::WriteInXmlFile()
288 const char* aFilePath = _path_resources.c_str();
290 FILE* aFile = fopen(aFilePath, "w");
294 #if defined(_DEBUG_) || defined(_DEBUG)
295 cerr << "Error opening file !" << endl;
300 xmlDocPtr aDoc = xmlNewDoc(BAD_CAST "1.0");
301 xmlNewDocComment(aDoc, BAD_CAST "ResourcesCatalog");
303 SALOME_ResourcesCatalog_Handler* handler =
304 new SALOME_ResourcesCatalog_Handler(_resourcesList, _resourcesBatchList);
305 handler->PrepareDocToXmlFile(aDoc);
308 #if defined(_DEBUG_) || defined(_DEBUG)
309 int isOk = xmlSaveFile(aFilePath, aDoc);
310 if (!isOk) cerr << "Error while XML file saving." << endl;
312 xmlSaveFile(aFilePath, aDoc);
320 #if defined(_DEBUG_) || defined(_DEBUG)
321 cerr << "WRITING DONE!" << endl;
325 //=============================================================================
327 * parse the data type catalog
329 //=============================================================================
331 const MapOfParserResourcesType& ResourcesManager_cpp::ParseXmlFile()
333 SALOME_ResourcesCatalog_Handler* handler =
334 new SALOME_ResourcesCatalog_Handler(_resourcesList, _resourcesBatchList);
336 const char* aFilePath = _path_resources.c_str();
337 FILE* aFile = fopen(aFilePath, "r");
341 xmlDocPtr aDoc = xmlReadFile(aFilePath, NULL, 0);
344 handler->ProcessXmlDocument(aDoc);
345 #if defined(_DEBUG_) || defined(_DEBUG)
347 cerr << "ResourcesManager_cpp: could not parse file "<< aFilePath << endl;
355 #if defined(_DEBUG_) || defined(_DEBUG)
357 cerr << "ResourcesManager_cpp: file "<<aFilePath<<" is not readable." << endl;
362 return _resourcesList;
365 //=============================================================================
367 * consult the content of the list
369 //=============================================================================
371 const MapOfParserResourcesType& ResourcesManager_cpp::GetList() const
373 return _resourcesList;
377 //=============================================================================
379 * dynamically obtains the first machines
381 //=============================================================================
383 string ResourcesManager_cpp::FindFirst(const std::vector<std::string>& listOfMachines)
385 return _dynamicResourcesSelecter.FindFirst(listOfMachines);
388 //=============================================================================
390 * dynamically obtains the best machines
392 //=============================================================================
394 string ResourcesManager_cpp::FindNext(const std::vector<std::string>& listOfMachines)
396 return _dynamicResourcesSelecter.FindNext(listOfMachines,_resourcesList);
398 //=============================================================================
400 * dynamically obtains the best machines
402 //=============================================================================
404 string ResourcesManager_cpp::FindBest(const std::vector<std::string>& listOfMachines)
406 return _dynamicResourcesSelecter.FindBest(listOfMachines);
409 //=============================================================================
411 * Gives a sublist of machines with matching OS.
412 * If parameter OS is empty, gives the complete list of machines
414 //=============================================================================
416 // Warning need an updated parsed list : _resourcesList
417 void ResourcesManager_cpp::SelectOnlyResourcesWithOS( vector<string>& hosts, const char *OS) const
418 throw(ResourcesException)
422 for (map<string, ParserResourcesType>::const_iterator iter =
423 _resourcesList.begin();
424 iter != _resourcesList.end();
427 if ( (*iter).second.OS == base || base.size() == 0)
428 hosts.push_back((*iter).first);
433 //=============================================================================
435 * Gives a sublist of machines on which the component is known.
437 //=============================================================================
439 //Warning need an updated parsed list : _resourcesList
440 void ResourcesManager_cpp::KeepOnlyResourcesWithComponent( vector<string>& hosts, const vector<string>& componentList) const
441 throw(ResourcesException)
443 for (vector<string>::iterator iter = hosts.begin(); iter != hosts.end();)
445 MapOfParserResourcesType::const_iterator it = _resourcesList.find(*iter);
446 const vector<string>& mapOfComponentsOfCurrentHost = (((*it).second).ComponentsList);
448 bool erasedHost = false;
449 if( mapOfComponentsOfCurrentHost.size() > 0 ){
450 for(unsigned int i=0;i<componentList.size();i++){
451 const char* compoi = componentList[i].c_str();
452 vector<string>::const_iterator itt = find(mapOfComponentsOfCurrentHost.begin(),
453 mapOfComponentsOfCurrentHost.end(),
455 // componentList[i]);
456 if (itt == mapOfComponentsOfCurrentHost.end()){
470 ParserResourcesType ResourcesManager_cpp::GetResourcesList(const std::string& machine)
472 if (_resourcesList.find(machine) != _resourcesList.end())
473 return _resourcesList[machine];
475 return _resourcesBatchList[machine];