@@ -10,19 +10,90 @@ use Cwd;
1010use IPC::Run;
1111use Socket;
1212
13+ our $last_port_assigned ;
14+ our $mm_listen_address = ' 127.0.0.1' ;
15+
16+ INIT
17+ {
18+ # Tracking of last port value assigned to accelerate free port lookup.
19+ $last_port_assigned = int (rand () * 1000) + 25999;
20+ }
21+
22+ # Copy of PostgresNode::get_free_port with corrected selection range: we
23+ # intentionally get the port from non-ephemeral range to prevent some guy
24+ # (often pg client connection) picking up the port while node is down.
25+ # (it actually rarely but steadily happens)
26+ sub mm_get_free_port
27+ {
28+ my $found = 0;
29+ my $port = $last_port_assigned ;
30+
31+ while ($found == 0)
32+ {
33+
34+ # advance $port, wrapping correctly around range end
35+ $port = 26000 if ++$port >= 27000;
36+ print " # Checking port $port \n " ;
37+
38+ # Check first that candidate port number is not included in
39+ # the list of already-registered nodes.
40+ $found = 1;
41+ foreach my $node (@PostgresNode::all_nodes )
42+ {
43+ $found = 0 if ($node -> port == $port );
44+ }
45+
46+ # Check to see if anything else is listening on this TCP port.
47+ # Seek a port available for all possible listen_addresses values,
48+ # so callers can harness this port for the widest range of purposes.
49+ # The 0.0.0.0 test achieves that for post-2006 Cygwin, which
50+ # automatically sets SO_EXCLUSIVEADDRUSE. The same holds for MSYS (a
51+ # Cygwin fork). Testing 0.0.0.0 is insufficient for Windows native
52+ # Perl (https://stackoverflow.com/a/14388707), so we also test
53+ # individual addresses.
54+ #
55+ # On non-Linux, non-Windows kernels, binding to 127.0.0/24 addresses
56+ # other than 127.0.0.1 might fail with EADDRNOTAVAIL. Binding to
57+ # 0.0.0.0 is unnecessary on non-Windows systems.
58+ if ($found == 1)
59+ {
60+ foreach my $addr (qw( 127.0.0.1) ,
61+ $PostgresNode::use_tcp ? qw( 127.0.0.2 127.0.0.3 0.0.0.0) : ())
62+ {
63+ if (!PostgresNode::can_bind($addr , $port ))
64+ {
65+ $found = 0;
66+ last ;
67+ }
68+ }
69+ }
70+ }
71+
72+ print " # Found port $port \n " ;
73+
74+ # Update port for next time
75+ $last_port_assigned = $port ;
76+
77+ return $port ;
78+ }
79+
1380sub new
1481{
1582 my ($class , $n_nodes , $referee ) = @_ ;
1683
17- my @nodes = map { get_new_node(" node$_ " ) } (1..$n_nodes );
84+ # ask PostgresNode to use tcp and listen on mm_listen_address
85+ $PostgresNode::use_tcp = 1;
86+ $PostgresNode::test_pghost = $mm_listen_address ;
87+
88+ my @nodes = map { get_new_node(" node$_ " , (' port' => mm_get_free_port())) } (1..$n_nodes );
1889
1990 my $self = {
2091 nodes => \@nodes ,
2192 recv_timeout => 6
2293 };
2394 if (defined $referee && $referee )
2495 {
25- $self -> {referee } = get_new_node(" referee" );
96+ $self -> {referee } = get_new_node(" referee" , ( ' port ' => mm_get_free_port() ) );
2697 }
2798
2899 bless $self , $class ;
@@ -43,7 +114,8 @@ sub init
43114 }
44115
45116 my $hba = qq{
46- local all all trust
117+ host all all ${mm_listen_address} /32 trust
118+ host replication all ${mm_listen_address} /32 trust
47119 } ;
48120
49121 # binary protocol doesn't tolerate strict alignment currently, so use it
@@ -103,13 +175,6 @@ sub init
103175
104176 multimaster.binary_basetypes = ${binary_basetypes}
105177
106- # There seems to be a weird issue with nonblocking connection to Unix
107- # sockets: rarely (during consenquent restart in the beginning of
108- # 001_regress) connection attempt hangs, as if we got EAGAIN but
109- # were never notified that the socket is ready. Let's see if this
110- # covers it up.
111- multimaster.connect_timeout = 10
112-
113178 # uncomment to get extensive logging for debugging
114179
115180 # multimaster.TxTrace_log_level = LOG
0 commit comments