#!/usr/bin/env perl use warnings; use strict; use Cwd; # PERL script to do round-robin uploads to MSS at NCSA # Usage is # NCSAstore.pl # where # destDir is the destination directory on MSS # nodeList is the PBS_NODEFILE # fileList is an "ls -1 --hide-control-chars" list of the # files to be stored my( $destDir, $nodeList, $fileList ); my( $rcs, $rev, $rcsdate ); my( $currDir ); my( @files, @machines ); my( $numFiles, $numMachines ); my( $currFile, $currMachine ); my( $msscommand, $sshcommand ); my( $i, @processList, $childPID ); # Write a welcome $rcs = '$RCSfile: NCSAstore.pl,v $'; $rev = '$Revision: 1.5 $'; $rcsdate = '$Date: 2006/02/17 20:55:56 $'; print "NCSAstore\n"; print "=========\n\n"; print "$rcs\n"; print "$rev\n"; print "$rcsdate\n\n"; # Fetch some arguments $destDir = shift @ARGV || die "No destination directory!\n"; $nodeList = shift @ARGV || die "No node list!\n"; $fileList = shift @ARGV || die "No file lsit!\n"; $currDir = Cwd::getcwd; # Slurp in the machines open( MACHLIST, "<".$nodeList ) || die "Can't open list of machines!\n"; @machines= ; close( MACHLIST ); $numMachines = @machines; # Slurp in the files open( FILELIST, "<".$fileList ) || die "Can't open list of files!\n"; @files = ; close( FILELIST ); $numFiles = @files; print "We are going to attempt to store $numFiles files "; print "using $numMachines machines\n\n"; # Remove CR/LF etc. chomp @files; chomp @machines; # Loop for( $i=0; $i<=$numFiles-1; $i++ ) { # Find the file and machine $currFile = $files[$i]; $currMachine = $machines[$i % $numMachines]; print "Storing $currFile using $currMachine\n"; # Make up the MSS command $msscommand = '"'."cd $destDir , lcd $currDir, put $currFile".'"'; # Make the SSH command $sshcommand = "ssh $currMachine msscmd $msscommand"; # Fork off $childPID = fork(); if( $childPID ) { # This is the parent # Stash the PID away $processList[$i % $numMachines] = $childPID; } else { # This is the child # Run the ssh command after a pause to help # keep the output in order sleep 1; exec( "$sshcommand" ); } # At the end of each pass through the machine list # wait for completion if( $i % $numMachines == $numMachines-1 ) { print "Waiting for completion of current batch: "; print "@processList\n\n"; foreach $childPID ( @processList ) { waitpid( $childPID, 0 ); print "Child $childPID completed\n"; } # Remember to nullify the process list @processList = (); print "Completed this batch\n\n"; } } print "\n\nFinal wait for completion\n"; print "Remaining processes: @processList\n\n"; foreach $childPID ( @processList ) { waitpid( $childPID, 0 ); print "Child $childPID completed\n"; } print "\n\nNCSAstore complete\n\n";