1*00b67f09SDavid van Moolenbroek#!/usr/bin/perl -w 2*00b67f09SDavid van Moolenbroek# 3*00b67f09SDavid van Moolenbroek# Copyright (C) 2004-2008, 2010-2014 Internet Systems Consortium, Inc. ("ISC") 4*00b67f09SDavid van Moolenbroek# Copyright (C) 2001 Internet Software Consortium. 5*00b67f09SDavid van Moolenbroek# 6*00b67f09SDavid van Moolenbroek# Permission to use, copy, modify, and/or distribute this software for any 7*00b67f09SDavid van Moolenbroek# purpose with or without fee is hereby granted, provided that the above 8*00b67f09SDavid van Moolenbroek# copyright notice and this permission notice appear in all copies. 9*00b67f09SDavid van Moolenbroek# 10*00b67f09SDavid van Moolenbroek# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 11*00b67f09SDavid van Moolenbroek# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 12*00b67f09SDavid van Moolenbroek# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 13*00b67f09SDavid van Moolenbroek# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 14*00b67f09SDavid van Moolenbroek# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 15*00b67f09SDavid van Moolenbroek# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16*00b67f09SDavid van Moolenbroek# PERFORMANCE OF THIS SOFTWARE. 17*00b67f09SDavid van Moolenbroek 18*00b67f09SDavid van Moolenbroek# Id: start.pl,v 1.30 2012/02/06 23:46:44 tbox Exp 19*00b67f09SDavid van Moolenbroek 20*00b67f09SDavid van Moolenbroek# Framework for starting test servers. 21*00b67f09SDavid van Moolenbroek# Based on the type of server specified, check for port availability, remove 22*00b67f09SDavid van Moolenbroek# temporary files, start the server, and verify that the server is running. 23*00b67f09SDavid van Moolenbroek# If a server is specified, start it. Otherwise, start all servers for test. 24*00b67f09SDavid van Moolenbroek 25*00b67f09SDavid van Moolenbroekuse strict; 26*00b67f09SDavid van Moolenbroekuse Cwd; 27*00b67f09SDavid van Moolenbroekuse Cwd 'abs_path'; 28*00b67f09SDavid van Moolenbroekuse Getopt::Long; 29*00b67f09SDavid van Moolenbroek 30*00b67f09SDavid van Moolenbroek# Option handling 31*00b67f09SDavid van Moolenbroek# --noclean test [server [options]] 32*00b67f09SDavid van Moolenbroek# 33*00b67f09SDavid van Moolenbroek# --noclean - Do not cleanup files in server directory 34*00b67f09SDavid van Moolenbroek# test - name of the test directory 35*00b67f09SDavid van Moolenbroek# server - name of the server directory 36*00b67f09SDavid van Moolenbroek# options - alternate options for the server 37*00b67f09SDavid van Moolenbroek# NOTE: options must be specified with '-- "<option list>"', 38*00b67f09SDavid van Moolenbroek# for instance: start.pl . ns1 -- "-c n.conf -d 43" 39*00b67f09SDavid van Moolenbroek# ALSO NOTE: this variable will be filled with the 40*00b67f09SDavid van Moolenbroek# contents of the first non-commented/non-blank line of args 41*00b67f09SDavid van Moolenbroek# in a file called "named.args" in an ns*/ subdirectory only 42*00b67f09SDavid van Moolenbroek# the FIRST non-commented/non-blank line is used (everything 43*00b67f09SDavid van Moolenbroek# else in the file is ignored. If "options" is already set, 44*00b67f09SDavid van Moolenbroek# then "named.args" is ignored. 45*00b67f09SDavid van Moolenbroek 46*00b67f09SDavid van Moolenbroekmy $usage = "usage: $0 [--noclean] [--restart] test-directory [server-directory [server-options]]"; 47*00b67f09SDavid van Moolenbroekmy $noclean = ''; 48*00b67f09SDavid van Moolenbroekmy $restart = ''; 49*00b67f09SDavid van MoolenbroekGetOptions('noclean' => \$noclean, 'restart' => \$restart); 50*00b67f09SDavid van Moolenbroekmy $test = $ARGV[0]; 51*00b67f09SDavid van Moolenbroekmy $server = $ARGV[1]; 52*00b67f09SDavid van Moolenbroekmy $options = $ARGV[2]; 53*00b67f09SDavid van Moolenbroek 54*00b67f09SDavid van Moolenbroekif (!$test) { 55*00b67f09SDavid van Moolenbroek print "$usage\n"; 56*00b67f09SDavid van Moolenbroek} 57*00b67f09SDavid van Moolenbroekif (!-d $test) { 58*00b67f09SDavid van Moolenbroek print "No test directory: \"$test\"\n"; 59*00b67f09SDavid van Moolenbroek} 60*00b67f09SDavid van Moolenbroekif ($server && !-d "$test/$server") { 61*00b67f09SDavid van Moolenbroek print "No server directory: \"$test/$server\"\n"; 62*00b67f09SDavid van Moolenbroek} 63*00b67f09SDavid van Moolenbroek 64*00b67f09SDavid van Moolenbroek# Global variables 65*00b67f09SDavid van Moolenbroekmy $topdir = abs_path("$test/.."); 66*00b67f09SDavid van Moolenbroekmy $testdir = abs_path("$test"); 67*00b67f09SDavid van Moolenbroekmy $NAMED = $ENV{'NAMED'}; 68*00b67f09SDavid van Moolenbroekmy $LWRESD = $ENV{'LWRESD'}; 69*00b67f09SDavid van Moolenbroekmy $DIG = $ENV{'DIG'}; 70*00b67f09SDavid van Moolenbroekmy $PERL = $ENV{'PERL'}; 71*00b67f09SDavid van Moolenbroek 72*00b67f09SDavid van Moolenbroek# Start the server(s) 73*00b67f09SDavid van Moolenbroek 74*00b67f09SDavid van Moolenbroekif ($server) { 75*00b67f09SDavid van Moolenbroek if ($server =~ /^ns/) { 76*00b67f09SDavid van Moolenbroek &check_ports($server); 77*00b67f09SDavid van Moolenbroek } 78*00b67f09SDavid van Moolenbroek &start_server($server, $options); 79*00b67f09SDavid van Moolenbroek if ($server =~ /^ns/) { 80*00b67f09SDavid van Moolenbroek &verify_server($server); 81*00b67f09SDavid van Moolenbroek } 82*00b67f09SDavid van Moolenbroek} else { 83*00b67f09SDavid van Moolenbroek # Determine which servers need to be started for this test. 84*00b67f09SDavid van Moolenbroek opendir DIR, $testdir; 85*00b67f09SDavid van Moolenbroek my @files = sort readdir DIR; 86*00b67f09SDavid van Moolenbroek closedir DIR; 87*00b67f09SDavid van Moolenbroek 88*00b67f09SDavid van Moolenbroek my @ns = grep /^ns[0-9]*$/, @files; 89*00b67f09SDavid van Moolenbroek my @lwresd = grep /^lwresd[0-9]*$/, @files; 90*00b67f09SDavid van Moolenbroek my @ans = grep /^ans[0-9]*$/, @files; 91*00b67f09SDavid van Moolenbroek my $name; 92*00b67f09SDavid van Moolenbroek 93*00b67f09SDavid van Moolenbroek # Start the servers we found. 94*00b67f09SDavid van Moolenbroek &check_ports(); 95*00b67f09SDavid van Moolenbroek foreach $name(@ns, @lwresd, @ans) { 96*00b67f09SDavid van Moolenbroek &start_server($name); 97*00b67f09SDavid van Moolenbroek &verify_server($name) if ($name =~ /^ns/); 98*00b67f09SDavid van Moolenbroek 99*00b67f09SDavid van Moolenbroek } 100*00b67f09SDavid van Moolenbroek} 101*00b67f09SDavid van Moolenbroek 102*00b67f09SDavid van Moolenbroek# Subroutines 103*00b67f09SDavid van Moolenbroek 104*00b67f09SDavid van Moolenbroeksub check_ports { 105*00b67f09SDavid van Moolenbroek my $server = shift; 106*00b67f09SDavid van Moolenbroek my $options = ""; 107*00b67f09SDavid van Moolenbroek my $port = 5300; 108*00b67f09SDavid van Moolenbroek my $file = ""; 109*00b67f09SDavid van Moolenbroek 110*00b67f09SDavid van Moolenbroek $file = $testdir . "/" . $server . "/named.port" if ($server); 111*00b67f09SDavid van Moolenbroek 112*00b67f09SDavid van Moolenbroek if ($server && $server =~ /(\d+)$/) { 113*00b67f09SDavid van Moolenbroek $options = "-i $1"; 114*00b67f09SDavid van Moolenbroek } 115*00b67f09SDavid van Moolenbroek 116*00b67f09SDavid van Moolenbroek if ($file ne "" && -e $file) { 117*00b67f09SDavid van Moolenbroek open(FH, "<", $file); 118*00b67f09SDavid van Moolenbroek while(my $line=<FH>) { 119*00b67f09SDavid van Moolenbroek chomp $line; 120*00b67f09SDavid van Moolenbroek $port = $line; 121*00b67f09SDavid van Moolenbroek last; 122*00b67f09SDavid van Moolenbroek } 123*00b67f09SDavid van Moolenbroek close FH; 124*00b67f09SDavid van Moolenbroek } 125*00b67f09SDavid van Moolenbroek 126*00b67f09SDavid van Moolenbroek my $tries = 0; 127*00b67f09SDavid van Moolenbroek while (1) { 128*00b67f09SDavid van Moolenbroek my $return = system("$PERL $topdir/testsock.pl -p $port $options"); 129*00b67f09SDavid van Moolenbroek last if ($return == 0); 130*00b67f09SDavid van Moolenbroek if (++$tries > 4) { 131*00b67f09SDavid van Moolenbroek print "$0: could not bind to server addresses, still running?\n"; 132*00b67f09SDavid van Moolenbroek print "I:server sockets not available\n"; 133*00b67f09SDavid van Moolenbroek print "R:FAIL\n"; 134*00b67f09SDavid van Moolenbroek system("$PERL $topdir/stop.pl $testdir"); # Is this the correct behavior? 135*00b67f09SDavid van Moolenbroek exit 1; 136*00b67f09SDavid van Moolenbroek } 137*00b67f09SDavid van Moolenbroek print "I:Couldn't bind to socket (yet)\n"; 138*00b67f09SDavid van Moolenbroek sleep 2; 139*00b67f09SDavid van Moolenbroek } 140*00b67f09SDavid van Moolenbroek} 141*00b67f09SDavid van Moolenbroek 142*00b67f09SDavid van Moolenbroeksub start_server { 143*00b67f09SDavid van Moolenbroek my $server = shift; 144*00b67f09SDavid van Moolenbroek my $options = shift; 145*00b67f09SDavid van Moolenbroek 146*00b67f09SDavid van Moolenbroek my $cleanup_files; 147*00b67f09SDavid van Moolenbroek my $command; 148*00b67f09SDavid van Moolenbroek my $pid_file; 149*00b67f09SDavid van Moolenbroek my $cwd = getcwd(); 150*00b67f09SDavid van Moolenbroek my $args_file = $cwd . "/" . $test . "/" . $server . "/" . "named.args"; 151*00b67f09SDavid van Moolenbroek 152*00b67f09SDavid van Moolenbroek if ($server =~ /^ns/) { 153*00b67f09SDavid van Moolenbroek $cleanup_files = "{*.jnl,*.bk,*.st,named.run}"; 154*00b67f09SDavid van Moolenbroek $command = "$NAMED "; 155*00b67f09SDavid van Moolenbroek if ($options) { 156*00b67f09SDavid van Moolenbroek $command .= "$options"; 157*00b67f09SDavid van Moolenbroek } elsif (-e $args_file) { 158*00b67f09SDavid van Moolenbroek open(FH, "<", $args_file); 159*00b67f09SDavid van Moolenbroek while(my $line=<FH>) 160*00b67f09SDavid van Moolenbroek { 161*00b67f09SDavid van Moolenbroek #$line =~ s/\R//g; 162*00b67f09SDavid van Moolenbroek chomp $line; 163*00b67f09SDavid van Moolenbroek next if ($line =~ /^\s*$/); #discard blank lines 164*00b67f09SDavid van Moolenbroek next if ($line =~ /^\s*#/); #discard comment lines 165*00b67f09SDavid van Moolenbroek $line =~ s/#.*$//g; 166*00b67f09SDavid van Moolenbroek $options = $line; 167*00b67f09SDavid van Moolenbroek last; 168*00b67f09SDavid van Moolenbroek } 169*00b67f09SDavid van Moolenbroek close FH; 170*00b67f09SDavid van Moolenbroek $command .= "$options"; 171*00b67f09SDavid van Moolenbroek } else { 172*00b67f09SDavid van Moolenbroek $command .= "-D $server "; 173*00b67f09SDavid van Moolenbroek $command .= "-m record,size,mctx "; 174*00b67f09SDavid van Moolenbroek $command .= "-T clienttest "; 175*00b67f09SDavid van Moolenbroek $command .= "-T nosoa " 176*00b67f09SDavid van Moolenbroek if (-e "$testdir/$server/named.nosoa"); 177*00b67f09SDavid van Moolenbroek $command .= "-T noaa " 178*00b67f09SDavid van Moolenbroek if (-e "$testdir/$server/named.noaa"); 179*00b67f09SDavid van Moolenbroek $command .= "-T noedns " 180*00b67f09SDavid van Moolenbroek if (-e "$testdir/$server/named.noedns"); 181*00b67f09SDavid van Moolenbroek $command .= "-T dropedns " 182*00b67f09SDavid van Moolenbroek if (-e "$testdir/$server/named.dropedns"); 183*00b67f09SDavid van Moolenbroek $command .= "-T maxudp512 " 184*00b67f09SDavid van Moolenbroek if (-e "$testdir/$server/named.maxudp512"); 185*00b67f09SDavid van Moolenbroek $command .= "-T maxudp1460 " 186*00b67f09SDavid van Moolenbroek if (-e "$testdir/$server/named.maxudp1460"); 187*00b67f09SDavid van Moolenbroek $command .= "-c named.conf -d 99 -g -U 4"; 188*00b67f09SDavid van Moolenbroek } 189*00b67f09SDavid van Moolenbroek $command .= " -T notcp" 190*00b67f09SDavid van Moolenbroek if (-e "$testdir/$server/named.notcp"); 191*00b67f09SDavid van Moolenbroek if ($restart) { 192*00b67f09SDavid van Moolenbroek $command .= " >>named.run 2>&1 &"; 193*00b67f09SDavid van Moolenbroek } else { 194*00b67f09SDavid van Moolenbroek $command .= " >named.run 2>&1 &"; 195*00b67f09SDavid van Moolenbroek } 196*00b67f09SDavid van Moolenbroek $pid_file = "named.pid"; 197*00b67f09SDavid van Moolenbroek } elsif ($server =~ /^lwresd/) { 198*00b67f09SDavid van Moolenbroek $cleanup_files = "{lwresd.run}"; 199*00b67f09SDavid van Moolenbroek $command = "$LWRESD "; 200*00b67f09SDavid van Moolenbroek if ($options) { 201*00b67f09SDavid van Moolenbroek $command .= "$options"; 202*00b67f09SDavid van Moolenbroek } else { 203*00b67f09SDavid van Moolenbroek $command .= "-m record,size,mctx "; 204*00b67f09SDavid van Moolenbroek $command .= "-T clienttest "; 205*00b67f09SDavid van Moolenbroek $command .= "-C resolv.conf -d 99 -g -U 4 "; 206*00b67f09SDavid van Moolenbroek $command .= "-i lwresd.pid -P 9210 -p 5300"; 207*00b67f09SDavid van Moolenbroek } 208*00b67f09SDavid van Moolenbroek if ($restart) { 209*00b67f09SDavid van Moolenbroek $command .= " >>lwresd.run 2>&1 &"; 210*00b67f09SDavid van Moolenbroek } else { 211*00b67f09SDavid van Moolenbroek $command .= " >lwresd.run 2>&1 &"; 212*00b67f09SDavid van Moolenbroek } 213*00b67f09SDavid van Moolenbroek $pid_file = "lwresd.pid"; 214*00b67f09SDavid van Moolenbroek } elsif ($server =~ /^ans/) { 215*00b67f09SDavid van Moolenbroek $cleanup_files = "{ans.run}"; 216*00b67f09SDavid van Moolenbroek if (-e "$testdir/$server/ans.pl") { 217*00b67f09SDavid van Moolenbroek $command = "$PERL ans.pl"; 218*00b67f09SDavid van Moolenbroek } else { 219*00b67f09SDavid van Moolenbroek $command = "$PERL $topdir/ans.pl 10.53.0.$'"; 220*00b67f09SDavid van Moolenbroek } 221*00b67f09SDavid van Moolenbroek if ($options) { 222*00b67f09SDavid van Moolenbroek $command .= "$options"; 223*00b67f09SDavid van Moolenbroek } else { 224*00b67f09SDavid van Moolenbroek $command .= ""; 225*00b67f09SDavid van Moolenbroek } 226*00b67f09SDavid van Moolenbroek if ($restart) { 227*00b67f09SDavid van Moolenbroek $command .= " >>ans.run 2>&1 &"; 228*00b67f09SDavid van Moolenbroek } else { 229*00b67f09SDavid van Moolenbroek $command .= " >ans.run 2>&1 &"; 230*00b67f09SDavid van Moolenbroek } 231*00b67f09SDavid van Moolenbroek $pid_file = "ans.pid"; 232*00b67f09SDavid van Moolenbroek } else { 233*00b67f09SDavid van Moolenbroek print "I:Unknown server type $server\n"; 234*00b67f09SDavid van Moolenbroek print "R:FAIL\n"; 235*00b67f09SDavid van Moolenbroek system "$PERL $topdir/stop.pl $testdir"; 236*00b67f09SDavid van Moolenbroek exit 1; 237*00b67f09SDavid van Moolenbroek } 238*00b67f09SDavid van Moolenbroek 239*00b67f09SDavid van Moolenbroek # print "I:starting server %s\n",$server; 240*00b67f09SDavid van Moolenbroek 241*00b67f09SDavid van Moolenbroek chdir "$testdir/$server"; 242*00b67f09SDavid van Moolenbroek 243*00b67f09SDavid van Moolenbroek unless ($noclean) { 244*00b67f09SDavid van Moolenbroek unlink glob $cleanup_files; 245*00b67f09SDavid van Moolenbroek } 246*00b67f09SDavid van Moolenbroek 247*00b67f09SDavid van Moolenbroek # get the shell to report the pid of the server ($!) 248*00b67f09SDavid van Moolenbroek $command .= "echo \$!"; 249*00b67f09SDavid van Moolenbroek 250*00b67f09SDavid van Moolenbroek # start the server 251*00b67f09SDavid van Moolenbroek my $child = `$command`; 252*00b67f09SDavid van Moolenbroek $child =~ s/\s+$//g; 253*00b67f09SDavid van Moolenbroek 254*00b67f09SDavid van Moolenbroek # wait up to 14 seconds for the server to start and to write the 255*00b67f09SDavid van Moolenbroek # pid file otherwise kill this server and any others that have 256*00b67f09SDavid van Moolenbroek # already been started 257*00b67f09SDavid van Moolenbroek my $tries = 0; 258*00b67f09SDavid van Moolenbroek while (!-s $pid_file) { 259*00b67f09SDavid van Moolenbroek if (++$tries > 140) { 260*00b67f09SDavid van Moolenbroek print "I:Couldn't start server $server (pid=$child)\n"; 261*00b67f09SDavid van Moolenbroek print "R:FAIL\n"; 262*00b67f09SDavid van Moolenbroek system "kill -9 $child" if ("$child" ne ""); 263*00b67f09SDavid van Moolenbroek system "$PERL $topdir/stop.pl $testdir"; 264*00b67f09SDavid van Moolenbroek exit 1; 265*00b67f09SDavid van Moolenbroek } 266*00b67f09SDavid van Moolenbroek # sleep for 0.1 seconds 267*00b67f09SDavid van Moolenbroek select undef,undef,undef,0.1; 268*00b67f09SDavid van Moolenbroek } 269*00b67f09SDavid van Moolenbroek 270*00b67f09SDavid van Moolenbroek # go back to the top level directory 271*00b67f09SDavid van Moolenbroek chdir $cwd; 272*00b67f09SDavid van Moolenbroek} 273*00b67f09SDavid van Moolenbroek 274*00b67f09SDavid van Moolenbroeksub verify_server { 275*00b67f09SDavid van Moolenbroek my $server = shift; 276*00b67f09SDavid van Moolenbroek my $n = $server; 277*00b67f09SDavid van Moolenbroek my $port = 5300; 278*00b67f09SDavid van Moolenbroek my $tcp = "+tcp"; 279*00b67f09SDavid van Moolenbroek 280*00b67f09SDavid van Moolenbroek $n =~ s/^ns//; 281*00b67f09SDavid van Moolenbroek 282*00b67f09SDavid van Moolenbroek if (-e "$testdir/$server/named.port") { 283*00b67f09SDavid van Moolenbroek open(FH, "<", "$testdir/$server/named.port"); 284*00b67f09SDavid van Moolenbroek while(my $line=<FH>) { 285*00b67f09SDavid van Moolenbroek chomp $line; 286*00b67f09SDavid van Moolenbroek $port = $line; 287*00b67f09SDavid van Moolenbroek last; 288*00b67f09SDavid van Moolenbroek } 289*00b67f09SDavid van Moolenbroek close FH; 290*00b67f09SDavid van Moolenbroek } 291*00b67f09SDavid van Moolenbroek 292*00b67f09SDavid van Moolenbroek $tcp = "" if (-e "$testdir/$server/named.notcp"); 293*00b67f09SDavid van Moolenbroek 294*00b67f09SDavid van Moolenbroek my $tries = 0; 295*00b67f09SDavid van Moolenbroek while (1) { 296*00b67f09SDavid van Moolenbroek my $return = system("$DIG $tcp +noadd +nosea +nostat +noquest +nocomm +nocmd +noedns -p $port version.bind. chaos txt \@10.53.0.$n > dig.out"); 297*00b67f09SDavid van Moolenbroek last if ($return == 0); 298*00b67f09SDavid van Moolenbroek if (++$tries >= 30) { 299*00b67f09SDavid van Moolenbroek print `grep ";" dig.out > /dev/null`; 300*00b67f09SDavid van Moolenbroek print "I:no response from $server\n"; 301*00b67f09SDavid van Moolenbroek print "R:FAIL\n"; 302*00b67f09SDavid van Moolenbroek system("$PERL $topdir/stop.pl $testdir"); 303*00b67f09SDavid van Moolenbroek exit 1; 304*00b67f09SDavid van Moolenbroek } 305*00b67f09SDavid van Moolenbroek sleep 2; 306*00b67f09SDavid van Moolenbroek } 307*00b67f09SDavid van Moolenbroek unlink "dig.out"; 308*00b67f09SDavid van Moolenbroek} 309