1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 * Auteur : Ivan DUTKA-MALEN - EDF R&D
24 * Mail : mailto:ivan.dutka-malen@der.edf.fr
25 * Date : Fri Nov 14 11:00:39 2003
33 #include "Batch_Job_PBS.hxx"
38 // Ajoute un element (name,resource,value) a la liste chainee d'attributs + operateur
39 void Job_PBS::setResourceAttributeOP(struct attropl ** attr_list, const char * attr_name, const char * attr_resource, const char * attr_value)
41 // L'element (name,resource,value) existe-t-il deja ? si oui ptr != 0
42 struct attropl * ptr = findResourceAttributeOP(*attr_list, attr_name, attr_resource);
44 if (!ptr) { // L'element n'existe pas, il faut le creer
45 if (ptr = lastAttributeOP(*attr_list)) { // la liste n'est pas vide
46 ptr->next = new struct attropl;
50 } else { // la liste est completement vide
51 ptr = *attr_list = new struct attropl;
55 // On remplit les champs (name,resource,value)
56 ptr->name = new char[strlen(attr_name) + 1];
57 strncpy(ptr->name, attr_name, strlen(attr_name));
58 ptr->name[strlen(attr_name)] = 0;
60 ptr->resource = new char[strlen(attr_resource) + 1];
61 strncpy(ptr->resource, attr_resource, strlen(attr_resource));
62 ptr->resource[strlen(attr_resource)] = 0;
64 ptr->value = new char[strlen(attr_value) + 1];
65 strncpy(ptr->value, attr_value, strlen(attr_value));
66 ptr->value[strlen(attr_value)] = 0;
68 } else { // L'attribut existe, on change sa valeur
69 delete[] ptr->value; // On efface la valeur precedente
70 ptr->value = new char[strlen(attr_value) + 1];
71 strncpy(ptr->value, attr_value, strlen(attr_value));
72 ptr->value[strlen(attr_value)] = 0;
78 // Recherche un element (name,resource,value) dans la liste chainee d'attributs + operateur
79 struct attropl * Job_PBS::findResourceAttributeOP(struct attropl * attr_list, const char * attr_name, const char * attr_resource)
81 // On parcoure la liste chainee pour trouver l'element dont les champs name et resource coincident
82 struct attropl * ptr = attr_list;
84 if (!strcmp(ptr->name, attr_name) && !strcmp(ptr->resource, attr_resource)) break;
91 // Recherche le dernier element de la liste chainee d'attributs + operateur
92 struct attropl * Job_PBS::lastAttributeOP(struct attropl * attr_list)
94 struct attropl * ptr = attr_list;
95 while (ptr && ptr->next) {
102 // Convertit un objet Parametre en liste chainee d'attributs + operateur
103 struct attropl * Job_PBS::ParametreToAttributeOPList(struct attropl ** _p_attr_list, Parametre & P)
105 Parametre::iterator it;
107 for(it=P.begin(); it!=P.end(); it++) {
108 if ( (*it).first == ACCOUNT ) {
109 st_second = (*it).second.str();
110 setResourceAttributeOP(_p_attr_list, ATTR_A, "", st_second.c_str());
113 } else if ( (*it).first == CHECKPOINT ) {
114 setResourceAttributeOP(_p_attr_list, ATTR_c, "", "u");
117 } else if ( (*it).first == CKPTINTERVAL ) {
120 } else if ( (*it).first == EXECUTABLE ) {
123 } else if ( (*it).first == HOLD ) {
124 if (static_cast< long >((*it).second))
125 setResourceAttributeOP(_p_attr_list, ATTR_h, "", USER_HOLD);
127 setResourceAttributeOP(_p_attr_list, ATTR_h, "", NO_HOLD);
129 } else if ( (*it).first == INFILE ) {
130 Versatile V = (*it).second;
131 Versatile::iterator Vit;
136 for(Vit=V.begin(); Vit!=V.end(); Vit++, sep=",") {
137 CoupleType cpt = *static_cast< CoupleType * >(*Vit);
139 string local = cp.getLocal();
140 string remote = cp.getRemote();
142 // 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
143 stagein += sep + remote + "@" + local;
147 setResourceAttributeOP(_p_attr_list, ATTR_stagein, "", stagein.c_str());
150 } else if ( (*it).first == MAIL ) {
151 st_second = (*it).second.str();
152 setResourceAttributeOP(_p_attr_list, ATTR_M, "", st_second.c_str());
154 } else if ( (*it).first == MAXCPUTIME ) {
156 long secondes = (*it).second;
157 long heures = secondes / 3600L;
158 long minutes = (secondes - 3600L * heures) / 60L;
159 secondes = secondes % 60L;
160 sprintf(attr_value, "%02ld:%02ld:%02ld", heures, minutes, secondes);
162 setResourceAttributeOP(_p_attr_list, ATTR_l, "cput", attr_value);
165 } else if ( (*it).first == MAXDISKSIZE ) {
167 } else if ( (*it).first == MAXRAMSIZE ) {
169 } else if ( (*it).first == MAXWALLTIME ) {
171 long secondes = (*it).second;
172 long heures = secondes / 3600L;
173 long minutes = (secondes - 3600L * heures) / 60L;
174 secondes = secondes % 60L;
175 sprintf(attr_value, "%02ld:%02ld:%02ld", heures, minutes, secondes);
177 setResourceAttributeOP(_p_attr_list, ATTR_l, "walltime", attr_value);
180 } else if ( (*it).first == NAME ) {
181 st_second = (*it).second.str();
182 setResourceAttributeOP(_p_attr_list, ATTR_N, "", st_second.c_str());
185 } else if ( (*it).first == OUTFILE ) {
186 Versatile V = (*it).second;
187 Versatile::iterator Vit;
192 for(Vit=V.begin(); Vit!=V.end(); Vit++, sep=",") {
193 CoupleType cpt = *static_cast< CoupleType * >(*Vit);
195 string local = cp.getLocal();
196 string remote = cp.getRemote();
198 if (remote == "stdout")
199 setResourceAttributeOP(_p_attr_list, ATTR_o, "", local.c_str());
201 else if (remote == "stderr")
202 setResourceAttributeOP(_p_attr_list, ATTR_e, "", local.c_str());
205 // 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
206 stageout += sep + remote + "@" + local;
210 setResourceAttributeOP(_p_attr_list, ATTR_stageout, "", stageout.c_str());
212 } else if ( (*it).first == QUEUE ) {
215 } else if ( (*it).first == STARTTIME ) {
217 } else if ( (*it).first == TMPDIR ) {
219 } else if ( (*it).first == USER ) {
220 st_second = (*it).second.str();
221 setResourceAttributeOP(_p_attr_list, ATTR_u, "", st_second.c_str());
225 return *_p_attr_list;
229 // Convertit un objet Environnement en liste chainee d'attributs + operateur
230 struct attropl * Job_PBS::EnvironnementToAttributeOPList(struct attropl ** _p_attr_list, Environnement & E)
232 Environnement::iterator it;
233 for(it=E.begin(); it!=E.end(); it++) {
234 setResourceAttributeOP(_p_attr_list, ATTR_v, (*it).first.c_str(), ( (*it).first + "=" + (*it).second ).c_str());
236 return *_p_attr_list;
240 // Ajoute les variables d'environnement presentes dans tout job PBS
241 void Job_PBS::addPBSEnvironnement(Environnement & E)
246 if (c) E["PBS_O_HOME"] = c;
249 if (c) E["PBS_O_LANG"] = c;
251 c = getenv("LOGNAME");
252 if (c) E["PBS_O_LOGNAME"] = c;
255 if (c) E["PBS_O_PATH"] = c;
257 c = getenv("LD_LIBRARY_PATH");
258 if (c) E["PBS_O_LD_LIBRARY_PATH"] = c;
261 if (c) E["PBS_O_MAIL"] = c;
264 if (c) E["PBS_O_SHELL"] = c;
267 if (c) E["PBS_O_TZ"] = c;
269 /* Recuperation du working directory */
274 if (buf) delete[] buf;
275 buf = new char[size];
276 rc = getcwd(buf, size);
279 E["PBS_O_WORKDIR"] = buf;
284 // Ajoute un element (name,resource,value) a la liste chainee d'attributs
285 void Job_PBS::setResourceAttribute(struct attrl ** attr_list, const char * attr_name, const char * attr_resource, const char * attr_value)
287 // L'element (name,resource,value) existe-t-il deja ? si oui ptr != 0
288 struct attrl * ptr = findResourceAttribute(*attr_list, attr_name, attr_resource);
290 if (!ptr) { // L'attribut n'existe pas, il faut le creer
291 if (ptr = lastAttribute(*attr_list)) { // la liste n'est pas vide
292 ptr->next = new struct attrl;
296 } else { // la liste est completement vide
297 ptr = *attr_list = new struct attrl;
301 // On remplit les champs (name,resource,value)
302 ptr->name = new char[strlen(attr_name) + 1];
303 strncpy(ptr->name, attr_name, strlen(attr_name));
304 ptr->name[strlen(attr_name)] = 0;
306 ptr->resource = new char[strlen(attr_resource) + 1];
307 strncpy(ptr->resource, attr_resource, strlen(attr_resource));
308 ptr->resource[strlen(attr_resource)] = 0;
310 ptr->value = new char[strlen(attr_value) + 1];
311 strncpy(ptr->value, attr_value, strlen(attr_value));
312 ptr->value[strlen(attr_value)] = 0;
314 } else { // L'attribut existe, on change sa valeur
315 delete[] ptr->value; // On efface la valeur precedente
316 ptr->value = new char[strlen(attr_value) + 1];
317 strncpy(ptr->value, attr_value, strlen(attr_value));
318 ptr->value[strlen(attr_value)] = 0;
323 // Recherche un element (name,resource,value) dans la liste chainee d'attributs
324 struct attrl * Job_PBS::findResourceAttribute(struct attrl * attr_list, const char * attr_name, const char * attr_resource)
326 // On parcoure la liste chainee pour trouver l'element dont les champs name et resource coincident
327 struct attrl * ptr = attr_list;
329 if (!strcmp(ptr->name, attr_name) && !strcmp(ptr->resource, attr_resource)) break;
336 // Recherche le dernier element de la liste chainee d'attributs
337 struct attrl * Job_PBS::lastAttribute(struct attrl * attr_list)
339 struct attrl * ptr = attr_list;
340 while (ptr && ptr->next) {
348 Job_PBS::Job_PBS(const Job & job) : _p_attropl(0), _p_attrl(0), _script(0), _destination(0)
350 Parametre P = job.getParametre();
351 Parametre::iterator it;
353 // On extrait de l'objet Parametre le champ EXECUTABLE qui deviendra le script PBS
354 if ( (it=P.find(EXECUTABLE)) != P.end()) {
355 Versatile V = (*it).second;
356 string st_exe = V.str();
357 const char * exe = st_exe.c_str();
358 int lg = strlen(exe);
359 _script = new char[lg + 1];
360 for (int ii=0; ii<lg+1; ii++) _script[ii] = 0;
361 strcpy(_script, exe);
365 _script = new char[1];
369 // On extrait de l'objet Parametre le champ QUEUE qui deviendra la destination
370 if ( (it=P.find(QUEUE)) != P.end()) {
371 Versatile V = (*it).second;
372 string st_dest = V.str();
373 const char * dest = st_dest.c_str();
374 _destination = new char[strlen(dest) + 2 + 1];
376 strcat(_destination, dest);
377 _destination[strlen(dest)] = 0;
379 _destination = new char[1];
383 // On convertit les objets Parametre et Environnement en liste chainee d'attributs + operateur
384 Environnement E = job.getEnvironnement();
385 addPBSEnvironnement(E);
387 _p_attropl = ParametreToAttributeOPList(&_p_attropl, P);
388 _p_attropl = EnvironnementToAttributeOPList(&_p_attropl, E);
396 // On detruit la liste chainee d'attributs + operateur
397 struct attropl * current_p_attropl = _p_attropl;
398 while (current_p_attropl) {
399 struct attropl * next = current_p_attropl->next;
400 delete[] current_p_attropl->name;
401 delete[] current_p_attropl->resource;
402 delete[] current_p_attropl->value;
403 delete current_p_attropl;
404 current_p_attropl = next;
407 // On detruit la liste chainee d'attributs
408 struct attrl * current_p_attrl = _p_attrl;
409 while (current_p_attrl) {
410 struct attrl * next = current_p_attrl->next;
411 delete[] current_p_attrl->name;
412 delete[] current_p_attrl->resource;
413 delete[] current_p_attrl->value;
414 delete current_p_attrl;
415 current_p_attrl = next;
418 // On detruit les champs alloues
420 delete[] _destination;
425 struct attropl * Job_PBS::getAttributesOP()
431 // Cette methode sert pour les pbs_alter de PBS
432 // Pbs_alter est buggé par rapport a la specification ers_all.ps car les
433 // variables d'environnement ne sont pas supportees (ATTR_v)
434 struct attrl * Job_PBS::getAttributes()
438 // On remplit la structure attrl a partir de la strucuture attropl
439 // (elles ne different que par le parametre op, mais elles ne sont pas interchangeables
442 struct attropl * current_p_attropl = _p_attropl;
443 while (current_p_attropl) {
444 if (strcmp(current_p_attropl->name, ATTR_v)) // Bug fix for ATTR_v
445 setResourceAttribute(&_p_attrl,
446 current_p_attropl->name,
447 current_p_attropl->resource,
448 current_p_attropl->value);
450 current_p_attropl = current_p_attropl->next;
459 char * Job_PBS::getScript()
465 char * Job_PBS::getDestination()