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