Hi Hackers,

Inside PostgresNode.pm there is a free port choosing routine --- get_free_port(). The comment section there says:

        # On non-Linux, non-Windows kernels, binding to 127.0.0/24 addresses
        # other than 127.0.0.1 might fail with EADDRNOTAVAIL.

And this is an absolute true, on BSD-like systems (macOS and FreeBSD tested) it hangs on looping through the entire ports range over and over when $PostgresNode::use_tcp = 1 is set, since bind fails with:

# Checking port 52208
# bind: 127.0.0.1 52208
# bind: 127.0.0.2 52208
bind: Can't assign requested address

To reproduce just apply reproduce.diff and try to run 'make -C src/bin/pg_ctl check'.

This is not a case with standard Postgres tests, since TestLib.pm chooses unix sockets automatically everywhere outside Windows. However, we got into this problem when tried to run a custom tap test that required TCP for stable running.

That way, if it really could happen why not to just skip binding to 127.0.0/24 addresses other than 127.0.0.1 outside of Linux/Windows as per attached patch_PostgresNode.diff?


Regards
--
Alexey Kondratov

Postgres Professional https://www.postgrespro.com
Russian Postgres Company
diff --git a/src/test/perl/PostgresNode.pm b/src/test/perl/PostgresNode.pm
index db47a97d196..9add9bde2a4 100644
--- a/src/test/perl/PostgresNode.pm
+++ b/src/test/perl/PostgresNode.pm
@@ -1203,7 +1203,7 @@ sub get_free_port
 		if ($found == 1)
 		{
 			foreach my $addr (qw(127.0.0.1),
-				$use_tcp ? qw(127.0.0.2 127.0.0.3 0.0.0.0) : ())
+				$use_tcp && ($^O eq "linux" || $TestLib::windows_os) ? qw(127.0.0.2 127.0.0.3 0.0.0.0) : ())
 			{
 				if (!can_bind($addr, $port))
 				{
diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl
index b1e419f02e9..c25c0793537 100644
--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -11,6 +11,8 @@ use Test::More tests => 24;
 my $tempdir       = TestLib::tempdir;
 my $tempdir_short = TestLib::tempdir_short;
 
+$PostgresNode::use_tcp = 1;
+
 program_help_ok('pg_ctl');
 program_version_ok('pg_ctl');
 program_options_handling_ok('pg_ctl');

Reply via email to