From 2f5f42596b37bf6c88fd50abc0ddb56240d6bca6 Mon Sep 17 00:00:00 2001 From: Damien Neil Date: Thu, 8 Mar 2001 02:34:01 +0000 Subject: [PATCH] - Stop can now use rndc, when passed the --use-rndc option. - Slightly restructured code to eliminate duplication. - No longer waits five seconds for a server to die, if it dies promptly. --- bin/tests/system/stop.pl | 181 ++++++++++++++++++++++++--------------- 1 file changed, 113 insertions(+), 68 deletions(-) diff --git a/bin/tests/system/stop.pl b/bin/tests/system/stop.pl index 51114979b9..6a090fab39 100644 --- a/bin/tests/system/stop.pl +++ b/bin/tests/system/stop.pl @@ -15,7 +15,7 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# $Id: stop.pl,v 1.3 2001/03/01 02:35:13 gson Exp $ +# $Id: stop.pl,v 1.4 2001/03/08 02:34:01 neild Exp $ # Framework for stopping test servers # Based on the type of server specified, signal the server to stop, wait @@ -26,67 +26,85 @@ use strict; use Cwd 'abs_path'; # Option handling -# test [server] +# [--use-rndc] test [server] # # test - name of the test directory # server - name of the server directory -my $usage = "usage: $0 test-directory [server-directory]"; +my $usage = "usage: $0 [--use-rndc] test-directory [server-directory]"; +my $use_rndc; + +while (@ARGV && $ARGV[0] =~ /^-/) { + my $opt = shift @ARGV; + if ($opt eq '--use-rndc') { + $use_rndc = 1; + } else { + die "$usage\n"; + } +} + my $test = $ARGV[0]; my $server = $ARGV[1]; my $errors = 0; + +die "$usage\n" unless defined($test); +die "No test directory: \"$test\"\n" unless (-d $test); +die "No server directory: \"$server\"\n" if (defined($server) && !-d $server); -if (!$test) { - print "$usage\n"; -} -if (!-d $test) { - print "No test directory: \"$test\"\n"; -} -if ($server && !-d $server) { - print "No server directory: \"$test\"\n"; -} - # Global variables -my $testdir = abs_path("$test"); +my $testdir = abs_path($test); +my @servers; -# Stop the server(s) -if ($server) { - &stop_server($server); - if ($server !~ /^ans/) { - sleep 5; - &kill_server($server); - } +# Determine which servers need to be stopped. +if (defined $server) { + @servers = ($server); } else { - # Determine which servers need to be stopped for this test. - opendir DIR, $testdir; + local *DIR; + opendir DIR, $testdir or die "$testdir: $!\n"; my @files = sort readdir DIR; closedir DIR; my @ns = grep /^ns[0-9]*$/, @files; my @lwresd = grep /^lwresd[0-9]*$/, @files; my @ans = grep /^ans[0-9]*$/, @files; + + push @servers, @ns, @lwresd, @ans; +} - # Stop the servers we found. - foreach (@ns, @lwresd, @ans) { - &stop_server($_); - } - sleep 5; - foreach (@ns, @lwresd) { - &kill_server($_); + +# Stop the server(s), pass 1: rndc. +if ($use_rndc) { + foreach my $server (grep /^ns/, @servers) { + stop_rndc($server); } + + wait_for_servers(5, grep /^ns/, @servers); +} + + +# Pass 2: SIGTERM +foreach my $server (@servers) { + stop_signal($server, "TERM"); +} +wait_for_servers(5, @servers); + + +# Pass 3: SIGKILL +foreach my $server (@servers) { + stop_signal($server, "KILL"); } exit($errors ? 1 : 0); # Subroutines -sub stop_server { - my $server = shift; +# Return the full path to a given server's PID file. +sub server_pid_file { + my($server) = @_; my $pid_file; - if ($server =~ /^ns/) { $pid_file = "named.pid"; } elsif ($server =~ /^lwresd/) { @@ -97,44 +115,71 @@ sub stop_server { print "I:Unknown server type $server\n"; exit 1; } - - # print "I:stopping server $server\n"; - - chdir "$testdir/$server"; - - if (-f $pid_file) { - my $result = kill 'TERM', `cat $pid_file`; - if ($result != 1) { - print "I:$server died before a SIGTERM was sent\n"; - unlink $pid_file; - $errors++; - } - } + $pid_file = "$testdir/$server/$pid_file"; } -sub kill_server { - my $server = shift; +# Read a PID. +sub read_pid { + my($pid_file) = @_; - my $pid_file; - - if ($server =~ /^ns/) { - $pid_file = "named.pid"; - } elsif ($server =~ /^lwresd/) { - $pid_file = "lwresd.pid"; - } else { - print "I:Unknown server type $server\n"; - exit 1; - } - - chdir "$testdir/$server"; - - if (-f $pid_file) { - print "I:$server didn't die when sent a SIGTERM\n"; - my $result = kill 'KILL', `cat $pid_file`; - if ($result != 1) { - print "I:$server died before a SIGKILL was sent\n"; - $errors++; - } + local *FH; + my $result = open FH, "< $pid_file"; + if (!$result) { + print "I:$pid_file: $!\n"; unlink $pid_file; + return; } + + my $pid = ; + chomp($pid); + return $pid; +} + +# Stop a named process with rndc. +sub stop_rndc { + my($server) = @_; + + return unless ($server =~ /^ns(\d+)$/); + my $ip = "10.53.0.$1"; + + # Ugly, but should work. + system("$ENV{RNDC} -c $testdir/../common/rndc.conf -s $ip -p 9953 stop | sed 's/^/I:$server /'"); + return; +} + +# Stop a server by sending a signal to it. +sub stop_signal { + my($server, $sig) = @_; + + my $pid_file = server_pid_file($server); + return unless -f $pid_file; + + my $pid = read_pid($pid_file); + return unless defined($pid); + + print "I:$server didn't die when sent a SIGTERM\n" if ($sig eq 'KILL'); + + my $result = kill $sig, $pid; + if (!$result) { + print "I:$server died before a SIG$sig was sent\n"; + unlink $pid_file; + $errors++; + } + + return; +} + +sub wait_for_servers { + my($timeout, @servers) = @_; + + my @pid_files = grep { defined($_) } + map { server_pid_file($_) } @servers; + + while ($timeout > 0 && @pid_files > 0) { + @pid_files = grep { -f $_ } @pid_files; + sleep 1 if (@pid_files > 0); + $timeout--; + } + + return; }