# skewSubmit.pl creates a batch file to submit AT jobs for a specified number # of machines, randomized so each job is submitted at a slightly different time. # # Created 1-dec-2000 by fgb. # # General idea: create a hash with an element for each machine. # Get the element total, divide by 2, and assign half of the machines # submit times starting with specified time varying by 1 minute up, and the # other half varying by 1 minute down. require "ctime.pl"; use Net::Ping; use rmtVer; # evil globals: my $bDebug = 0; my $sAppName = "skewSubmit"; my $sCmdFile = ""; my $sDate = &ctime(time); chop $sDate; my $sEvery = ""; my %jobs = (); my $sLocalMachine = Win32::NodeName; my $sMachine = ""; my $sMachineFile = ""; my $sNow = time(); my $sRuntime; my $nRunHh = 0; my $nRunMm = 0; my $sSubmitFile = "skewSubmitJobs.cmd"; my $nTotalMachines = 0; my $bVerbose = 0; my $sVersion = "1.0"; MAIN: ParseCmdArgs(); print "$sAppName $sVersion starting at $sDate...\n"; open(FPCLIST,$sMachineFile) || die "Can't open file $sMachineFile: $!\n"; while () { if (!/^[\!\#;']/) { # skip comments chop $_; s/\s(.*)//; # remove whitespace s/^\\\\//; # remove leading '\\' $sMachine = $_; if (!&IsVisibleOnNet()) { print "$sMachine not reachable on net; job not submitted.\n"; } else { $jobs{$sMachine} = sprintf("%d",++$nTotalMachines); # add to hash } } } close(FPCLIST); &FillHashTimeValues(); &BuildJobFile(); print "\nCreated batch file $sSubmitFile\n"; #print "\n$sAppName: submitted job to $nTotalMachines machine"; #if ($nTotalMachines != 1) { print "s."; } exit; # subroutines: sub BuildJobFile { my $sLine = ""; my $sOutFile = sprintf(">%s",$sSubmitFile); open(FPOUT,$sOutFile) || die "Can't open file $sSubmitFile: $!\n"; print FPOUT "\@echo off\n"; print FPOUT "rem $sAppName $sVersion submit script generated $sDate\n\n"; foreach $key (keys %jobs) { $sLine = "AT \\\\$key $jobs{$key} "; if (length($sEvery) > 0) { $sLine .= "/every:$sEvery "; } $sLine .= "$sCmdFile"; print FPOUT "$sLine\n"; } close(FPOUT); } sub ErrExit { print "Error: $_[0]\n"; exit 0; } sub FillHashTimeValues { my $nHalf = $nTotalMachines / 2; my $nStartHh = $nRunHh; my $nStartMm = $nRunMm; my $nHh = $nStartHh; my $nMm = $nStartMm; my $sSubTime = ""; my $i; my $bHalfway = 0; # assign 1st half counting down, 2nd half counting up: $i = 0; foreach $key (keys %jobs) { if (!$bHalfway) { $nMm = $nStartMm - $i; if ($nMm < 0) { $nMm = 60 - $i; $nHh -= 1; } if ($nHh < 0) { $nHh = 23; } } else { $nMm = $nStartMm + ($i - $nHalf) + 1; if ($nMm > 59) { $nMm = 0 + ($i - $nHalf); $nHh += 1; } if ($nHh > 23) { $nHh = 0; } } $sSubTime = sprintf("%2d:%2d",$nHh,$nMm); $sSubTime =~ s/ /0/g; $jobs{$key} = $sSubTime; if (++$i >= $nHalf) { if ($bHalfway == 0) { $nHh = $nStartHh; $nMm = $nStartMm; } $bHalfway = 1; } if ($bDebug) { print "dbg: $key = $jobs{$key}\n"; } } } sub Help { printf("\n%s version %s submits skewed AT jobs",$sAppName,$sVersion); print " to avoid collisions.\n"; print "\nWritten 5-dec-2000 by Frank Brown\n"; printf("\nusage: %s machinelist.fil command.fil runtime [/every:]\n\n",$sAppName); print "machinelist.fil is an ascii file with 1 machine per line\n"; print "command.fil is fully-qualified command file to schedule for run\n"; print "runtime is time of day (format = hh:mm)\n"; print "/every: is the AT command's optional argument (comma-seperated day list)\n"; print "\nType AT /? for help with Windows NT/2000's AT command.\n"; } sub IsVisibleOnNet { $p = Net::Ping->new("icmp"); return ($p->ping($sMachine,1)); } sub ParseCmdArgs { if ($#ARGV+1 < 3) { Help(); exit 0; } while (@ARGV) { $_ = shift @ARGV; if ($bDebug) { print "dbg: parsing $_\n"; } if (/^[\/\-]/) { # is arg a switch? $arg = substr($_,1,3); # parse 1st 3 chars: $arg =~ s/[A-Z]/[a-z]/; if ($arg eq "eve") { $i = index($_,":"); $i++; $sEvery = sprintf("%s",substr($_,$i)); } if (($arg eq "hel") || (substr($arg,0,1) eq "?")) { &Help(); exit; } if (substr($arg,0,1) eq "v") { $bVerbose = 1; } if (($arg eq "deb")) { $bDebug = 1; } } else { # not a switch if ($sMachineFile eq "") { $sMachineFile = $_; } elsif ($sCmdFile eq "") { $sCmdFile = $_; } elsif ($sRuntime eq "") { $sRuntime = $_; } } } if ($bDebug) { print "\ndbg: machinefile=$sMachineFile cmdfile=$sCmdFile runtime=$sRuntime"; print " every:$sEvery\n"; } if (!FileExists($sMachineFile)) { ErrExit("Bad filespec: $sMachineFile"); } if (!FileExists($sCmdFile)) { ErrExit("Bad filespec: $sCmdFile"); } } sub FileExists { return (-e $_[0]); } sub ValidateRuntime { }