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>
34 #include <libxml/parser.h>
38 #define MAX_SIZE_FOR_HOSTNAME 256;
42 static LoadRateManagerFirst first;
43 static LoadRateManagerCycl cycl;
44 static LoadRateManagerAltCycl altcycl;
45 //=============================================================================
49 //=============================================================================
51 ResourcesManager_cpp::
52 ResourcesManager_cpp(const char *xmlFilePath) :
53 _path_resources(xmlFilePath)
55 #if defined(_DEBUG_) || defined(_DEBUG)
56 cerr << "ResourcesManager_cpp constructor" << endl;
58 _resourceManagerMap["first"]=&first;
59 _resourceManagerMap["cycl"]=&cycl;
60 _resourceManagerMap["altcycl"]=&altcycl;
61 _resourceManagerMap["best"]=&altcycl;
62 _resourceManagerMap[""]=&altcycl;
65 //=============================================================================
67 * Standard constructor, parse resource file.
68 * - if ${APPLI} exists in environment,
69 * look for ${HOME}/${APPLI}/CatalogResources.xml
70 * - else look for default:
71 * ${KERNEL_ROOT_DIR}/share/salome/resources/kernel/CatalogResources.xml
72 * - parse XML resource file.
74 //=============================================================================
76 ResourcesManager_cpp::ResourcesManager_cpp() throw(ResourcesException)
78 #if defined(_DEBUG_) || defined(_DEBUG)
79 cerr << "ResourcesManager_cpp constructor" << endl;
81 _resourceManagerMap["first"]=&first;
82 _resourceManagerMap["cycl"]=&cycl;
83 _resourceManagerMap["altcycl"]=&altcycl;
84 _resourceManagerMap["best"]=&altcycl;
85 _resourceManagerMap[""]=&altcycl;
87 _isAppliSalomeDefined = (getenv("APPLI") != 0);
88 if(!getenv("KERNEL_ROOT_DIR"))
89 throw ResourcesException("you must define KERNEL_ROOT_DIR environment variable!!");
91 if (_isAppliSalomeDefined)
93 _path_resources = getenv("HOME");
94 _path_resources += "/";
95 _path_resources += getenv("APPLI");
96 _path_resources += "/CatalogResources.xml";
101 _path_resources = getenv("KERNEL_ROOT_DIR");
102 _path_resources += "/share/salome/resources/kernel/CatalogResources.xml";
106 #if defined(_DEBUG_) || defined(_DEBUG)
107 cerr << "ResourcesManager_cpp constructor end";
111 //=============================================================================
113 * Standard Destructor
115 //=============================================================================
117 ResourcesManager_cpp::~ResourcesManager_cpp()
119 #if defined(_DEBUG_) || defined(_DEBUG)
120 cerr << "ResourcesManager_cpp destructor" << endl;
124 //=============================================================================
125 //! get the list of resource names fitting constraints given by params
127 * If hostname is specified, check if it is local or known in resources catalog.
130 * - select first machines with corresponding OS (all machines if
131 * parameter OS empty),
132 * - then select the sublist of machines on which the component is known
133 * (if the result is empty, that probably means that the inventory of
134 * components is probably not done, so give complete list from previous step)
136 //=============================================================================
138 std::vector<std::string>
139 ResourcesManager_cpp::GetFittingResources(const machineParams& params) throw(ResourcesException)
141 vector <std::string> vec;
145 const char *hostname = params.hostname.c_str();
146 #if defined(_DEBUG_) || defined(_DEBUG)
147 cerr << "GetFittingResources " << hostname << " " << Kernel_Utils::GetHostname().c_str() << endl;
150 if (hostname[0] != '\0'){
152 if ( strcmp(hostname, "localhost") == 0 ||
153 strcmp(hostname, Kernel_Utils::GetHostname().c_str()) == 0 )
155 //#if defined(_DEBUG_) || defined(_DEBUG)
156 // cerr << "ResourcesManager_cpp::GetFittingResources : localhost" << endl;
158 vec.push_back(Kernel_Utils::GetHostname().c_str());
159 //#if defined(_DEBUG_) || defined(_DEBUG)
160 // cerr << "ResourcesManager_cpp::GetFittingResources : " << vec.size() << endl;
164 else if (_resourcesList.find(hostname) != _resourcesList.end())
166 // --- params.hostname is in the list of resources so return it.
167 vec.push_back(hostname);
170 else if (_resourcesBatchList.find(hostname) != _resourcesBatchList.end())
172 // --- params.hostname is in the list of resources so return it.
173 vec.push_back(hostname);
178 // Cas d'un cluster: nombre de noeuds > 1
180 for (map<string, ParserResourcesType>::const_iterator iter = _resourcesList.begin(); iter != _resourcesList.end(); iter++){
181 if( (*iter).second.DataForSort._nbOfNodes > 1 ){
182 if( strncmp(hostname,(*iter).first.c_str(),strlen(hostname)) == 0 ){
183 vec.push_back((*iter).first.c_str());
189 // --- user specified an unknown hostame so notify him.
190 #if defined(_DEBUG_) || defined(_DEBUG)
191 cerr << "ResourcesManager_cpp::GetFittingResources : SALOME_Exception" << endl;
193 throw ResourcesException("unknown host");
199 // --- Search for available resources sorted by priority
200 vec=params.computerList;
202 SelectOnlyResourcesWithOS(vec, params.OS.c_str());
204 KeepOnlyResourcesWithComponent(vec, params.componentList);
206 //if hosts list (vec) is empty, ignore componentList constraint and use only OS constraint
208 SelectOnlyResourcesWithOS(vec, params.OS.c_str());
210 // --- set wanted parameters
211 ResourceDataToSort::_nbOfNodesWanted = params.nb_node;
213 ResourceDataToSort::_nbOfProcPerNodeWanted = params.nb_proc_per_node;
215 ResourceDataToSort::_CPUFreqMHzWanted = params.cpu_clock;
217 ResourceDataToSort::_memInMBWanted = params.mem_mb;
221 list<ResourceDataToSort> li;
223 for (vector<string>::iterator iter = vec.begin();
226 li.push_back(_resourcesList[(*iter)].DataForSort);
232 for (list<ResourceDataToSort>::iterator iter2 = li.begin();
235 vec[i++] = (*iter2)._hostName;
242 //=============================================================================
244 * add an entry in the ressources catalog xml file.
245 * Return 0 if OK (KERNEL found in new resources components) else throw exception
247 //=============================================================================
250 ResourcesManager_cpp::
251 AddResourceInCatalog(const machineParams& paramsOfNewResources,
252 const vector<string>& componentsOnNewResources,
254 const char *userName,
256 AccessProtocolType prot)
257 throw(ResourcesException)
259 vector<string>::const_iterator iter = find(componentsOnNewResources.begin(),
260 componentsOnNewResources.end(),
263 if (iter != componentsOnNewResources.end())
265 ParserResourcesType newElt;
266 newElt.DataForSort._hostName = paramsOfNewResources.hostname;
267 newElt.Alias = alias;
268 newElt.Protocol = prot;
270 newElt.UserName = userName;
271 newElt.ComponentsList = componentsOnNewResources;
272 newElt.OS = paramsOfNewResources.OS;
273 newElt.DataForSort._memInMB = paramsOfNewResources.mem_mb;
274 newElt.DataForSort._CPUFreqMHz = paramsOfNewResources.cpu_clock;
275 newElt.DataForSort._nbOfNodes = paramsOfNewResources.nb_node;
276 newElt.DataForSort._nbOfProcPerNode =
277 paramsOfNewResources.nb_proc_per_node;
278 _resourcesList[newElt.DataForSort._hostName] = newElt;
283 throw ResourcesException("KERNEL is not present in this resource");
286 //=============================================================================
288 * Deletes a resource from the catalog
290 //=============================================================================
292 void ResourcesManager_cpp::DeleteResourceInCatalog(const char *hostname)
294 _resourcesList.erase(hostname);
297 //=============================================================================
299 * write the current data in memory in file.
301 //=============================================================================
303 void ResourcesManager_cpp::WriteInXmlFile()
305 const char* aFilePath = _path_resources.c_str();
307 FILE* aFile = fopen(aFilePath, "w");
311 #if defined(_DEBUG_) || defined(_DEBUG)
312 cerr << "Error opening file !" << endl;
317 xmlDocPtr aDoc = xmlNewDoc(BAD_CAST "1.0");
318 xmlNewDocComment(aDoc, BAD_CAST "ResourcesCatalog");
320 SALOME_ResourcesCatalog_Handler* handler =
321 new SALOME_ResourcesCatalog_Handler(_resourcesList, _resourcesBatchList);
322 handler->PrepareDocToXmlFile(aDoc);
325 #if defined(_DEBUG_) || defined(_DEBUG)
326 int isOk = xmlSaveFile(aFilePath, aDoc);
327 if (!isOk) cerr << "Error while XML file saving." << endl;
329 xmlSaveFile(aFilePath, aDoc);
337 #if defined(_DEBUG_) || defined(_DEBUG)
338 cerr << "WRITING DONE!" << endl;
342 //=============================================================================
344 * parse the data type catalog
346 //=============================================================================
348 const MapOfParserResourcesType& ResourcesManager_cpp::ParseXmlFile()
350 //Parse file only if its modification time is greater than lasttime (last registered modification time)
351 static time_t lasttime=0;
352 struct stat statinfo;
353 int result = stat(_path_resources.c_str(), &statinfo);
354 if (result < 0) return _resourcesList;
355 if(statinfo.st_mtime <= lasttime)
356 return _resourcesList;
357 lasttime=statinfo.st_mtime;
359 SALOME_ResourcesCatalog_Handler* handler =
360 new SALOME_ResourcesCatalog_Handler(_resourcesList, _resourcesBatchList);
362 const char* aFilePath = _path_resources.c_str();
363 FILE* aFile = fopen(aFilePath, "r");
367 xmlDocPtr aDoc = xmlReadFile(aFilePath, NULL, 0);
370 handler->ProcessXmlDocument(aDoc);
371 #if defined(_DEBUG_) || defined(_DEBUG)
373 cerr << "ResourcesManager_cpp: could not parse file "<< aFilePath << endl;
381 #if defined(_DEBUG_) || defined(_DEBUG)
383 cerr << "ResourcesManager_cpp: file "<<aFilePath<<" is not readable." << endl;
388 return _resourcesList;
391 //=============================================================================
393 * consult the content of the list
395 //=============================================================================
397 const MapOfParserResourcesType& ResourcesManager_cpp::GetList() const
399 return _resourcesList;
402 string ResourcesManager_cpp::Find(const std::string& policy, const std::vector<std::string>& listOfMachines)
404 if(_resourceManagerMap.count(policy)==0)
405 return _resourceManagerMap[""]->Find(listOfMachines,_resourcesList);
406 return _resourceManagerMap[policy]->Find(listOfMachines,_resourcesList);
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)
424 //No constraint on computer list : take all known resources with OS
425 map<string, ParserResourcesType>::const_iterator iter;
426 for (iter = _resourcesList.begin(); iter != _resourcesList.end(); iter++)
428 if ( (*iter).second.OS == base || base.size() == 0)
429 hosts.push_back((*iter).first);
434 //a computer list is given : take only resources with OS on those computers
435 vector<string> vec=hosts;
437 vector<string>::iterator iter;
438 for (iter = vec.begin(); iter != vec.end(); iter++)
440 MapOfParserResourcesType::const_iterator it = _resourcesList.find(*iter);
441 if(it != _resourcesList.end())
442 if ( (*it).second.OS == base || base.size() == 0 )
443 hosts.push_back(*iter);
449 //=============================================================================
451 * Gives a sublist of machines on which the component is known.
453 //=============================================================================
455 //Warning need an updated parsed list : _resourcesList
456 void ResourcesManager_cpp::KeepOnlyResourcesWithComponent( vector<string>& hosts, const vector<string>& componentList) const
457 throw(ResourcesException)
459 for (vector<string>::iterator iter = hosts.begin(); iter != hosts.end();)
461 MapOfParserResourcesType::const_iterator it = _resourcesList.find(*iter);
462 const vector<string>& mapOfComponentsOfCurrentHost = (((*it).second).ComponentsList);
464 bool erasedHost = false;
465 if( mapOfComponentsOfCurrentHost.size() > 0 ){
466 for(unsigned int i=0;i<componentList.size();i++){
467 const char* compoi = componentList[i].c_str();
468 vector<string>::const_iterator itt = find(mapOfComponentsOfCurrentHost.begin(),
469 mapOfComponentsOfCurrentHost.end(),
471 if (itt == mapOfComponentsOfCurrentHost.end()){
485 ParserResourcesType ResourcesManager_cpp::GetResourcesList(const std::string& machine)
487 if (_resourcesList.find(machine) != _resourcesList.end())
488 return _resourcesList[machine];
490 return _resourcesBatchList[machine];