Merge commit 'b5be6201e00421a59e574a07b3d28cde5defff84'
[foam-extend-4.0.git] / bin / foamEndJob
blob8707ce4eeb8d394bb53a85dcc91ebd21579919ad
1 #!/bin/sh
2 #------------------------------------------------------------------------------
3 # ========= |
4 # \\ / F ield | foam-extend: Open Source CFD
5 # \\ / O peration | Version: 4.0
6 # \\ / A nd | Web: http://www.foam-extend.org
7 # \\/ M anipulation | For copyright notice see file Copyright
8 #------------------------------------------------------------------------------
9 # License
10 # This file is part of foam-extend.
12 # foam-extend is free software: you can redistribute it and/or modify it
13 # under the terms of the GNU General Public License as published by the
14 # Free Software Foundation, either version 3 of the License, or (at your
15 # option) any later version.
17 # foam-extend is distributed in the hope that it will be useful, but
18 # WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 # General Public License for more details.
22 # You should have received a copy of the GNU General Public License
23 # along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
25 # Script
26 # foamEndJob
28 # Description
29 # Ends running job on current machine. Called with root,case,pid.
30 # - checks if pid exists
31 # - modifies controlDict
32 # - waits until
33 # - pid disappeared
34 # - controlDict modified
35 # to restore controlDict
37 #------------------------------------------------------------------------------
39 PROGNAME=`basename $0`
42 #------------------------------------------------------------------------------
44 # Functions
46 #------------------------------------------------------------------------------
48 # getNumberedLine dictionary entry
49 # Prints dictionary entry line + lineno
50 getNumberedLine() {
51 grep -n "^[ \t]*$2[ \t]" $1 | grep -v '^//' | head -1
54 # getLine dictionary entry
55 # Prints dictionary entry line (without lineno)
56 getLine() {
57 getNumberedLine $1 "$2" | sed -e 's/^[^:]*://'
60 # getRawEntry dictionary entry
61 # Prints value of dictionary entry
62 getRawEntry() {
63 getLine $1 "$2" | sed -e "s/^[ \t]*$2[ \t][ \t]*//"
66 # getEntry dictionary entry
67 # Like getRawEntry but strips " and ending ';'
68 getEntry() {
69 getRawEntry $1 "$2" | sed -e 's/^"//' -e 's/;$//' -e 's/"$//'
72 # getKey entryLine
73 # Prints first item on line
74 getKey() {
75 echo "$1" | sed -e 's/[ \t]*\(.*\)[ \t].*/\1/'
79 # setRawEntry dictionary entry newValue
80 # Replaces value of entry
81 setRawEntry() {
82 oldNumLine=`getNumberedLine $1 "$2"`
83 lineNo=`echo "$oldNumLine" | sed -e 's/:.*//'`
84 oldLine=`echo "$oldNumLine" | sed -e 's/^[^:]*://'`
85 oldKey=`getKey "$oldLine"`
86 oldVal=`getRawEntry $1 "$2"`
87 if [ ! "$oldKey" -o ! "$oldVal" -o ! "$oldLine" ]; then
88 echo "setRawStringEntry: entry $2 not found in $1"
89 echo "oldKey=$oldKey"
90 echo "lineNo=$lineNo"
91 echo "oldLine=$oldLine"
92 exit 1
94 #echo "oldKey=$oldKey"
95 #echo "lineNo=$lineNo"
96 #echo "oldLine=$oldLine"
97 #echo "oldVal=$oldVal"
98 mv $1 ${1}_tmp
99 sed -e "${lineNo}s/ ${oldVal}/ $3;/" ${1}_tmp > $1
100 rm -f ${1}_tmp
105 # like getEntry but returns true if boolean is logical true
106 getBoolEntry()
108 val=`getEntry $1 $2`
109 case "$val" in
110 'yes')
111 return 0
113 'no')
114 return 123
116 'true')
117 return 0
119 'false')
120 return 123
123 return 0
126 return 123
129 echo "$PROGNAME : getBoolEntry : Illegal boolean value $val in dictionary $1"
130 exit 1
132 esac
135 # newerFile file1 file2
136 newerFile() {
137 latest=`ls -1 -t $1 $2 2> /dev/null | head -1`
138 if [ "$latest" = $1 ]; then
139 return 0
140 else
141 return 1
145 # processExists pid
146 # Returns true if pid exists.
147 processExists() {
148 ps -u $LOGNAME -o 'pid' | fgrep $1 >/dev/null
151 printUsage() {
152 cat << USAGELABEL
153 Usage: $PROGNAME [-n] <root> <case> <pid>
155 $PROGNAME -c <root> <case>
157 Tries to end running Foam application at next write or at next time
158 step (-n option). It needs runTimeModifiable switched on in the
159 controlDict. It changes stopAt in the controlDict and waits for the job to
160 finish. Restores original controlDict if
161 - job has finished
162 - controlDict gets modified (by user)
163 - $PROGNAME gets killed.
165 The -c option clears any outstanding $PROGNAME for the case.
167 USAGELABEL
171 # Restore controlDict and clean up
172 restoreDict() {
173 trap 2 3 15
175 echo "$PROGNAME : Restoring controlDict from controlDict_bak."
176 if [ -r ${controlDict}_bak ]; then
177 cp ${controlDict}_bak $controlDict
180 rm -f $pidFile
182 echo "$PROGNAME : Exiting."
183 exit 0
187 #------------------------------------------------------------------------------
189 # Main
191 #------------------------------------------------------------------------------
193 ARCH=`uname -s`
195 #-- Force standards behaving ps
196 # Get info on all $USER processes
197 case $ARCH in
198 HP-UX*)
199 UNIX95=a; export UNIX95
201 IRIX*)
202 _XPG=1; export _XPG
204 esac
208 # Initial checks
210 if [ $# -lt 3 ]; then
211 printUsage
212 exit 1
214 STOPNOW=''
215 if [ $1 = '-n' ]; then
216 STOPNOW='yes'
217 shift
219 CLEAR=''
220 if [ $1 = '-c' ]; then
221 CLEAR='yes'
222 shift
223 if [ $# -ne 2 ]; then
224 printUsage
225 exit 1
227 ROOT=$1
228 CASE=$2
229 else
230 if [ $# -ne 3 ]; then
231 printUsage
232 exit 1
234 ROOT=$1
235 CASE=$2
236 PID=$3
238 CASE=`echo $CASE | sed -e 's!/.*!!'` #strip of processorXXX ending
240 #- Pid actually running
241 if [ ! "$CLEAR" ]; then
242 processExists $PID
243 if [ $? -ne 0 ] ;then
244 echo "$PROGNAME : process $PID not running."
245 exit 1
249 #- case directory writeable
250 if [ ! -w $ROOT/$CASE ]; then
251 echo "$PROGNAME : $ROOT/$CASE is not writeable."
252 exit 1
255 #- Controldict writeable
256 controlDict=$ROOT/$CASE/system/controlDict
257 if [ ! -w $controlDict ]; then
258 echo "$PROGNAME : $controlDict is not writeable."
259 exit 1
262 #- runTimeModifiable
263 getBoolEntry $controlDict 'runTimeModifiable'
264 if [ $? -ne 0 ]; then
265 echo "$PROGNAME : runTimeModifiable not true in dictionary $controlDict."
266 exit 1
270 #- Check if another foamEndJob running
272 if [ "$CLEAR" ]; then
273 pidFiles=`ls $ROOT/$CASE/.foamEndJob* 2>/dev/null`
274 for pidFile in $pidFiles
276 pid=`cat $pidFile`
277 if [ "$pid" ]; then
278 echo "$PROGNAME : found $PROGNAME (pid $pid) for Foam process"
279 echo " root: $ROOT"
280 echo " case: $CASE"
281 echo "$PROGNAME : Killing $PROGNAME (pid $pid)."
282 kill $pid
283 rm -f $pidFile
285 done
286 exit 0
289 pidFile=$ROOT/$CASE/.foamEndJob${PID}
290 if [ -f $pidFile ]; then
291 pid=`cat $pidFile`
292 if [ "$pid" ]; then
293 processExists $pid
294 if [ $? -eq 0 ] ;then
295 echo "$PROGNAME : found running $PROGNAME (pid $pid) for Foam process"
296 echo " root: $ROOT"
297 echo " case: $CASE"
298 echo " pid : $PID"
299 echo " lock: $pidFile"
300 echo "Remove the lock if this is not the case."
301 exit 1
306 # Mark with my pid
307 echo $$ > $pidFile
310 #- Get controlDict entries
314 #- startTime
315 startTime=`getEntry $controlDict 'startTime'`
316 if [ ! "$startTime" ]; then
317 echo "$PROGNAME : startTime not set in dictionary $controlDict."
318 exit 1
321 #- Write interval
322 writeInterval=`getEntry $controlDict 'writeInterval'`
323 if [ ! "$writeInterval" ]; then
324 echo "$PROGNAME : writeInterval not set in dictionary $controlDict."
325 exit 1
328 #- stopAt
329 stopAt=`getEntry $controlDict 'stopAt'`
330 if [ ! "$stopAt" ]; then
331 echo "$PROGNAME : stopAt not set in dictionary $controlDict."
332 exit 1
335 #- endTime
336 endTime=`getEntry $controlDict 'endTime'`
337 if [ ! "$endTime" ]; then
338 echo "$PROGNAME : endTime not set in dictionary $controlDict."
339 exit 1
343 echo "$PROGNAME : Read from controlDict:"
344 echo " controlDict : $controlDict"
345 echo " writeInterval : $writeInterval"
346 #echo " startTime : $startTime"
347 echo " stopAt : $stopAt"
348 #echo " endTime : $endTime"
350 echo "$PROGNAME : Making backup of controlDict to controlDict_bak"
351 cp $controlDict ${controlDict}_bak
352 #- Set up handler to restore controlDict
353 trap restoreDict 2 3 15
355 if [ "$STOPNOW" ]; then
356 setRawEntry $controlDict 'stopAt' 'nextWrite'
357 setRawEntry $controlDict 'writeInterval' '1'
359 echo "$PROGNAME : Changed in controlDict:"
360 echo " `getLine $controlDict 'stopAt'`"
361 echo " `getLine $controlDict 'writeInterval'`"
362 else
363 setRawEntry $controlDict 'stopAt' 'nextWrite'
365 echo "$PROGNAME : Changed in controlDict:"
366 echo " `getLine $controlDict 'stopAt'`"
371 #- Just to make sure time has changed
372 touch ${controlDict}
374 sleep 5
376 #- Give bak a later date
377 touch ${controlDict}_bak
379 #- Loop a while to give NFS time to update
380 if newerFile ${controlDict} ${controlDict}_bak; then
381 echo "$PROGNAME : controlDict newer than controlDict_bak."
382 echo "$PROGNAME : Waiting for file dates to get updated."
384 iter=0
385 while newerFile ${controlDict} ${controlDict}_bak
387 if [ $iter -ge 120 ]; then
388 #- 120*5 sec = 10 mins passed. Give up
389 echo "$PROGNAME : File date not yet ok after 10 mins. Giving up."
390 break
392 #- Give _bak a later time
393 touch ${controlDict}_bak
395 #- Give nfs some time to update time on controlDict.
396 sleep 5
398 iter=`expr $iter + 1`
399 done
403 #- Start waiting until:
404 # - pid finished. Restore controlDict.
405 # - controlDict modified. No restore.
406 # - controlDict_bak removed. No restore.
408 echo "$PROGNAME : Waiting for Foam job $PID to finish ..."
410 while true
412 sleep 5
414 if [ ! -r ${controlDict}_bak ]; then
415 echo "$PROGNAME : ${controlDict}_bak dissappeared. Exiting without restore."
416 exit 1
419 if newerFile ${controlDict} ${controlDict}_bak; then
420 echo "$PROGNAME : ${controlDict} modified externally. Exiting without restore."
421 exit 0
424 processExists $PID
425 if [ $? -ne 0 ] ;then
426 #- Job finished
427 break
429 #echo "Foam job $PID still running ..."
430 done
432 #- Dictionary restore
433 restoreDict
435 #------------------------------------------------------------------------------