diff --git a/erlang.spec b/erlang.spec index ac9196c..bc2d166 100644 --- a/erlang.spec +++ b/erlang.spec @@ -65,8 +65,8 @@ Name: erlang -Version: 22.0.7 -Release: 3%{?dist} +Version: 22.1.5 +Release: 1%{?dist} Summary: General-purpose programming language and runtime environment License: ASL 2.0 @@ -106,7 +106,7 @@ Patch6: otp-0006-Do-not-install-erlang-sources.patch Patch7: otp-0007-Add-extra-search-directory.patch Patch8: otp-0008-Avoid-forking-sed-to-get-basename.patch Patch9: otp-0009-Load-man-pages-from-system-wide-directory.patch -Patch10: otp-0010-Improve-nodes-querying.patch +Patch10: otp-0010-erl_child_setup-reduce-number-of-calls-to-close.patch # end of autogenerated patch tag list BuildRequires: gcc @@ -1936,6 +1936,9 @@ useradd -r -g epmd -d /dev/null -s /sbin/nologin \ %changelog +* Tue Nov 5 2019 John Eckersberg - 22.1.5-1 +- Ver. 22.1.5 + * Mon Sep 16 2019 Peter Lemenkov - 22.0.7-3 - Enable arches disabled in a previous build diff --git a/otp-0010-Improve-nodes-querying.patch b/otp-0010-Improve-nodes-querying.patch deleted file mode 100644 index fbf61b1..0000000 --- a/otp-0010-Improve-nodes-querying.patch +++ /dev/null @@ -1,134 +0,0 @@ -From: Peter Lemenkov -Date: Wed, 24 Oct 2018 14:58:41 +0200 -Subject: [PATCH] Improve nodes querying - -We've got a few similar stacktraces once. See the following one for -example: - -** Reason for termination == -** {badarg, - [{ets,next,[sys_dist,'rabbitmq-cli-42@host.example.com'],[]}, - {net_kernel,get_nodes,2,[{file,"net_kernel.erl"},{line,1025}]}, - {net_kernel,get_nodes,2,[{file,"net_kernel.erl"},{line,1019}]}, - {net_kernel,get_nodes_info,0,[{file,"net_kernel.erl"},{line,1439}]}, - {rabbit_mgmt_external_stats,cluster_links,0, - [{file,"src/rabbit_mgmt_external_stats.erl"},{line,252}]}, - {rabbit_mgmt_external_stats,emit_node_node_stats,1, - [{file,"src/rabbit_mgmt_external_stats.erl"},{line,366}]}, - {rabbit_mgmt_external_stats,handle_info,2, - [{file,"src/rabbit_mgmt_external_stats.erl"},{line,347}]}, - {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}]} - -The problem is that when we're trying to query a list of connected -nodes, we're doing it in the following way: - - Call for the first record in ETS - While not EOF: - Call for the next record in ETS - -What happens, when some Node disconnects during the "not EOF" loop? -We'll get an exception. - -Let's do it differently - query a list of nodes in one shot, and then -get info from each of the nodes in list (w/o extra calls to ets). These -individual calls care of disconnected nodes so everything will be fine -even if a node disconnects. - -Signed-off-by: Peter Lemenkov - -diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl -index 83d3b4b5e1..bebefc2e08 100644 ---- a/lib/kernel/src/net_kernel.erl -+++ b/lib/kernel/src/net_kernel.erl -@@ -670,24 +670,16 @@ code_change(_OldVsn, State, _Extra) -> - - terminate(no_network, State) -> - lists:foreach( -- fun({Node, Type}) -> -- case Type of -- normal -> ?nodedown(Node, State); -- _ -> ok -- end -- end, get_up_nodes() ++ [{node(), normal}]); -+ fun(Node) -> ?nodedown(Node, State) -+ end, get_nodes_up_normal() ++ [node()]); - terminate(_Reason, State) -> - lists:foreach( - fun(#listen {listen = Listen,module = Mod}) -> - Mod:close(Listen) - end, State#state.listen), - lists:foreach( -- fun({Node, Type}) -> -- case Type of -- normal -> ?nodedown(Node, State); -- _ -> ok -- end -- end, get_up_nodes() ++ [{node(), normal}]). -+ fun(Node) -> ?nodedown(Node, State) -+ end, get_nodes_up_normal() ++ [node()]). - - - %% ------------------------------------------------------------ -@@ -1147,35 +1139,10 @@ disconnect_pid(Pid, State) -> - %% - %% - %% --get_nodes(Which) -> -- get_nodes(ets:first(sys_dist), Which). - --get_nodes('$end_of_table', _) -> -- []; --get_nodes(Key, Which) -> -- case ets:lookup(sys_dist, Key) of -- [Conn = #connection{state = up}] -> -- [Conn#connection.node | get_nodes(ets:next(sys_dist, Key), -- Which)]; -- [Conn = #connection{}] when Which =:= all -> -- [Conn#connection.node | get_nodes(ets:next(sys_dist, Key), -- Which)]; -- _ -> -- get_nodes(ets:next(sys_dist, Key), Which) -- end. -- --%% Return a list of all nodes that are 'up'. --get_up_nodes() -> -- get_up_nodes(ets:first(sys_dist)). -- --get_up_nodes('$end_of_table') -> []; --get_up_nodes(Key) -> -- case ets:lookup(sys_dist, Key) of -- [#connection{state=up,node=Node,type=Type}] -> -- [{Node,Type}|get_up_nodes(ets:next(sys_dist, Key))]; -- _ -> -- get_up_nodes(ets:next(sys_dist, Key)) -- end. -+%% Return a list of all nodes that are 'up' and not hidden. -+get_nodes_up_normal() -> -+ ets:select(sys_dist, [{#connection{node = '$1', state = up, type = normal, _ = '_'}, [], ['$1']}]). - - ticker(Kernel, Tick) when is_integer(Tick) -> - process_flag(priority, max), -@@ -1640,15 +1607,14 @@ get_node_info(Node, Key) -> - end. - - get_nodes_info() -> -- get_nodes_info(get_nodes(all), []). -- --get_nodes_info([Node|Nodes], InfoList) -> -- case get_node_info(Node) of -- {ok, Info} -> get_nodes_info(Nodes, [{Node, Info}|InfoList]); -- _ -> get_nodes_info(Nodes, InfoList) -- end; --get_nodes_info([], InfoList) -> -- {ok, InfoList}. -+ Nodes = ets:select(sys_dist, [{#connection{node = '$1', _ = '_'}, [], ['$1']}]), -+ {ok, lists:filtermap( -+ fun(Node) -> -+ case get_node_info(Node) of -+ {ok, Info} -> {true, {Node, Info}}; -+ _ -> false -+ end -+ end, Nodes)}. - - %% ------------------------------------------------------------ - %% Misc. functions diff --git a/otp-0010-erl_child_setup-reduce-number-of-calls-to-close.patch b/otp-0010-erl_child_setup-reduce-number-of-calls-to-close.patch new file mode 100644 index 0000000..0a2a3a5 --- /dev/null +++ b/otp-0010-erl_child_setup-reduce-number-of-calls-to-close.patch @@ -0,0 +1,64 @@ +From 8a5bf2ad16c416c389147ca59c56545e038470e1 Mon Sep 17 00:00:00 2001 +From: John Eckersberg +Date: Fri, 11 Oct 2019 13:06:20 -0400 +Subject: [PATCH] erl_child_setup: reduce number of calls to close() + +On systems without closefrom(), such as Linux, iterating over all +possible file descriptors and calling close() for each is inefficient. +This is markedly so when the maximum number of file descriptors has +been tuned to a large number. + +Instead, walk the open descriptors under /dev/fd and close only those +which are open. +--- + erts/emulator/sys/unix/erl_child_setup.c | 25 +++++++++++++++++++++--- + 1 file changed, 22 insertions(+), 3 deletions(-) + +diff --git a/erts/emulator/sys/unix/erl_child_setup.c b/erts/emulator/sys/unix/erl_child_setup.c +index 129861ebd5..7ddd753136 100644 +--- a/erts/emulator/sys/unix/erl_child_setup.c ++++ b/erts/emulator/sys/unix/erl_child_setup.c +@@ -411,6 +411,7 @@ main(int argc, char *argv[]) + int uds_fd = 3, max_fd = 3; + #ifndef HAVE_CLOSEFROM + int i; ++ DIR *dir; + #endif + struct sigaction sa; + +@@ -426,11 +427,29 @@ main(int argc, char *argv[]) + #if defined(HAVE_CLOSEFROM) + closefrom(4); + #else +- for (i = 4; i < max_files; i++) ++ dir = opendir("/dev/fd"); ++ if (dir == NULL) { /* /dev/fd not available */ ++ for (i = 4; i < max_files; i++) + #if defined(__ANDROID__) +- if (i != system_properties_fd()) ++ if (i != system_properties_fd()) + #endif +- (void) close(i); ++ (void) close(i); ++ } else { ++ /* Iterate over fds obtained from /dev/fd */ ++ struct dirent *entry; ++ int dir_fd = dirfd(dir); ++ ++ while ((entry = readdir(dir)) != NULL) { ++ i = atoi(entry->d_name); ++#if defined(__ANDROID__) ++ if (i != system_properties_fd()) ++#endif ++ if (i >= 4 && i != dir_fd) ++ (void) close(i); ++ } ++ ++ closedir(dir); ++ } + #endif + + if (pipe(sigchld_pipe) < 0) { +-- +2.23.0 + diff --git a/sources b/sources index 2313247..80f0067 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (otp-OTP-22.0.7.tar.gz) = cf84cc20b97ed46f9ab3c7f1d77bcf6254ac3ebbb5c1e4e5202f4d5ba3d9c3bf5542567b047edaa68c204bc67ca667b1d96eb8153ac660e628c78fe271b6a8d9 +SHA512 (otp-OTP-22.1.5.tar.gz) = 0a32a1a7ca8092ee316c5e954384f133938e214101b54a37705b0c97b3e1ba26bd330da7d30fc6aaf667e21106476ddcf13cd48a59513e53e4abfc3fc8109231