#!/bin/csh
# CVS: $Id$

# Name:   copy-snapshots
# Author: wd (Wolfgang.Dobler@kis.uni-freiburg.de)
# Date:   24-Sep-2002
# Description:
#   Copy snapshots VAR# and TAVG# from /scratch to $PBS_O_WORKDIR (from
#   where the code started).
#     Relies on PBS (and on tcsh)  and is needed on Horseshoe (the Odense
#   cluster).
#     Should better be a Perl script.

set debug = 0
foreach argv_scalar ($argv)
  if (($argv_scalar == "-v") || ($argv_scalar == "--verbose")) then
    set debug = 1          # for debugging output (recommended)
  else if (($argv_scalar == "-1")) then
    set run_only_once = 1  # check only once for files to copy
  else
    set varfile = $argv_scalar
    if ($debug) echo "varfile = <$varfile>"
  endif
end
##
## Set some necessary filesystem variables...
##
set pwd = `pwd`
set targetdir = $pwd/data
set nodelist = (`echo $NODELIST | sed 's/:/ /g'`) # unpack NODELIST
##
## ... and print out their values.
##
if ($debug) then
  echo "SCRATCH_DIR = <$SCRATCH_DIR>"
  echo "targetdir   = <$targetdir>"
  echo "nodelist    = <$nodelist>"
endif
##
## Produce debug output file in data directory
##
if($debug) then
  echo "copy-snapshots: pid=$$ starting" >>! $targetdir/copy-snaps_was_here.log
  echo "copy-snapshots: pid=$$ args=<$*>" >>! $targetdir/copy-snaps_was_here.log
endif
##
## If explicit filename is given, copy that file from local scratch discs
##
if ($?varfile) then
  echo "======================== $varfile ========================"
  foreach node ($nodelist)
    echo "------------------ working on node: $node ----------------------"
##
## Output directories and whereabouts of $varfile at the root processor's
## scratch disc
##
    if ($debug) then
      printf "\n  ##Checking if scratch directory is accessible\n"
      printf "\n$SSH $node ls -ltd $SCRATCH_DIR :\n"
      $SSH $node "ls -ltd $SCRATCH_DIR"
      printf "\n\n  ##Checking for presence of $varfile on scratch disc\n"
      printf "\n$SSH $node ls -ltd $SCRATCH_DIR/proc*/$varfile $SCRATCH_DIR/allprocs/$varfile :\n"
      $SSH $node "ls -ltd $SCRATCH_DIR/proc*/$varfile $SCRATCH_DIR/allprocs/$varfile"
      printf "\n  ##Checking for presence of $varfile in data directory\n"
      printf "\n$SSH $node ls -ltd $targetdir/proc*/$varfile $targetdir/allprocs/$varfile :\n"
      $SSH $node "ls -ltd $targetdir/proc*/$varfile $targetdir/allprocs/$varfile"
      echo
    endif
##
## Copy all $varfile you find (on all nodes) to the data directory
## (not efficient on dual-CPU systems, unless we would delete files
## after copying..)
##
    if ($debug) printf "  ##Copying proc*/$varfile and allprocs/$varfile to data directory\n\n"

    set remcmd = 'cd '"$SCRATCH_DIR"'; for f in `ls proc*/'"$varfile"' allprocs/'"$varfile"' 2> /dev/null`; do echo "Copying '"$SCRATCH_DIR"'/$f to '"$targetdir"'/$f"; cp '"$SCRATCH_DIR"'/$f '"$targetdir"'/$f; done'

    if ($debug) echo "Now running <$SSH $node sh -c $remcmd>"

    $SSH $node sh -c "'$remcmd'"

    if ($debug) then
      printf "\n  ##Checking for changes to $varfile in data directory\n"
      printf "\n$SSH $node ls -ltd $targetdir/proc*/$varfile $targetdir/allprocs/$varfile :\n"
      $SSH $node "ls -ltd $targetdir/proc*/$varfile $targetdir/allprocs/$varfile"
    endif

  end  # loop over nodes
  echo "========================================================"
else
##
## If no explicit filename is given, copy VARN, TIMEAVGN
##
  echo
  echo "=================== VARN, TIMEAVGN ====================="
##
## Check for relevant files at regular intervals
##
  while (1)
    echo
    echo "=========  "`date`"  ========="
