Skip to content

Commit c21bbb6

Browse files
committed
kernel: Fix -erl_epmd_port to work properly
1 parent f998978 commit c21bbb6

File tree

4 files changed

+84
-53
lines changed

4 files changed

+84
-53
lines changed

erts/doc/src/erl_cmd.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -492,8 +492,7 @@
492492
<item>
493493
<p>Starts Erlang with a remote shell connected to <c><![CDATA[Node]]></c>.</p>
494494
<p>If no <c><![CDATA[-name]]></c> or <c><![CDATA[-sname]]></c> is given
495-
the node will be started using <c>-sname undefined</c>. If <c>Node</c>
496-
is using long names then you should give <c>-name undefined</c>.
495+
the node will be started using <c>-sname undefined</c>.
497496
If <c><![CDATA[Node]]></c> does not contain a hostname, one is automatically
498497
taken from <c><![CDATA[-name]]></c> or <c><![CDATA[-sname]]></c>
499498
</p>

lib/kernel/src/erl_epmd.erl

Lines changed: 52 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -95,37 +95,39 @@ port_please(Node, Host) ->
9595
Port :: non_neg_integer(),
9696
Version :: non_neg_integer().
9797

98-
port_please(Node, HostName, Timeout) when is_atom(HostName) ->
99-
port_please1(Node, atom_to_list(HostName), Timeout);
100-
port_please(Node, HostName, Timeout) when is_list(HostName) ->
101-
port_please1(Node, HostName, Timeout);
102-
port_please(Node, EpmdAddr, Timeout) ->
103-
get_port(Node, EpmdAddr, Timeout).
104-
105-
port_please1(Node, HostName, Timeout) ->
106-
Family = case inet_db:res_option(inet6) of
107-
true ->
108-
inet6;
109-
false ->
110-
inet
111-
end,
112-
case inet:gethostbyname(HostName, Family, Timeout) of
113-
{ok,#hostent{ h_addr_list = [EpmdAddr | _]}} ->
114-
case get_port(Node, EpmdAddr, Timeout) of
115-
noport ->
116-
case listen_port_please(Node, HostName) of
117-
{ok, 0} ->
118-
noport;
119-
{ok, Prt} ->
120-
{port, Prt, 5}
121-
end;
122-
Reply ->
123-
Reply
124-
end;
125-
_Else ->
126-
?port_please_failure2(_Else),
127-
noport
128-
end.
98+
port_please(Node, HostName, Timeout) ->
99+
case listen_port_please(Node, HostName) of
100+
{ok, 0} ->
101+
case getepmdbyname(HostName, Timeout) of
102+
{ok, EpmdAddr} ->
103+
get_port(Node, EpmdAddr, Timeout);
104+
Error ->
105+
?port_please_failure2(Error),
106+
Error
107+
end;
108+
{ok, Prt} ->
109+
%% We don't know which dist version the other node is running
110+
%% so return the low version so that we can talk to older nodes
111+
{port, Prt, ?epmd_dist_low}
112+
end.
113+
114+
getepmdbyname(HostName, Timeout) when is_atom(HostName) ->
115+
getepmdbyname(atom_to_list(HostName), Timeout);
116+
getepmdbyname(HostName, Timeout) when is_list(HostName) ->
117+
Family = case inet_db:res_option(inet6) of
118+
true ->
119+
inet6;
120+
false ->
121+
inet
122+
end,
123+
case inet:gethostbyname(HostName, Family, Timeout) of
124+
{ok,#hostent{ h_addr_list = [EpmdAddr | _]}} ->
125+
{ok, EpmdAddr};
126+
_Else ->
127+
noport
128+
end;
129+
getepmdbyname(HostName, _Timeout) ->
130+
{ok, HostName}.
129131

130132
-spec listen_port_please(Name, Host) -> {ok, Port} when
131133
Name :: atom(),
@@ -157,15 +159,13 @@ names() ->
157159
Port :: non_neg_integer(),
158160
Reason :: address | file:posix().
159161

160-
names(HostName) when is_atom(HostName); is_list(HostName) ->
161-
case inet:gethostbyname(HostName) of
162-
{ok,#hostent{ h_addr_list = [EpmdAddr | _]}} ->
163-
get_names(EpmdAddr);
164-
Else ->
165-
Else
166-
end;
167-
names(EpmdAddr) ->
168-
get_names(EpmdAddr).
162+
names(HostName) ->
163+
case getepmdbyname(HostName, infinity) of
164+
{ok,EpmdAddr} ->
165+
get_names(EpmdAddr);
166+
Else ->
167+
Else
168+
end.
169169

170170
-spec register_node(Name, Port) -> Result when
171171
Name :: string(),
@@ -230,8 +230,15 @@ handle_call({register, Name, PortNo, Family}, _From, State) ->
230230
port_no = PortNo,
231231
name = Name},
232232
{reply, {ok, Creation}, S};
233-
Error ->
234-
{reply, Error, State}
233+
Error ->
234+
case init:get_argument(erl_epmd_port) of
235+
{ok, _} ->
236+
{reply, {ok, -1}, State#state{ socket = -1,
237+
port_no = PortNo,
238+
name = Name} };
239+
error ->
240+
{reply, Error, State}
241+
end
235242
end;
236243
_ ->
237244
{reply, {error, already_registered}, State}
@@ -336,7 +343,7 @@ do_register_node(NodeName, TcpPort, Family) ->
336343
Error
337344
end;
338345
Error ->
339-
Error
346+
Error
340347
end.
341348

342349
epmd_dist_high() ->
@@ -416,9 +423,8 @@ get_port(Node, EpmdAddress, Timeout) ->
416423
?port_please_failure2(_Error),
417424
noport
418425
end;
419-
_Error ->
420-
?port_please_failure2(_Error),
421-
noport
426+
_Error ->
427+
noport
422428
end.
423429

424430

lib/kernel/src/net_kernel.erl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,9 +1590,7 @@ create_name(Name, LongOrShortNames, Try) ->
15901590
{error, badarg};
15911591
{error,Type} ->
15921592
error_logger:info_msg(
1593-
lists:concat(["Can\'t set ",
1594-
Type,
1595-
" node name!\n"
1593+
lists:concat(["Can't set ", Type, " node name!\n"
15961594
"Please check your configuration\n"])),
15971595
{error,badarg}
15981596
end.

lib/kernel/test/interactive_shell_SUITE.erl

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
job_control_remote/1,stop_during_init/1,
2626
job_control_remote_noshell/1,ctrl_keys/1,
2727
get_columns_and_rows_escript/1,
28-
remsh/1, remsh_longnames/1]).
28+
remsh/1, remsh_longnames/1, remsh_no_epmd/1]).
2929

