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
25 * Auteur : Ivan DUTKA-MALEN - EDF R&D
26 * Mail : mailto:ivan.dutka-malen@der.edf.fr
27 * Date : Fri Nov 14 11:00:39 2003
37 #include "Batch_Constants.hxx"
38 #include "Batch_Job_PBS.hxx"
43 // Ajoute un element (name,resource,value) a la liste chainee d'attributs + operateur
44 void Job_PBS::setResourceAttributeOP(struct attropl ** attr_list, const char * attr_name, const char * attr_resource, const char * attr_value)
46 // L'element (name,resource,value) existe-t-il deja ? si oui ptr != 0
47 struct attropl * ptr = findResourceAttributeOP(*attr_list, attr_name, attr_resource);
49 if (!ptr) { // L'element n'existe pas, il faut le creer
50 if ((ptr = lastAttributeOP(*attr_list))) { // la liste n'est pas vide
51 ptr->next = new struct attropl;
55 } else { // la liste est completement vide
56 ptr = *attr_list = new struct attropl;
60 // On remplit les champs (name,resource,value)
61 ptr->name = new char[strlen(attr_name) + 1];
62 strncpy(ptr->name, attr_name, strlen(attr_name));
63 ptr->name[strlen(attr_name)] = 0;
65 ptr->resource = new char[strlen(attr_resource) + 1];
66 strncpy(ptr->resource, attr_resource, strlen(attr_resource));
67 ptr->resource[strlen(attr_resource)] = 0;
69 ptr->value = new char[strlen(attr_value) + 1];
70 strncpy(ptr->value, attr_value, strlen(attr_value));
71 ptr->value[strlen(attr_value)] = 0;
73 } else { // L'attribut existe, on change sa valeur
74 delete[] ptr->value; // On efface la valeur precedente
75 ptr->value = new char[strlen(attr_value) + 1];
76 strncpy(ptr->value, attr_value, strlen(attr_value));
77 ptr->value[strlen(attr_value)] = 0;
83 // Recherche un element (name,resource,value) dans la liste chainee d'attributs + operateur
84 struct attropl * Job_PBS::findResourceAttributeOP(struct attropl * attr_list, const char * attr_name, const char * attr_resource)
86 // On parcoure la liste chainee pour trouver l'element dont les champs name et resource coincident
87 struct attropl * ptr = attr_list;
89 if (!strcmp(ptr->name, attr_name) && !strcmp(ptr->resource, attr_resource)) break;
96 // Recherche le dernier element de la liste chainee d'attributs + operateur
97 struct attropl * Job_PBS::lastAttributeOP(struct attropl * attr_list)
99 struct attropl * ptr = attr_list;
100 while (ptr && ptr->next) {
107 // Convertit un objet Parametre en liste chainee d'attributs + operateur
108 struct attropl * Job_PBS::ParametreToAttributeOPList(struct attropl ** _p_attr_list, Parametre & P)
110 Parametre::iterator it;
112 for(it=P.begin(); it!=P.end(); it++) {
113 if ( (*it).first == ACCOUNT ) {
114 st_second = (*it).second.str();
115 setResourceAttributeOP(_p_attr_list, ATTR_A, "", st_second.c_str());
118 } else if ( (*it).first == CHECKPOINT ) {
119 setResourceAttributeOP(_p_attr_list, ATTR_c, "", "u");
122 } else if ( (*it).first == CKPTINTERVAL ) {
125 } else if ( (*it).first == EXECUTABLE ) {
128 } else if ( (*it).first == HOLD ) {
129 if (static_cast< long >((*it).second))
130 setResourceAttributeOP(_p_attr_list, ATTR_h, "", USER_HOLD);
132 setResourceAttributeOP(_p_attr_list, ATTR_h, "", NO_HOLD);
134 } else if ( (*it).first == INFILE ) {
135 Versatile V = (*it).second;
136 Versatile::iterator Vit;
141 for(Vit=V.begin(); Vit!=V.end(); Vit++, sep=",") {
142 CoupleType cpt = *static_cast< CoupleType * >(*Vit);
144 string local = cp.getLocal();
145 string remote = cp.getRemote();
147 // ATTENTION : les notions de fichier "local" ou "remote" sont inverses de celle de PBS qui a un point de vue serveur et non pas utilisateur
148 stagein += sep + remote + "@" + local;
152 setResourceAttributeOP(_p_attr_list, ATTR_stagein, "", stagein.c_str());
155 } else if ( (*it).first == MAIL ) {
156 st_second = (*it).second.str();
157 setResourceAttributeOP(_p_attr_list, ATTR_M, "", st_second.c_str());
159 } else if ( (*it).first == MAXCPUTIME ) {
161 long secondes = (*it).second;
162 long heures = secondes / 3600L;
163 long minutes = (secondes - 3600L * heures) / 60L;
164 secondes = secondes % 60L;
165 sprintf(attr_value, "%02ld:%02ld:%02ld", heures, minutes, secondes);
167 setResourceAttributeOP(_p_attr_list, ATTR_l, "cput", attr_value);
170 } else if ( (*it).first == MAXDISKSIZE ) {
172 } else if ( (*it).first == MAXRAMSIZE ) {
174 } else if ( (*it).first == MAXWALLTIME ) {
176 long minutes = (*it).second;
177 long heures = minutes / 60L;
178 minutes -= 60L * heures;
179 sprintf(attr_value, "%02ld:%02ld:00", heures, minutes);
181 setResourceAttributeOP(_p_attr_list, ATTR_l, "walltime", attr_value);
184 } else if ( (*it).first == NAME ) {
185 st_second = (*it).second.str();
186 setResourceAttributeOP(_p_attr_list, ATTR_N, "", st_second.c_str());
189 } else if ( (*it).first == OUTFILE ) {
190 Versatile V = (*it).second;
191 Versatile::iterator Vit;
196 for(Vit=V.begin(); Vit!=V.end(); Vit++, sep=",") {
197 CoupleType cpt = *static_cast< CoupleType * >(*Vit);
199 string local = cp.getLocal();
200 string remote = cp.getRemote();
202 if (remote == "stdout")
203 setResourceAttributeOP(_p_attr_list, ATTR_o, "", local.c_str());
205 else if (remote == "stderr")
206 setResourceAttributeOP(_p_attr_list, ATTR_e, "", local.c_str());
209 // ATTENTION : les notions de fichier "local" ou "remote" sont inverses de celle de PBS qui a un point de vue serveur et non pas utilisateur
210 stageout += sep + remote + "@" + local;
214 setResourceAttributeOP(_p_attr_list, ATTR_stageout, "", stageout.c_str());
216 } else if ( (*it).first == QUEUE ) {
219 } else if ( (*it).first == STARTTIME ) {
221 } else if ( (*it).first == TMPDIR ) {
223 } else if ( (*it).first == USER ) {
224 st_second = (*it).second.str();
225 setResourceAttributeOP(_p_attr_list, ATTR_u, "", st_second.c_str());
229 return *_p_attr_list;
233 // Convertit un objet Environnement en liste chainee d'attributs + operateur
234 struct attropl * Job_PBS::EnvironnementToAttributeOPList(struct attropl ** _p_attr_list, Environnement & E)
236 Environnement::iterator it;
237 for(it=E.begin(); it!=E.end(); it++) {
238 setResourceAttributeOP(_p_attr_list, ATTR_v, (*it).first.c_str(), ( (*it).first + "=" + (*it).second ).c_str());
240 return *_p_attr_list;
244 // Ajoute les variables d'environnement presentes dans tout job PBS
245 void Job_PBS::addPBSEnvironnement(Environnement & E)
250 if (c) E["PBS_O_HOME"] = c;
253 if (c) E["PBS_O_LANG"] = c;
255 c = getenv("LOGNAME");
256 if (c) E["PBS_O_LOGNAME"] = c;
259 if (c) E["PBS_O_PATH"] = c;
261 c = getenv("LD_LIBRARY_PATH");
262 if (c) E["PBS_O_LD_LIBRARY_PATH"] = c;
265 if (c) E["PBS_O_MAIL"] = c;
268 if (c) E["PBS_O_SHELL"] = c;
271 if (c) E["PBS_O_TZ"] = c;
273 /* Recuperation du working directory */
278 if (buf) delete[] buf;
279 buf = new char[size];
280 rc = getcwd(buf, size);
283 E["PBS_O_WORKDIR"] = buf;
288 // Ajoute un element (name,resource,value) a la liste chainee d'attributs
289 void Job_PBS::setResourceAttribute(struct attrl ** attr_list, const char * attr_name, const char * attr_resource, const char * attr_value)
291 // L'element (name,resource,value) existe-t-il deja ? si oui ptr != 0
292 struct attrl * ptr = findResourceAttribute(*attr_list, attr_name, attr_resource);
294 if (!ptr) { // L'attribut n'existe pas, il faut le creer
295 if ((ptr = lastAttribute(*attr_list))) { // la liste n'est pas vide
296 ptr->next = new struct attrl;
300 } else { // la liste est completement vide
301 ptr = *attr_list = new struct attrl;
305 // On remplit les champs (name,resource,value)
306 ptr->name = new char[strlen(attr_name) + 1];
307 strncpy(ptr->name, attr_name, strlen(attr_name));
308 ptr->name[strlen(attr_name)] = 0;
310 ptr->resource = new char[strlen(attr_resource) + 1];
311 strncpy(ptr->resource, attr_resource, strlen(attr_resource));
312 ptr->resource[strlen(attr_resource)] = 0;
314 ptr->value = new char[strlen(attr_value) + 1];
315 strncpy(ptr->value, attr_value, strlen(attr_value));
316 ptr->value[strlen(attr_value)] = 0;
318 } else { // L'attribut existe, on change sa valeur
319 delete[] ptr->value; // On efface la valeur precedente
320 ptr->value = new char[strlen(attr_value) + 1];
321 strncpy(ptr->value, attr_value, strlen(attr_value));
322 ptr->value[strlen(attr_value)] = 0;
327 // Recherche un element (name,resource,value) dans la liste chainee d'attributs
328 struct attrl * Job_PBS::findResourceAttribute(struct attrl * attr_list, const char * attr_name, const char * attr_resource)
330 // On parcoure la liste chainee pour trouver l'element dont les champs name et resource coincident
331 struct attrl * ptr = attr_list;
333 if (!strcmp(ptr->name, attr_name) && !strcmp(ptr->resource, attr_resource)) break;
340 // Recherche le dernier element de la liste chainee d'attributs
341 struct attrl * Job_PBS::lastAttribute(struct attrl * attr_list)
343 struct attrl * ptr = attr_list;
344 while (ptr && ptr->next) {
352 Job_PBS::Job_PBS(const Job & job) : _p_attropl(0), _p_attrl(0), _script(0), _destination(0)
354 Parametre P = job.getParametre();
355 Parametre::iterator it;
357 // On extrait de l'objet Parametre le champ EXECUTABLE qui deviendra le script PBS
358 if ( (it=P.find(EXECUTABLE)) != P.end()) {
359 Versatile V = (*it).second;
360 string st_exe = V.str();
361 const char * exe = st_exe.c_str();
362 int lg = strlen(exe);
363 _script = new char[lg + 1];
364 for (int ii=0; ii<lg+1; ii++) _script[ii] = 0;
365 strcpy(_script, exe);
369 _script = new char[1];
373 // On extrait de l'objet Parametre le champ QUEUE qui deviendra la destination
374 if ( (it=P.find(QUEUE)) != P.end()) {
375 Versatile V = (*it).second;
376 string st_dest = V.str();
377 const char * dest = st_dest.c_str();
378 _destination = new char[strlen(dest) + 2 + 1];
380 strcat(_destination, dest);
381 _destination[strlen(dest)] = 0;
383 _destination = new char[1];
387 // On convertit les objets Parametre et Environnement en liste chainee d'attributs + operateur
388 Environnement E = job.getEnvironnement();
389 addPBSEnvironnement(E);
391 _p_attropl = ParametreToAttributeOPList(&_p_attropl, P);
392 _p_attropl = EnvironnementToAttributeOPList(&_p_attropl, E);
400 // On detruit la liste chainee d'attributs + operateur
401 struct attropl * current_p_attropl = _p_attropl;
402 while (current_p_attropl) {
403 struct attropl * next = current_p_attropl->next;
404 delete[] current_p_attropl->name;
405 delete[] current_p_attropl->resource;
406 delete[] current_p_attropl->value;
407 delete current_p_attropl;
408 current_p_attropl = next;
411 // On detruit la liste chainee d'attributs
412 struct attrl * current_p_attrl = _p_attrl;
413 while (current_p_attrl) {
414 struct attrl * next = current_p_attrl->next;
415 delete[] current_p_attrl->name;
416 delete[] current_p_attrl->resource;
417 delete[] current_p_attrl->value;
418 delete current_p_attrl;
419 current_p_attrl = next;
422 // On detruit les champs alloues
424 delete[] _destination;
429 struct attropl * Job_PBS::getAttributesOP()
435 // Cette methode sert pour les pbs_alter de PBS
436 // Pbs_alter est bugg� par rapport a la specification ers_all.ps car les
437 // variables d'environnement ne sont pas supportees (ATTR_v)
438 struct attrl * Job_PBS::getAttributes()
442 // On remplit la structure attrl a partir de la strucuture attropl
443 // (elles ne different que par le parametre op, mais elles ne sont pas interchangeables
446 struct attropl * current_p_attropl = _p_attropl;
447 while (current_p_attropl) {
448 if (strcmp(current_p_attropl->name, ATTR_v)) // Bug fix for ATTR_v
449 setResourceAttribute(&_p_attrl,
450 current_p_attropl->name,
451 current_p_attropl->resource,
452 current_p_attropl->value);
454 current_p_attropl = current_p_attropl->next;
463 char * Job_PBS::getScript()
469 char * Job_PBS::getDestination()