##
## Is there something to copy? (It is sufficient to copy once the
## files show up for the master process of this job -- might depend on
## the queuing system etc.)
##
    if { ( (ls $SCRATCH_DIR/proc0/VAR[0-9]*     || \
            ls $SCRATCH_DIR/proc0/TIMEAVG[0-9]* || \
            ls $SCRATCH_DIR/allprocs/VAR[0-9]*  || \
            ls $SCRATCH_DIR/allprocs/TIMEAVG[0-9]* ) >& /dev/null ) } then
##
## Some debug output reporting that copy-snapshots found something to copy
##
      if ($debug) then
        printf "  ##Found something to copy on the root processor's scratch disc\n"
        echo "ls -l $SCRATCH_DIR/proc0/; ls -l $SCRATCH_DIR/allprocs/ :"
        foreach node ($nodelist)
          echo $node
          $SSH $node "ls -l $SCRATCH_DIR/proc*/; ls -l $SCRATCH_DIR/allprocs/"
        end
        if (-e $SCRATCH_DIR/proc0/varN.list) then
          printf "  ##Contents of $SCRATCH_DIR/proc0/varN.list :\n"
          echo `cat $SCRATCH_DIR/proc0/varN.list`
        endif
          if (-e $SCRATCH_DIR/allprocs/varN.list) then
          printf "  ##Contents of $SCRATCH_DIR/allprocs/varN.list :\n"
          echo `cat $SCRATCH_DIR/allprocs/varN.list`
        endif
        printf "\n"
        printf " ##Next copy-snapshots is going to move the filenames found\n"
        printf " ##in proc*/varN.list from all nodes to the data directory.\n"
      endif
##
##  Go to all nodes and copy everything from proc*/varN.list to the
##  data directory (this is the so-called new method for copying snapshots).
##
      foreach node ($nodelist)
        echo "------------------ working on node: $node ----------------------"
##
## Construct remote command that will do approximately the
## following thing (strongly complicated by the pathetic shell
## quoting rules. ceterum censeo: This script should be written
## in Perl):
##
##   for d in `cd $SCRATCH_DIR; ls -d allprocs proc*`; do
##       fdir="$SCRATCH_DIR/$d"
##       for f in `cat $fdir/*.list`; do
##           file=$fdir/$f
##           if [ -e $file ]; then
##               echo "Moving $file to $targetdir/$d/"
##               mv -f $file $targetdir/$d/"
##           fi
##       done
##   done
##
## This runs as a POSIX (Bourne) shell script on the remote
## side, so wo can write a full for(each) loop in one line.
##
        set remcmd = 'for d in `cd "'"$SCRATCH_DIR"'"; ls -d allprocs proc* 2> /dev/null`; do fdir="'"$SCRATCH_DIR"'/$d"; for f in `cat $fdir/*.list 2> /dev/null`; do file=$fdir/$f; if [ -e $file ]; then echo "Moving $file to '"$targetdir"'/$d/"; mv -f $file "'"$targetdir"'/$d/"; fi; done; done;'
        if ($debug) echo "Now running <$SSH $node sh -c $remcmd>"
        $SSH $node sh -c "'$remcmd'"
            echo "--------------------------------------------------------------"
      end

      if (`ps -p $PARENT_PID | fgrep -c $PARENT_PID` <= 0) then
        echo "No parent process (pid $PARENT_PID) -- exiting"
        exit 1
      endif

    else
##
## Output message if no interesting files found
##
      printf "  ##Nothing to copy:\n"
      printf "  ##no {proc0,allprocs}/{VAR,TIMEAVG}[0-9]* at the root processor's scratch disc\n"
    endif
##
## Break infinite while loop if set to check only once for files to copy
##
    if ($?run_only_once) break
##
## Check only every 60 seconds
##
    if (! $?varfile) then
      sleep 60
    endif

  end # while(1)

endif # no input filename given
##
## Finishing output
##
if ($debug) echo "copy-snapshots: done"
echo "------------------------------------------------------ "

#TEST-BEGIN
if($debug) then
  echo "copy-snapshots: pid=$$ finished" >>! $targetdir/copy-snaps_was_here.log
endif
#TEST-END

# End of file copy-snapshots
