aboutsummaryrefslogtreecommitdiff
path: root/src/test/perl/PostgreSQL/Test/Cluster.pm
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/perl/PostgreSQL/Test/Cluster.pm')
-rw-r--r--src/test/perl/PostgreSQL/Test/Cluster.pm40
1 files changed, 34 insertions, 6 deletions
diff --git a/src/test/perl/PostgreSQL/Test/Cluster.pm b/src/test/perl/PostgreSQL/Test/Cluster.pm
index b7d4c245539..265f3ae6574 100644
--- a/src/test/perl/PostgreSQL/Test/Cluster.pm
+++ b/src/test/perl/PostgreSQL/Test/Cluster.pm
@@ -896,23 +896,40 @@ Note: if the node is already known stopped, this does nothing.
However, if we think it's running and it's not, it's important for
this to fail. Otherwise, tests might fail to detect server crashes.
+With optional extra param fail_ok => 1, returns 0 for failure
+instead of bailing out.
+
=cut
sub stop
{
- my ($self, $mode) = @_;
- my $port = $self->port;
+ my ($self, $mode, %params) = @_;
my $pgdata = $self->data_dir;
my $name = $self->name;
+ my $ret;
local %ENV = $self->_get_env();
$mode = 'fast' unless defined $mode;
- return unless defined $self->{_pid};
+ return 1 unless defined $self->{_pid};
+
print "### Stopping node \"$name\" using mode $mode\n";
- PostgreSQL::Test::Utils::system_or_bail('pg_ctl', '-D', $pgdata, '-m', $mode, 'stop');
+ $ret = PostgreSQL::Test::Utils::system_log('pg_ctl', '-D', $pgdata,
+ '-m', $mode, 'stop');
+
+ if ($ret != 0)
+ {
+ print "# pg_ctl stop failed: $ret\n";
+
+ # Check to see if we still have a postmaster or not.
+ $self->_update_pid(-1);
+
+ BAIL_OUT("pg_ctl stop failed") unless $params{fail_ok};
+ return 0;
+ }
+
$self->_update_pid(0);
- return;
+ return 1;
}
=pod
@@ -1142,9 +1159,20 @@ sub _update_pid
if (open my $pidfile, '<', $self->data_dir . "/postmaster.pid")
{
chomp($self->{_pid} = <$pidfile>);
- print "# Postmaster PID for node \"$name\" is $self->{_pid}\n";
close $pidfile;
+ # If we aren't sure what to expect, validate the PID using kill().
+ # This protects against stale PID files left by crashed postmasters.
+ if ($is_running == -1 && kill(0, $self->{_pid}) == 0)
+ {
+ print
+ "# Stale postmaster.pid file for node \"$name\": PID $self->{_pid} no longer exists\n";
+ $self->{_pid} = undef;
+ return;
+ }
+
+ print "# Postmaster PID for node \"$name\" is $self->{_pid}\n";
+
# If we found a pidfile when there shouldn't be one, complain.
BAIL_OUT("postmaster.pid unexpectedly present") if $is_running == 0;
return;