Salome HOME
Copyrights update
[modules/kernel.git] / src / Batch / Batch_Job_LSF.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
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.
8 // 
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.
13 //
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
17 //
18 // See http://www.salome-platform.org/
19 //
20 /*
21  * Job_LSF.cxx : 
22  *
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
26  * Projet : Salome 2
27  *
28  */
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <string.h>
34 #include <vector>
35 #include "Batch_Job_LSF.hxx"
36
37 namespace Batch {
38
39
40   // Constructeur
41   Job_LSF::Job_LSF(const Job & job) : _p_submit(0)
42   {
43     Parametre P = job.getParametre();
44     _p_submit = ParametreToSubmitStruct(P);
45   }
46
47
48   // Destructeur
49   Job_LSF::~Job_LSF()
50   {
51     if (_p_submit) {
52       if (_p_submit->jobName)     delete [] _p_submit->jobName;
53       if (_p_submit->queue)       delete [] _p_submit->queue;
54       if (_p_submit->askedHosts) {
55         delete [] *(_p_submit->askedHosts);
56         delete [] _p_submit->askedHosts;
57       }
58       if (_p_submit->resReq)      delete [] _p_submit->resReq;
59       if (_p_submit->hostSpec)    delete [] _p_submit->hostSpec;
60       if (_p_submit->dependCond)  delete [] _p_submit->dependCond;
61       if (_p_submit->timeEvent)   delete [] _p_submit->timeEvent;
62       if (_p_submit->inFile)      delete [] _p_submit->inFile;
63       if (_p_submit->outFile)     delete [] _p_submit->outFile;
64       if (_p_submit->errFile)     delete [] _p_submit->errFile;
65       if (_p_submit->command)     delete [] _p_submit->command;
66       if (_p_submit->newCommand)  delete [] _p_submit->newCommand;
67       if (_p_submit->chkpntDir)   delete [] _p_submit->chkpntDir;
68       if (_p_submit->xf)          delete [] _p_submit->xf;
69       if (_p_submit->preExecCmd)  delete [] _p_submit->preExecCmd;
70       if (_p_submit->mailUser)    delete [] _p_submit->mailUser;
71       if (_p_submit->projectName) delete [] _p_submit->projectName;
72       if (_p_submit->loginShell)  delete [] _p_submit->loginShell;
73       if (_p_submit->exceptList)  delete [] _p_submit->exceptList;
74       delete _p_submit;
75     }
76   }
77
78
79   // Accesseur
80   struct submit * Job_LSF::getSubmitStruct()
81   {
82     return _p_submit;
83   }
84
85
86   char * Job_LSF::string2char(const string & s)
87   {
88     char * ch = new char [s.size() + 1];
89     memset(ch, 0, s.size() + 1);
90     strncat(ch, s.c_str(), s.size());
91     return ch;
92   }
93
94
95   struct submit * Job_LSF::ParametreToSubmitStruct(const Parametre & P)
96   {
97     if (! _p_submit) _p_submit = new struct submit;
98
99     memset( (void *) _p_submit, 0, sizeof(struct submit));
100
101     struct submit & sub = * _p_submit;
102     sub.options  = 0;
103     sub.options2 = 0;
104
105     sub.beginTime = 0; // job can run as soon as possible (default)
106     sub.termTime  = 0; // job can run as long as it wishes (default)
107
108     sub.numProcessors    = 1; // job can run on one single processor (default)
109     sub.maxNumProcessors = 1; // job can run on one single processor (default)
110
111     for(int i = 0; i< LSF_RLIM_NLIMITS; i++) sub.rLimits[i] = DEFAULT_RLIMIT;
112
113     typedef std::vector< struct xFile > XFTAB;
114     XFTAB xf_tab;
115
116     string st_second;
117     for(Parametre::const_iterator it = P.begin(); it != P.end(); it++) {
118       if ( (*it).first == ACCOUNT ) {
119         sub.options |= SUB_PROJECT_NAME;
120         st_second = (*it).second.str();
121         sub.projectName = string2char(st_second);
122
123       } else if ( (*it).first == CHECKPOINT ) {
124         if (static_cast< long >((*it).second))
125           sub.options |= SUB_CHKPNT_PERIOD;
126         else
127           sub.options &= ~ SUB_CHKPNT_PERIOD;
128
129       } else if ( (*it).first == CKPTINTERVAL ) {
130         sub.chkpntPeriod = static_cast< long >((*it).second);
131
132       } else if ( (*it).first == EXECUTABLE ) {
133         st_second = (*it).second.str();
134         sub.command = string2char(st_second);
135
136       } else if ( (*it).first == EXECUTIONHOST ) {
137         sub.options |= SUB_HOST;
138         if (! sub.numAskedHosts) {
139           sub.numAskedHosts = 1;
140           sub.askedHosts = new char* [1];
141         }
142         st_second = (*it).second.str();
143         sub.askedHosts[0] = string2char(st_second);
144
145       } else if ( (*it).first == HOLD ) {
146         if (static_cast< long >((*it).second))
147           sub.options2 |= SUB2_HOLD;
148         else
149           sub.options2 &= ~ SUB2_HOLD;
150
151       } else if ( (*it).first == INFILE ) {
152         Versatile V = (*it).second;
153         Versatile::iterator Vit;
154
155         for(Vit=V.begin(); Vit!=V.end(); Vit++) {
156           CoupleType cpt  = *static_cast< CoupleType * >(*Vit);
157           Couple cp       = cpt;
158           string local    = cp.getLocal();
159           string remote   = cp.getRemote();
160                                         
161           // 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
162           if (remote == "stdin"){
163             sub.options |= SUB_IN_FILE;
164             sub.inFile = string2char(local);
165
166           } else {
167             struct xFile xf;
168             strncpy(xf.subFn,  local.c_str(),  MAXFILENAMELEN - 1); xf.subFn[MAXFILENAMELEN - 1]  = 0;
169             strncpy(xf.execFn, remote.c_str(), MAXFILENAMELEN - 1); xf.execFn[MAXFILENAMELEN - 1] = 0;
170             xf.options = XF_OP_SUB2EXEC;
171             xf_tab.push_back(xf);
172           }
173         }
174
175       } else if ( (*it).first == MAIL ) {
176         sub.options |= SUB_MAIL_USER;
177         st_second = (*it).second.str();
178         sub.mailUser = string2char(st_second);
179
180       } else if ( (*it).first == MAXCPUTIME ) {
181         sub.rLimits[LSF_RLIMIT_CPU] = static_cast< long >((*it).second);
182
183       } else if ( (*it).first == MAXDISKSIZE ) {
184         sub.rLimits[LSF_RLIMIT_FSIZE] = static_cast< long >((*it).second);
185
186       } else if ( (*it).first == MAXRAMSIZE ) {
187         sub.rLimits[LSF_RLIMIT_SWAP] = static_cast< long >((*it).second);
188
189       } else if ( (*it).first == MAXWALLTIME ) {
190         sub.rLimits[LSF_RLIMIT_RUN] = static_cast< long >((*it).second);
191
192       } else if ( (*it).first == NAME ) {
193         sub.options |= SUB_JOB_NAME;
194         st_second = (*it).second.str();
195         sub.jobName = string2char(st_second);
196
197       } else if ( (*it).first == NBPROC ) {
198         sub.numProcessors    = static_cast< long >((*it).second);
199         sub.maxNumProcessors = static_cast< long >((*it).second);
200
201       } else if ( (*it).first == OUTFILE ) {
202         Versatile V = (*it).second;
203         Versatile::iterator Vit;
204
205         for(Vit=V.begin(); Vit!=V.end(); Vit++) {
206           CoupleType cpt  = *static_cast< CoupleType * >(*Vit);
207           Couple cp       = cpt;
208           string local    = cp.getLocal();
209           string remote   = cp.getRemote();
210                                         
211           // 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
212           if (remote == "stdout"){
213             sub.options |= SUB_OUT_FILE;
214             sub.outFile = string2char(local);
215
216           } else if (remote == "stderr"){
217             sub.options |= SUB_ERR_FILE;
218             sub.errFile = string2char(local);
219
220           } else {
221             struct xFile xf;
222             strncpy(xf.subFn,  local.c_str(),  MAXFILENAMELEN - 1); xf.subFn[MAXFILENAMELEN - 1]  = 0;
223             strncpy(xf.execFn, remote.c_str(), MAXFILENAMELEN - 1); xf.execFn[MAXFILENAMELEN - 1] = 0;
224             xf.options = XF_OP_EXEC2SUB;
225             xf_tab.push_back(xf);
226           }
227         }
228
229
230       } else if ( (*it).first == QUEUE ) {
231         sub.options |= SUB_QUEUE;
232         st_second = (*it).second.str();
233         sub.queue = string2char(st_second);
234
235       } else if ( (*it).first == STARTTIME ) {
236         sub.beginTime = static_cast< long >((*it).second);
237
238       } else if ( (*it).first == TMPDIR ) {
239         // TODO
240
241       } else if ( (*it).first == USER ) {
242         // TODO
243
244       }
245     }
246
247
248     // Transfert de fichiers en entree et sortie
249     sub.options |= SUB_OTHER_FILES;
250     sub.nxf = xf_tab.size();
251     sub.xf = new struct xFile [sub.nxf];
252     int ixf = 0;
253     for(XFTAB::const_iterator it_xf=xf_tab.begin(); it_xf != xf_tab.end(); it_xf++, ixf++)
254       sub.xf[ixf] = *it_xf; // *it_xf == xf_tab[ixf]
255         
256
257     return _p_submit;
258   }
259
260 }