1 // Copyright (C) 2007-2011 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
23 #include "ResourcesManager.hxx"
24 #include <Basics_Utils.hxx>
31 #include <sys/types.h>
37 #include <libxml/parser.h>
41 #define MAX_SIZE_FOR_HOSTNAME 256;
43 static LoadRateManagerFirst first;
44 static LoadRateManagerCycl cycl;
45 static LoadRateManagerAltCycl altcycl;
46 //=============================================================================
50 //=============================================================================
52 ResourcesManager_cpp::
53 ResourcesManager_cpp(const char *xmlFilePath)
55 _path_resources.push_back(xmlFilePath);
56 #if defined(_DEBUG_) || defined(_DEBUG)
57 std::cerr << "ResourcesManager_cpp constructor" << std::endl;
59 _resourceManagerMap["first"]=&first;
60 _resourceManagerMap["cycl"]=&cycl;
61 _resourceManagerMap["altcycl"]=&altcycl;
62 _resourceManagerMap["best"]=&altcycl;
63 _resourceManagerMap[""]=&altcycl;
66 //=============================================================================
68 * Standard constructor, parse resource file.
69 * - if ${APPLI} exists in environment,
70 * look for ${HOME}/${APPLI}/CatalogResources.xml
71 * - else look for default:
72 * ${KERNEL_ROOT_DIR}/share/salome/resources/kernel/CatalogResources.xml
73 * - parse XML resource file.
75 //=============================================================================
77 ResourcesManager_cpp::ResourcesManager_cpp() throw(ResourcesException)
79 RES_MESSAGE("ResourcesManager_cpp constructor");
81 _resourceManagerMap["first"]=&first;
82 _resourceManagerMap["cycl"]=&cycl;
83 _resourceManagerMap["altcycl"]=&altcycl;
84 _resourceManagerMap["best"]=&altcycl;
85 _resourceManagerMap[""]=&altcycl;
87 bool default_catalog_resource = true;
88 if (getenv("USER_CATALOG_RESOURCES_FILE") != 0)
90 default_catalog_resource = false;
91 std::string user_file("");
92 user_file = getenv("USER_CATALOG_RESOURCES_FILE");
93 std::ifstream ifile(user_file.c_str(), std::ifstream::in );
95 // The file exists, and is open for input
96 _path_resources.push_back(user_file);
99 default_catalog_resource = true;
100 RES_INFOS("Warning: USER_CATALOG_RESOURCES_FILE is set and file cannot be found.")
103 if (default_catalog_resource)
105 std::string default_file("");
106 if (getenv("APPLI") != 0)
108 default_file += getenv("HOME");
110 default_file += getenv("APPLI");
111 default_file += "/CatalogResources.xml";
112 _path_resources.push_back(default_file);
116 if(!getenv("KERNEL_ROOT_DIR"))
117 throw ResourcesException("you must define KERNEL_ROOT_DIR environment variable!! -> cannot load a CatalogResources.xml");
118 default_file = getenv("KERNEL_ROOT_DIR");
119 default_file += "/share/salome/resources/kernel/CatalogResources.xml";
120 _path_resources.push_back(default_file);
127 RES_MESSAGE("ResourcesManager_cpp constructor end");
130 //=============================================================================
132 * Standard Destructor
134 //=============================================================================
136 ResourcesManager_cpp::~ResourcesManager_cpp()
138 RES_MESSAGE("ResourcesManager_cpp destructor");
141 //=============================================================================
142 //! get the list of resource names fitting constraints given by params
145 * 1: Restrict list with resourceList if defined
146 * 2: If name is defined -> check resource list
147 * 3: If not 2:, if hostname is defined -> check resource list
148 * 4: If not 3:, sort resource with nb_proc, etc...
149 * 5: In all cases remove resource that does not correspond with OS
150 * 6: And remove resource with componentList - if list is empty ignored it...
152 //=============================================================================
154 std::vector<std::string>
155 ResourcesManager_cpp::GetFittingResources(const resourceParams& params) throw(ResourcesException)
157 RES_MESSAGE("[GetFittingResources] on computer " << Kernel_Utils::GetHostname().c_str());
158 RES_MESSAGE("[GetFittingResources] with resource name: " << params.name);
159 RES_MESSAGE("[GetFittingResources] with hostname: "<< params.hostname);
162 std::vector<std::string> vec;
164 // Parse Again CalatogResource File
168 // 1: If name is defined -> check resource list
169 // 2: Restrict list with resourceList if defined
170 // 3: If not 2:, if hostname is defined -> check resource list
171 // 4: If not 3:, sort resource with nb_proc, etc...
172 // 5: In all cases remove resource that does not correspond with OS
173 // 6: And remove resource with componentList - if list is empty ignored it...
176 if (params.name != "")
178 RES_MESSAGE("[GetFittingResources] name parameter found !");
179 if (_resourcesList.find(params.name) != _resourcesList.end())
181 vec.push_back(params.name);
185 RES_MESSAGE("[GetFittingResources] resource name was not found on resource list ! name requested was " << params.name);
186 std::string error("[GetFittingResources] resource name was not found on resource list ! name requested was " + params.name);
187 throw ResourcesException(error);
190 MapOfParserResourcesType local_resourcesList = _resourcesList;
192 if (params.resourceList.size() > 0)
194 RES_MESSAGE("[GetFittingResources] Restricted resource list found !");
195 local_resourcesList.clear();
196 std::vector<std::string>::size_type sz = params.resourceList.size();
198 for (unsigned int i=0; i < sz; i++)
200 if (_resourcesList.find(params.resourceList[i]) != _resourcesList.end())
201 local_resourcesList[params.resourceList[i]] = _resourcesList[params.resourceList[i]];
206 if (params.hostname != "")
208 RES_MESSAGE("[GetFittingResources] Entering in hostname case !");
210 std::string hostname = params.hostname;
211 if (hostname == "localhost")
212 hostname = Kernel_Utils::GetHostname().c_str();
214 std::map<std::string, ParserResourcesType>::const_iterator iter = _resourcesList.begin();
215 for (; iter != _resourcesList.end(); iter++)
217 if ((*iter).second.HostName == hostname)
218 vec.push_back((*iter).first);
224 // --- Search for available resources sorted by priority
225 MapOfParserResourcesType_it i = local_resourcesList.begin();
226 for (; i != local_resourcesList.end(); ++i)
227 vec.push_back(i->first);
229 // --- set wanted parameters
230 ResourceDataToSort::_nbOfProcWanted = params.nb_proc;
231 ResourceDataToSort::_nbOfNodesWanted = params.nb_node;
232 ResourceDataToSort::_nbOfProcPerNodeWanted = params.nb_proc_per_node;
233 ResourceDataToSort::_CPUFreqMHzWanted = params.cpu_clock;
234 ResourceDataToSort::_memInMBWanted = params.mem_mb;
238 std::list<ResourceDataToSort> li;
239 std::vector<std::string>::iterator iter = vec.begin();
240 for (; iter != vec.end(); iter++)
241 li.push_back(local_resourcesList[(*iter)].DataForSort);
245 for (std::list<ResourceDataToSort>::iterator iter2 = li.begin(); iter2 != li.end(); iter2++)
246 vec.push_back((*iter2)._Name);
250 SelectOnlyResourcesWithOS(vec, params.OS.c_str());
253 std::vector<std::string> vec_save(vec);
254 KeepOnlyResourcesWithComponent(vec, params.componentList);
259 // Send an exception if return list is empty...
262 std::string error("[GetFittingResources] ResourcesManager doesn't find any resource that fits to your parameters");
263 throw ResourcesException(error);
269 //=============================================================================
271 * add an entry in the ressources catalog xml file.
273 //=============================================================================
276 ResourcesManager_cpp::AddResourceInCatalog(const ParserResourcesType & new_resource) throw(ResourcesException)
278 // TODO - Add minimal check
279 _resourcesList[new_resource.Name] = new_resource;
282 //=============================================================================
284 * Deletes a resource from the catalog
286 //=============================================================================
288 void ResourcesManager_cpp::DeleteResourceInCatalog(const char * name)
290 MapOfParserResourcesType_it it = _resourcesList.find(name);
291 if (it != _resourcesList.end())
292 _resourcesList.erase(name);
294 RES_INFOS("You try to delete a resource that does not exist... : " << name);
297 //=============================================================================
299 * write the current data in memory in file.
301 //=============================================================================
303 void ResourcesManager_cpp::WriteInXmlFile(std::string xml_file)
305 RES_MESSAGE("WriteInXmlFile : start");
309 _path_resources_it = _path_resources.begin();
310 xml_file = *_path_resources_it;
313 const char* aFilePath = xml_file.c_str();
314 FILE* aFile = fopen(aFilePath, "w");
318 std::cerr << "Error opening file in WriteInXmlFile : " << xml_file << std::endl;
322 xmlDocPtr aDoc = xmlNewDoc(BAD_CAST "1.0");
323 xmlNewDocComment(aDoc, BAD_CAST "ResourcesCatalog");
325 SALOME_ResourcesCatalog_Handler* handler =
326 new SALOME_ResourcesCatalog_Handler(_resourcesList);
327 handler->PrepareDocToXmlFile(aDoc);
330 int isOk = xmlSaveFormatFile(aFilePath, aDoc, 1);
332 std::cerr << "Error while XML file saving : " << xml_file << std::endl;
337 RES_MESSAGE("WriteInXmlFile : WRITING DONE!");
340 //=============================================================================
342 * parse the data type catalog
344 //=============================================================================
346 const MapOfParserResourcesType& ResourcesManager_cpp::ParseXmlFiles()
348 // Parse file only if its modification time is greater than lasttime (last registered modification time)
349 bool to_parse = false;
350 for(_path_resources_it = _path_resources.begin(); _path_resources_it != _path_resources.end(); ++_path_resources_it)
352 struct stat statinfo;
353 int result = stat((*_path_resources_it).c_str(), &statinfo);
356 std::cerr << "Error in method stat for file : " << (*_path_resources_it).c_str() << " no new xml file is parsed" << std::endl;
357 return _resourcesList;
360 if(statinfo.st_mtime > _lasttime)
363 _lasttime = statinfo.st_mtime;
369 _resourcesList.clear();
370 // On parse tous les fichiers
371 for(_path_resources_it = _path_resources.begin(); _path_resources_it != _path_resources.end(); ++_path_resources_it)
373 MapOfParserResourcesType _resourcesList_tmp;
374 MapOfParserResourcesType _resourcesBatchList_tmp;
375 SALOME_ResourcesCatalog_Handler* handler =
376 new SALOME_ResourcesCatalog_Handler(_resourcesList_tmp);
377 const char* aFilePath = (*_path_resources_it).c_str();
378 FILE* aFile = fopen(aFilePath, "r");
382 xmlDocPtr aDoc = xmlReadFile(aFilePath, NULL, 0);
385 handler->ProcessXmlDocument(aDoc);
387 // adding new resources to the file
388 for (MapOfParserResourcesType_it i = _resourcesList_tmp.begin(); i != _resourcesList_tmp.end(); ++i)
390 MapOfParserResourcesType_it j = _resourcesList.find(i->first);
391 if (j == _resourcesList.end())
393 _resourcesList[i->first] = i->second;
397 std::cerr << "ParseXmlFiles Warning, two resources with the same name were found, taking the first declaration : " << i->first << std::endl;
402 std::cerr << "ResourcesManager_cpp: could not parse file " << aFilePath << std::endl;
408 std::cerr << "ResourcesManager_cpp: file " << aFilePath << " is not readable." << std::endl;
413 return _resourcesList;
416 //=============================================================================
418 * consult the content of the list
420 //=============================================================================
422 const MapOfParserResourcesType& ResourcesManager_cpp::GetList() const
424 return _resourcesList;
427 std::string ResourcesManager_cpp::Find(const std::string& policy, const std::vector<std::string>& listOfResources)
429 if(_resourceManagerMap.count(policy)==0)
430 return _resourceManagerMap[""]->Find(listOfResources, _resourcesList);
431 return _resourceManagerMap[policy]->Find(listOfResources, _resourcesList);
434 //=============================================================================
436 * Gives a sublist of resources with matching OS.
437 * If parameter OS is empty, gives the complete list of resources
439 //=============================================================================
441 ResourcesManager_cpp::SelectOnlyResourcesWithOS(std::vector<std::string>& resources, std::string OS)
445 // a computer list is given : take only resources with OS on those computers
446 std::vector<std::string> vec_tmp = resources;
448 std::vector<std::string>::iterator iter = vec_tmp.begin();
449 for (; iter != vec_tmp.end(); iter++)
451 MapOfParserResourcesType::const_iterator it = _resourcesList.find(*iter);
452 if(it != _resourcesList.end())
453 if ( (*it).second.OS == OS)
454 resources.push_back(*iter);
460 //=============================================================================
462 * Gives a sublist of machines on which the component is known.
464 //=============================================================================
466 ResourcesManager_cpp::KeepOnlyResourcesWithComponent(std::vector<std::string>& resources,
467 const std::vector<std::string>& componentList)
469 std::vector<std::string> kept_resources;
471 std::vector<std::string>::iterator iter = resources.begin();
472 for (; iter != resources.end(); iter++)
474 const std::vector<std::string>& mapOfComponentsOfCurrentHost = _resourcesList[*iter].ComponentsList;
476 bool erasedHost = false;
477 if( mapOfComponentsOfCurrentHost.size() > 0 )
479 for(unsigned int i=0; i<componentList.size(); i++)
481 std::vector<std::string>::const_iterator itt = find(mapOfComponentsOfCurrentHost.begin(),
482 mapOfComponentsOfCurrentHost.end(),
484 if (itt == mapOfComponentsOfCurrentHost.end())
492 kept_resources.push_back(*iter);
494 resources=kept_resources;
499 ResourcesManager_cpp::GetResourcesDescr(const std::string & name)
501 if (_resourcesList.find(name) != _resourcesList.end())
502 return _resourcesList[name];
505 std::string error("[GetResourcesDescr] Resource does not exist: ");
507 throw ResourcesException(error);