@@ -3,6 +3,7 @@ package Cluster;
33use strict;
44use warnings;
55
6+ use Proc::ProcessTable;
67use PostgresNode;
78use TestLib;
89use Test::More;
@@ -135,7 +136,12 @@ sub stopnode
135136 $mode = ' fast' unless defined $mode ;
136137 diag(" stopping node $name ${mode} ly at $pgdata port $port " );
137138 next unless defined $node -> {_pid };
138- my $ret = TestLib::system_log(' pg_ctl' , ' -D' , $pgdata , ' -m' , ' fast' , ' stop' );
139+ my $ret = 0;
140+ if ($mode eq ' kill' ) {
141+ killtree($node -> {_pid });
142+ } else {
143+ $ret = TestLib::system_log(' pg_ctl' , ' -D' , $pgdata , ' -m' , ' fast' , ' stop' );
144+ }
139145 $node -> {_pid } = undef ;
140146 $node -> _update_pid;
141147
@@ -147,6 +153,45 @@ sub stopnode
147153 return 1;
148154}
149155
156+ sub killtree
157+ {
158+ my $root = shift ;
159+ diag(" killtree $root \n " );
160+
161+ my $t = new Proc::ProcessTable;
162+
163+ my %parent = ();
164+ # my %cmd = ();
165+ foreach my $p (@{$t -> table}) {
166+ $parent {$p -> pid} = $p -> ppid;
167+ # $cmd{$p->pid} = $p->cmndline;
168+ }
169+
170+ if (!defined $root ) {
171+ return ;
172+ }
173+ my @queue = ($root );
174+ my @killist = ();
175+
176+ while (scalar @queue ) {
177+ my $victim = shift @queue ;
178+ while (my ($pid , $ppid ) = each %parent ) {
179+ if ($ppid == $victim ) {
180+ push @queue , $pid ;
181+ }
182+ }
183+ diag(" SIGSTOP to $victim " );
184+ kill ' STOP' , $victim ;
185+ unshift @killist , $victim ;
186+ }
187+
188+ diag(" SIGKILL to " . join (' ' , @killist ));
189+ kill ' KILL' , @killist ;
190+ # foreach my $victim (@killist) {
191+ # print("kill $victim " . $cmd{$victim} . "\n");
192+ # }
193+ }
194+
150195sub stop
151196{
152197 my ($self , $mode ) = @_ ;
@@ -155,8 +200,8 @@ sub stop
155200
156201 my $ok = 1;
157202 diag(" stopping cluster ${mode} ly" );
158- foreach my $node ( @$nodes )
159- {
203+
204+ foreach my $node ( @$nodes ) {
160205 if (!stopnode($node , $mode )) {
161206 $ok = 0;
162207 if (!stopnode($node , ' immediate' )) {
0 commit comments