3030
-export([init_per_testcase/2, end_per_testcase/2]).
3131
%% For spawn
@@ -46,7 +46,7 @@ all() ->
4646
exit_initial, job_control_local,
4747
job_control_remote, job_control_remote_noshell,
4848
ctrl_keys, stop_during_init,
49-
remsh, remsh_longnames].
49+
remsh, remsh_longnames, remsh_no_epmd].
5050

5151
groups() ->
5252
[].
@@ -456,6 +456,34 @@ remsh_longnames(Config) when is_list(Config) ->
456456
end
457457
end.
458458

459+
%% Test that -remsh works without epmd
460+
remsh_no_epmd(Config) when is_list(Config) ->
461+
462+
case proplists:get_value(default_shell,Config) of
463+
old -> {skip,"Not supported in old shell"};
464+
new ->
465+
EPMD_ARGS = "-start_epmd false -erl_epmd_port 12345 ",
466+
case rtstart([],"ERL_EPMD_PORT=12345 ",
467+
EPMD_ARGS ++ " -sname " ++ atom_to_list(?FUNCTION_NAME)) of
468+
{ok, _SRPid, _STPid, SState} ->
469+
{ok, _CRPid, CTPid, CState} =
470+
rtstart([],"ERL_EPMD_PORT=12345 ",
471+
EPMD_ARGS ++ " -remsh "++atom_to_list(?FUNCTION_NAME)),
472+
try
473+
ok = get_and_put(
474+
CTPid,
475+
[{kill_emulator_command,sigint},
476+
{putline,""},
477+
{putline,"node()."},
478+
{getline_re,atom_to_list(?FUNCTION_NAME)}], 1)
479+
after
480+
rtstop(CState), %% Stop client before server
481+
rtstop(SState)
482+
end;
483+
Else ->
484+
Else
485+
end
486+
end.
459487

460488
rtnode(C,N) ->
461489
rtnode(C,N,[]).

0 commit comments

Comments
 (0)