File 5241-erts-Unwrap-supervised-shutdown-reasons-for-distr-co.patch of Package erlang
From add7bfb90cbebdefdd51ba3d4a207a66d7199db1 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Wed, 23 Feb 2022 19:42:05 +0100
Subject: [PATCH] erts: Unwrap supervised shutdown reasons for distr controller
---
erts/emulator/beam/atom.names | 1 +
erts/emulator/beam/dist.c | 13 ++++++++++
lib/ssl/test/ssl_dist_SUITE.erl | 43 +++++++++++++++++++++++++++++++++
3 files changed, 57 insertions(+)
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index b9022689ba..49062e97a8 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -637,6 +637,7 @@ atom set_on_spawn
atom set_tcw
atom set_tcw_fake
atom short
+atom shutdown
atom sighup
atom sigterm
atom sigusr1
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index bea5f060a8..1287c6616a 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -965,6 +965,19 @@ int erts_do_net_exits(DistEntry *dep, Eterm reason)
if (erts_port_task_is_scheduled(&dep->dist_cmd))
erts_port_task_abort(&dep->dist_cmd);
}
+ else {
+ ASSERT(is_internal_pid(dep->cid));
+ /*
+ * Supervised distribution controllers may exit "normally" with
+ * {shutdown,Reason}. Unwrap such shutdown tuple to get a correct
+ * documented 'nodedown_reason' from net_kernel:montitor_nodes.
+ */
+ if (is_tuple_arity(reason, 2)) {
+ Eterm* tpl = tuple_val(reason);
+ if (tpl[1] == am_shutdown)
+ reason = tpl[2];
+ }
+ }
if (dep->state == ERTS_DE_STATE_EXITING) {
ASSERT(erts_atomic32_read_nob(&dep->qflgs) & ERTS_DE_QFLG_EXIT);
diff --git a/lib/ssl/test/ssl_dist_SUITE.erl b/lib/ssl/test/ssl_dist_SUITE.erl
index 493a19b4fa..4439b63bae 100644
--- a/lib/ssl/test/ssl_dist_SUITE.erl
+++ b/lib/ssl/test/ssl_dist_SUITE.erl
@@ -37,6 +37,7 @@
%% Test cases
-export([basic/0,
basic/1,
+ monitor_nodes/1,
payload/0,
payload/1,
dist_port_overload/0,
@@ -65,6 +66,7 @@
%% Apply export
-export([basic_test/3,
+ monitor_nodes_test/3,
payload_test/3,
plain_options_test/3,
plain_verify_options_test/3,
@@ -100,6 +102,7 @@ start_ssl_node_name(Name, Args) ->
%%--------------------------------------------------------------------
all() ->
[basic,
+ monitor_nodes,
payload,
dist_port_overload,
plain_options,
@@ -170,6 +173,11 @@ basic() ->
basic(Config) when is_list(Config) ->
gen_dist_test(basic_test, Config).
+%%--------------------------------------------------------------------
+%% Test net_kernel:monitor_nodes with nodedown_reason (OTP-17838)
+monitor_nodes(Config) when is_list(Config) ->
+ gen_dist_test(monitor_nodes_test, Config).
+
%%--------------------------------------------------------------------
payload() ->
[{doc,"Test that send a lot of data between the ssl distributed nodes"}].
@@ -530,6 +538,41 @@ basic_test(NH1, NH2, _) ->
end)
end.
+monitor_nodes_test(NH1, NH2, _) ->
+ Node2 = NH2#node_handle.nodename,
+
+ Ref = make_ref(),
+ MonitorNodesFun =
+ fun() ->
+ tstsrvr_format("Hi from ~p!~n", [node()]),
+ ok = net_kernel:monitor_nodes(true, [nodedown_reason]),
+ send_to_tstcntrl({self(), ready, Ref}),
+ NodeUp = receive_any(),
+ send_to_tstcntrl({self(), got, NodeUp}),
+ NodeDown = receive_any(),
+ send_to_tstcntrl({self(), got, NodeDown}),
+ ok = net_kernel:monitor_nodes(false, [nodedown_reason])
+ end,
+ spawn_link(fun () ->
+ ok = apply_on_ssl_node(NH1, MonitorNodesFun)
+ end),
+ {SslPid, ready, Ref} = receive_any(),
+
+ %% Setup connection and expect 'nodeup'
+ pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
+ {SslPid, got, {nodeup, Node2, []}} = receive_any(),
+
+ %% Disconnect and expect 'nodedown' with correct reason
+ true = apply_on_ssl_node(NH1, fun () ->
+ net_kernel:disconnect(Node2)
+ end),
+ {SslPid, got, {nodedown, Node2, [{nodedown_reason, disconnect}]}} = receive_any(),
+ ok.
+
+
+receive_any() ->
+ receive M -> M end.
+
payload_test(NH1, NH2, _) ->
Node1 = NH1#node_handle.nodename,
Node2 = NH2#node_handle.nodename,
--
2.34.1