Skip to content

Commit

Permalink
kernel: Fix -erl_epmd_port to work properly
Browse files Browse the repository at this point in the history
  • Loading branch information
garazdawi committed Jun 23, 2020
1 parent f998978 commit c21bbb6
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 53 deletions.
3 changes: 1 addition & 2 deletions erts/doc/src/erl_cmd.xml
Expand Up @@ -492,8 +492,7 @@
<item>
<p>Starts Erlang with a remote shell connected to <c><![CDATA[Node]]></c>.</p>
<p>If no <c><![CDATA[-name]]></c> or <c><![CDATA[-sname]]></c> is given
the node will be started using <c>-sname undefined</c>. If <c>Node</c>
is using long names then you should give <c>-name undefined</c>.
the node will be started using <c>-sname undefined</c>.
If <c><![CDATA[Node]]></c> does not contain a hostname, one is automatically
taken from <c><![CDATA[-name]]></c> or <c><![CDATA[-sname]]></c>
</p>
Expand Down
98 changes: 52 additions & 46 deletions lib/kernel/src/erl_epmd.erl
Expand Up @@ -95,37 +95,39 @@ port_please(Node, Host) ->
Port :: non_neg_integer(),
Version :: non_neg_integer().

port_please(Node, HostName, Timeout) when is_atom(HostName) ->
port_please1(Node, atom_to_list(HostName), Timeout);
port_please(Node, HostName, Timeout) when is_list(HostName) ->
port_please1(Node, HostName, Timeout);
port_please(Node, EpmdAddr, Timeout) ->
get_port(Node, EpmdAddr, Timeout).

port_please1(Node, HostName, Timeout) ->
Family = case inet_db:res_option(inet6) of
true ->
inet6;
false ->
inet
end,
case inet:gethostbyname(HostName, Family, Timeout) of
{ok,#hostent{ h_addr_list = [EpmdAddr | _]}} ->
case get_port(Node, EpmdAddr, Timeout) of
noport ->
case listen_port_please(Node, HostName) of
{ok, 0} ->
noport;
{ok, Prt} ->
{port, Prt, 5}
end;
Reply ->
Reply
end;
_Else ->
?port_please_failure2(_Else),
noport
end.
port_please(Node, HostName, Timeout) ->
case listen_port_please(Node, HostName) of
{ok, 0} ->
case getepmdbyname(HostName, Timeout) of
{ok, EpmdAddr} ->
get_port(Node, EpmdAddr, Timeout);
Error ->
?port_please_failure2(Error),
Error
end;
{ok, Prt} ->
%% We don't know which dist version the other node is running
%% so return the low version so that we can talk to older nodes
{port, Prt, ?epmd_dist_low}
end.

getepmdbyname(HostName, Timeout) when is_atom(HostName) ->
getepmdbyname(atom_to_list(HostName), Timeout);
getepmdbyname(HostName, Timeout) when is_list(HostName) ->
Family = case inet_db:res_option(inet6) of
true ->
inet6;
false ->
inet
end,
case inet:gethostbyname(HostName, Family, Timeout) of
{ok,#hostent{ h_addr_list = [EpmdAddr | _]}} ->
{ok, EpmdAddr};
_Else ->
noport
end;
getepmdbyname(HostName, _Timeout) ->
{ok, HostName}.

-spec listen_port_please(Name, Host) -> {ok, Port} when
Name :: atom(),
Expand Down Expand Up @@ -157,15 +159,13 @@ names() ->
Port :: non_neg_integer(),
Reason :: address | file:posix().

names(HostName) when is_atom(HostName); is_list(HostName) ->
case inet:gethostbyname(HostName) of
{ok,#hostent{ h_addr_list = [EpmdAddr | _]}} ->
get_names(EpmdAddr);
Else ->
Else
end;
names(EpmdAddr) ->
get_names(EpmdAddr).
names(HostName) ->
case getepmdbyname(HostName, infinity) of
{ok,EpmdAddr} ->
get_names(EpmdAddr);
Else ->
Else
end.

-spec register_node(Name, Port) -> Result when
Name :: string(),
Expand Down Expand Up @@ -230,8 +230,15 @@ handle_call({register, Name, PortNo, Family}, _From, State) ->
port_no = PortNo,
name = Name},
{reply, {ok, Creation}, S};
Error ->
{reply, Error, State}
Error ->
case init:get_argument(erl_epmd_port) of
{ok, _} ->
{reply, {ok, -1}, State#state{ socket = -1,
port_no = PortNo,
name = Name} };
error ->
{reply, Error, State}
end
end;
_ ->
{reply, {error, already_registered}, State}
Expand Down Expand Up @@ -336,7 +343,7 @@ do_register_node(NodeName, TcpPort, Family) ->
Error
end;
Error ->
Error
Error
end.

epmd_dist_high() ->
Expand Down Expand Up @@ -416,9 +423,8 @@ get_port(Node, EpmdAddress, Timeout) ->
?port_please_failure2(_Error),
noport
end;
_Error ->
?port_please_failure2(_Error),
noport
_Error ->
noport
end.


Expand Down
4 changes: 1 addition & 3 deletions lib/kernel/src/net_kernel.erl
Expand Up @@ -1590,9 +1590,7 @@ create_name(Name, LongOrShortNames, Try) ->
{error, badarg};
{error,Type} ->
error_logger:info_msg(
lists:concat(["Can\'t set ",
Type,
" node name!\n"
lists:concat(["Can't set ", Type, " node name!\n"
"Please check your configuration\n"])),
{error,badarg}
end.
Expand Down
32 changes: 30 additions & 2 deletions lib/kernel/test/interactive_shell_SUITE.erl
Expand Up @@ -25,7 +25,7 @@
job_control_remote/1,stop_during_init/1,
job_control_remote_noshell/1,ctrl_keys/1,
get_columns_and_rows_escript/1,
remsh/1, remsh_longnames/1]).
remsh/1, remsh_longnames/1, remsh_no_epmd/1]).

-export([init_per_testcase/2, end_per_testcase/2]).
%% For spawn
Expand All @@ -46,7 +46,7 @@ all() ->
exit_initial, job_control_local,
job_control_remote, job_control_remote_noshell,
ctrl_keys, stop_during_init,
remsh, remsh_longnames].
remsh, remsh_longnames, remsh_no_epmd].

groups() ->
[].
Expand Down Expand Up @@ -456,6 +456,34 @@ remsh_longnames(Config) when is_list(Config) ->
end
end.

%% Test that -remsh works without epmd
remsh_no_epmd(Config) when is_list(Config) ->

case proplists:get_value(default_shell,Config) of
old -> {skip,"Not supported in old shell"};
new ->
EPMD_ARGS = "-start_epmd false -erl_epmd_port 12345 ",
case rtstart([],"ERL_EPMD_PORT=12345 ",
EPMD_ARGS ++ " -sname " ++ atom_to_list(?FUNCTION_NAME)) of
{ok, _SRPid, _STPid, SState} ->
{ok, _CRPid, CTPid, CState} =
rtstart([],"ERL_EPMD_PORT=12345 ",
EPMD_ARGS ++ " -remsh "++atom_to_list(?FUNCTION_NAME)),
try
ok = get_and_put(
CTPid,
[{kill_emulator_command,sigint},
{putline,""},
{putline,"node()."},
{getline_re,atom_to_list(?FUNCTION_NAME)}], 1)
after
rtstop(CState), %% Stop client before server
rtstop(SState)
end;
Else ->
Else
end
end.

rtnode(C,N) ->
rtnode(C,N,[]).
Expand Down

0 comments on commit c21bbb6

Please sign in to comment.