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>
37 #include <libxml/parser.h>
41 #define MAX_SIZE_FOR_HOSTNAME 256;
45 static LoadRateManagerFirst first;
46 static LoadRateManagerCycl cycl;
47 static LoadRateManagerAltCycl altcycl;
48 //=============================================================================
52 //=============================================================================
54 ResourcesManager_cpp::
55 ResourcesManager_cpp(const char *xmlFilePath) :
56 _path_resources(xmlFilePath)
58 #if defined(_DEBUG_) || defined(_DEBUG)
59 cerr << "ResourcesManager_cpp constructor" << endl;
61 _resourceManagerMap["first"]=&first;
62 _resourceManagerMap["cycl"]=&cycl;
63 _resourceManagerMap["altcycl"]=&altcycl;
64 _resourceManagerMap["best"]=&altcycl;
65 _resourceManagerMap[""]=&altcycl;
68 //=============================================================================
70 * Standard constructor, parse resource file.
71 * - if ${APPLI} exists in environment,
72 * look for ${HOME}/${APPLI}/CatalogResources.xml
73 * - else look for default:
74 * ${KERNEL_ROOT_DIR}/share/salome/resources/kernel/CatalogResources.xml
75 * - parse XML resource file.
77 //=============================================================================
79 ResourcesManager_cpp::ResourcesManager_cpp() throw(ResourcesException)
81 #if defined(_DEBUG_) || defined(_DEBUG)
82 cerr << "ResourcesManager_cpp constructor" << endl;
84 _resourceManagerMap["first"]=&first;
85 _resourceManagerMap["cycl"]=&cycl;
86 _resourceManagerMap["altcycl"]=&altcycl;
87 _resourceManagerMap["best"]=&altcycl;
88 _resourceManagerMap[""]=&altcycl;
90 _isAppliSalomeDefined = (getenv("APPLI") != 0);
91 if(!getenv("KERNEL_ROOT_DIR"))
92 throw ResourcesException("you must define KERNEL_ROOT_DIR environment variable!!");
94 if (_isAppliSalomeDefined)
96 _path_resources = getenv("HOME");
97 _path_resources += "/";
98 _path_resources += getenv("APPLI");
99 _path_resources += "/CatalogResources.xml";
104 _path_resources = getenv("KERNEL_ROOT_DIR");
105 _path_resources += "/share/salome/resources/kernel/CatalogResources.xml";
109 #if defined(_DEBUG_) || defined(_DEBUG)
110 cerr << "ResourcesManager_cpp constructor end";
114 //=============================================================================
116 * Standard Destructor
118 //=============================================================================
120 ResourcesManager_cpp::~ResourcesManager_cpp()
122 #if defined(_DEBUG_) || defined(_DEBUG)
123 cerr << "ResourcesManager_cpp destructor" << endl;
127 //=============================================================================
128 //! get the list of resource names fitting constraints given by params
130 * If hostname is specified, check if it is local or known in resources catalog.
133 * - select first machines with corresponding OS (all machines if
134 * parameter OS empty),
135 * - then select the sublist of machines on which the component is known
136 * (if the result is empty, that probably means that the inventory of
137 * components is probably not done, so give complete list from previous step)
139 //=============================================================================
141 std::vector<std::string>
142 ResourcesManager_cpp::GetFittingResources(const machineParams& params) throw(ResourcesException)
144 vector <std::string> vec;
148 const char *hostname = params.hostname.c_str();
149 #if defined(_DEBUG_) || defined(_DEBUG)
150 cerr << "GetFittingResources " << hostname << " " << Kernel_Utils::GetHostname().c_str() << endl;
153 if (hostname[0] != '\0'){
155 if ( strcmp(hostname, "localhost") == 0 ||
156 strcmp(hostname, Kernel_Utils::GetHostname().c_str()) == 0 )
158 //#if defined(_DEBUG_) || defined(_DEBUG)
159 // cerr << "ResourcesManager_cpp::GetFittingResources : localhost" << endl;
161 vec.push_back(Kernel_Utils::GetHostname().c_str());
162 //#if defined(_DEBUG_) || defined(_DEBUG)
163 // cerr << "ResourcesManager_cpp::GetFittingResources : " << vec.size() << endl;
167 else if (_resourcesList.find(hostname) != _resourcesList.end())
169 // --- params.hostname is in the list of resources so return it.
170 vec.push_back(hostname);
173 else if (_resourcesBatchList.find(hostname) != _resourcesBatchList.end())
175 // --- params.hostname is in the list of resources so return it.
176 vec.push_back(hostname);
181 // Cas d'un cluster: nombre de noeuds > 1
183 for (map<string, ParserResourcesType>::const_iterator iter = _resourcesList.begin(); iter != _resourcesList.end(); iter++){
184 if( (*iter).second.DataForSort._nbOfNodes > 1 ){
185 if( strncmp(hostname,(*iter).first.c_str(),strlen(hostname)) == 0 ){
186 vec.push_back((*iter).first.c_str());
192 // --- user specified an unknown hostame so notify him.
193 #if defined(_DEBUG_) || defined(_DEBUG)
194 cerr << "ResourcesManager_cpp::GetFittingResources : SALOME_Exception" << endl;
196 throw ResourcesException("unknown host");
202 // --- Search for available resources sorted by priority
203 vec=params.computerList;
205 SelectOnlyResourcesWithOS(vec, params.OS.c_str());
207 KeepOnlyResourcesWithComponent(vec, params.componentList);
209 //if hosts list (vec) is empty, ignore componentList constraint and use only OS constraint
211 SelectOnlyResourcesWithOS(vec, params.OS.c_str());
213 // --- set wanted parameters
214 ResourceDataToSort::_nbOfNodesWanted = params.nb_node;
216 ResourceDataToSort::_nbOfProcPerNodeWanted = params.nb_proc_per_node;
218 ResourceDataToSort::_CPUFreqMHzWanted = params.cpu_clock;
220 ResourceDataToSort::_memInMBWanted = params.mem_mb;
224 list<ResourceDataToSort> li;
226 for (vector<string>::iterator iter = vec.begin();
229 li.push_back(_resourcesList[(*iter)].DataForSort);
235 for (list<ResourceDataToSort>::iterator iter2 = li.begin();
238 vec[i++] = (*iter2)._hostName;
245 //=============================================================================
247 * add an entry in the ressources catalog xml file.
248 * Return 0 if OK (KERNEL found in new resources components) else throw exception
250 //=============================================================================
253 ResourcesManager_cpp::
254 AddResourceInCatalog(const machineParams& paramsOfNewResources,
255 const vector<string>& componentsOnNewResources,
257 const char *userName,
259 AccessProtocolType prot)
260 throw(ResourcesException)
262 vector<string>::const_iterator iter = find(componentsOnNewResources.begin(),
263 componentsOnNewResources.end(),
266 if (iter != componentsOnNewResources.end())
268 ParserResourcesType newElt;
269 newElt.DataForSort._hostName = paramsOfNewResources.hostname;
270 newElt.Alias = alias;
271 newElt.Protocol = prot;
273 newElt.UserName = userName;
274 newElt.ComponentsList = componentsOnNewResources;
275 newElt.OS = paramsOfNewResources.OS;
276 newElt.DataForSort._memInMB = paramsOfNewResources.mem_mb;
277 newElt.DataForSort._CPUFreqMHz = paramsOfNewResources.cpu_clock;
278 newElt.DataForSort._nbOfNodes = paramsOfNewResources.nb_node;
279 newElt.DataForSort._nbOfProcPerNode =
280 paramsOfNewResources.nb_proc_per_node;
281 _resourcesList[newElt.DataForSort._hostName] = newElt;
286 throw ResourcesException("KERNEL is not present in this resource");
289 //=============================================================================
291 * Deletes a resource from the catalog
293 //=============================================================================
295 void ResourcesManager_cpp::DeleteResourceInCatalog(const char *hostname)
297 _resourcesList.erase(hostname);
300 //=============================================================================
302 * write the current data in memory in file.
304 //=============================================================================
306 void ResourcesManager_cpp::WriteInXmlFile()
308 const char* aFilePath = _path_resources.c_str();
310 FILE* aFile = fopen(aFilePath, "w");
314 #if defined(_DEBUG_) || defined(_DEBUG)
315 cerr << "Error opening file !" << endl;
320 xmlDocPtr aDoc = xmlNewDoc(BAD_CAST "1.0");
321 xmlNewDocComment(aDoc, BAD_CAST "ResourcesCatalog");
323 SALOME_ResourcesCatalog_Handler* handler =
324 new SALOME_ResourcesCatalog_Handler(_resourcesList, _resourcesBatchList);
325 handler->PrepareDocToXmlFile(aDoc);
328 #if defined(_DEBUG_) || defined(_DEBUG)
329 int isOk = xmlSaveFile(aFilePath, aDoc);
330 if (!isOk) cerr << "Error while XML file saving." << endl;
332 xmlSaveFile(aFilePath, aDoc);
340 #if defined(_DEBUG_) || defined(_DEBUG)
341 cerr << "WRITING DONE!" << endl;
345 //=============================================================================
347 * parse the data type catalog
349 //=============================================================================
351 const MapOfParserResourcesType& ResourcesManager_cpp::ParseXmlFile()
353 //Parse file only if its modification time is greater than lasttime (last registered modification time)
354 static time_t lasttime=0;
355 struct stat statinfo;
356 int result = stat(_path_resources.c_str(), &statinfo);
357 if (result < 0) return _resourcesList;
358 if(statinfo.st_mtime <= lasttime)
359 return _resourcesList;
360 lasttime=statinfo.st_mtime;
362 SALOME_ResourcesCatalog_Handler* handler =
363 new SALOME_ResourcesCatalog_Handler(_resourcesList, _resourcesBatchList);
365 const char* aFilePath = _path_resources.c_str();
366 FILE* aFile = fopen(aFilePath, "r");
370 xmlDocPtr aDoc = xmlReadFile(aFilePath, NULL, 0);
373 handler->ProcessXmlDocument(aDoc);
374 #if defined(_DEBUG_) || defined(_DEBUG)
376 cerr << "ResourcesManager_cpp: could not parse file "<< aFilePath << endl;
384 #if defined(_DEBUG_) || defined(_DEBUG)
386 cerr << "ResourcesManager_cpp: file "<<aFilePath<<" is not readable." << endl;
391 return _resourcesList;
394 //=============================================================================
396 * consult the content of the list
398 //=============================================================================
400 const MapOfParserResourcesType& ResourcesManager_cpp::GetList() const
402 return _resourcesList;
405 string ResourcesManager_cpp::Find(const std::string& policy, const std::vector<std::string>& listOfMachines)
407 if(_resourceManagerMap.count(policy)==0)
408 return _resourceManagerMap[""]->Find(listOfMachines,_resourcesList);
409 return _resourceManagerMap[policy]->Find(listOfMachines,_resourcesList);
412 //=============================================================================
414 * Gives a sublist of machines with matching OS.
415 * If parameter OS is empty, gives the complete list of machines
417 //=============================================================================
419 // Warning need an updated parsed list : _resourcesList
420 void ResourcesManager_cpp::SelectOnlyResourcesWithOS( vector<string>& hosts, const char *OS) const
421 throw(ResourcesException)
427 //No constraint on computer list : take all known resources with OS
428 map<string, ParserResourcesType>::const_iterator iter;
429 for (iter = _resourcesList.begin(); iter != _resourcesList.end(); iter++)
431 if ( (*iter).second.OS == base || base.size() == 0)
432 hosts.push_back((*iter).first);
437 //a computer list is given : take only resources with OS on those computers
438 vector<string> vec=hosts;
440 vector<string>::iterator iter;
441 for (iter = vec.begin(); iter != vec.end(); iter++)
443 MapOfParserResourcesType::const_iterator it = _resourcesList.find(*iter);
444 if(it != _resourcesList.end())
445 if ( (*it).second.OS == base || base.size() == 0 )
446 hosts.push_back(*iter);
452 //=============================================================================
454 * Gives a sublist of machines on which the component is known.
456 //=============================================================================
458 //Warning need an updated parsed list : _resourcesList
459 void ResourcesManager_cpp::KeepOnlyResourcesWithComponent( vector<string>& hosts, const vector<string>& componentList) const
460 throw(ResourcesException)
462 for (vector<string>::iterator iter = hosts.begin(); iter != hosts.end();)
464 MapOfParserResourcesType::const_iterator it = _resourcesList.find(*iter);
465 const vector<string>& mapOfComponentsOfCurrentHost = (((*it).second).ComponentsList);
467 bool erasedHost = false;
468 if( mapOfComponentsOfCurrentHost.size() > 0 ){
469 for(unsigned int i=0;i<componentList.size();i++){
470 const char* compoi = componentList[i].c_str();
471 vector<string>::const_iterator itt = find(mapOfComponentsOfCurrentHost.begin(),
472 mapOfComponentsOfCurrentHost.end(),
474 if (itt == mapOfComponentsOfCurrentHost.end()){
488 ParserResourcesType ResourcesManager_cpp::GetResourcesList(const std::string& machine)
490 if (_resourcesList.find(machine) != _resourcesList.end())
491 return _resourcesList[machine];
493 return _resourcesBatchList[machine];