File 4292-Read-other-nodes-cookies-from-command-line.patch of Package erlang

From 1bdda7678df6cbf93b42758c8cbc1b0dcbeadc12 Mon Sep 17 00:00:00 2001
From: Raimo Niskanen <raimo@erlang.org>
Date: Thu, 29 Jul 2021 12:25:11 +0200
Subject: [PATCH 2/9] Read other nodes' cookies from command line

---
 erts/doc/src/erl_cmd.xml                    |   8 +-
 lib/kernel/src/auth.erl                     | 105 +++++++++++++++-----
 system/doc/reference_manual/distributed.xml |   6 +-
 3 files changed, 92 insertions(+), 27 deletions(-)

diff --git a/erts/doc/src/erl_cmd.xml b/erts/doc/src/erl_cmd.xml
index 4d59a64b10..c28632ec7a 100644
--- a/erts/doc/src/erl_cmd.xml
+++ b/erts/doc/src/erl_cmd.xml
@@ -629,6 +629,12 @@ $ <input>erl \
           <seemfa marker="erlang#set_cookie/2">
           <c>erlang:set_cookie/2</c></seemfa>.</p>
       </item>
+      <tag><c><![CDATA[-setcookie Node Cookie]]></c></tag>
+      <item>
+        <p>Sets the magic cookie of Node to <c><![CDATA[Cookie]]></c>; see
+          <seemfa marker="erlang#set_cookie/2">
+          <c>erlang:set_cookie/2</c></seemfa>.</p>
+      </item>
       <tag><c><![CDATA[-shutdown_time Time]]></c></tag>
       <item>
         <p>Specifies how long time (in milliseconds) the <c><![CDATA[init]]></c>
diff --git a/lib/kernel/src/auth.erl b/lib/kernel/src/auth.erl
index e552758a0d..6fb4267eb4 100644
--- a/lib/kernel/src/auth.erl
+++ b/lib/kernel/src/auth.erl
@@ -271,35 +271,90 @@ getnode(P) -> P.
 %%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-%% Read cookie from $HOME/.erlang.cookie and set it.
+%% Read and set cookie from command line or $HOME/.erlang.cookie.
 init_cookie() ->
+    case init:get_argument(setcookie) of
+        error ->
+            init_no_setcookie();
+        {ok, Setcookie} ->
+            init_setcookie(Setcookie, [], #{})
+    end.
+
+%% No -setcookie argument
+init_no_setcookie() ->
     case init:get_argument(nocookie) of
-	error ->
-	    case init:get_argument(setcookie) of
-		{ok, [[C0]]} ->
-		    C = list_to_atom(C0),
-		    #state{our_cookie = C,
-			   other_cookies = ets:new(cookies,
-						   [?COOKIE_ETS_PROTECTION])};
-		_ ->
-		    %% Here is the default 
-		    case read_cookie() of
-			{error, Error} ->
-			    error_logger:error_msg(Error, []),
-			    %% Is this really this serious?
-			    erlang:error(Error);
-			{ok, Co}  ->
-			    #state{our_cookie = list_to_atom(Co),
-				   other_cookies = ets:new(
-						     cookies,
-						     [?COOKIE_ETS_PROTECTION])}
-		    end
-	    end;
-	_Other ->
-	    #state{our_cookie = nocookie,
-		   other_cookies = ets:new(cookies, [?COOKIE_ETS_PROTECTION])}
+        error ->
+            %% Here is the default
+            %% - no -setcookie nor -nocookie argument
+            case read_cookie() of
+                {error, Error} ->
+                    error_logger:error_msg(Error, []),
+                    %% Is this really this serious?
+                    erlang:error(Error);
+                {ok, Co}  ->
+                    #state{our_cookie = list_to_atom(Co),
+                           other_cookies = ets_new_cookies()}
+            end;
+        {ok, Nocookie} when is_list(Nocookie) ->
+            %% Ignore the value
+            #state{our_cookie = nocookie,
+                   other_cookies = ets_new_cookies()}
     end.
 
+%% Process -setcookie options
+init_setcookie([SetCo | Setcookie], OurCookies, OtherCookies) ->
+    case SetCo of
+        %% Collect arity 0 and 1 options as our cookie
+        [] ->
+            init_setcookie(Setcookie, [SetCo | OurCookies], OtherCookies);
+        [_] ->
+            init_setcookie(Setcookie, [SetCo | OurCookies], OtherCookies);
+        [Node, Co] ->
+            %% Collect arity 2 options as other nodes' cookies
+            init_setcookie(
+              Setcookie, OurCookies,
+              case OtherCookies of
+                  #{Node := _} ->
+                      %% If a node's cookie is set more than once
+                      %% we pretend it was not set, a'la how
+                      %% setting our own cookie is handled
+                      OtherCookies#{Node := undefined};
+                  #{} ->
+                      OtherCookies#{Node => Co}
+              end);
+        _ when is_list(SetCo) ->
+            %% Ignore options of arity 3 or more, which changes
+            %% legacy behaviour which was to ignore our own
+            %% cookie due to invalid arity (only valid was 1)
+            init_setcookie(Setcookie, OurCookies, OtherCookies)
+    end;
+init_setcookie([], OurCookies, OtherCookies) ->
+    %% Options collected - handle them
+    State =
+        case OurCookies of
+            [[Co]] ->
+                %% We have no arity 0 and exactly one arity 1
+                %% option i.e our cookie
+                #state{
+                   our_cookie = list_to_atom(Co),
+                   other_cookies = ets_new_cookies()};
+            _ when is_list(OurCookies) ->
+                %% Any other combination of arity 0 and 1 options
+                %% makes us pretend they were not there;
+                %% legacy behaviour - we have no set cookie
+                init_no_setcookie()
+        end,
+    %% Register all other node's cookies (arity 2 options)
+    ets:insert(
+      State#state.other_cookies,
+      [{list_to_atom(Node), list_to_atom(Co)} ||
+          {Node, Co} <- maps:to_list(OtherCookies),
+          Co =/= undefined]),
+    State.
+
+ets_new_cookies() ->
+    ets:new(cookies, [?COOKIE_ETS_PROTECTION]).
+
 read_cookie() ->
     case init:get_argument(home) of
 	{ok, [[Home]]} ->
diff --git a/system/doc/reference_manual/distributed.xml b/system/doc/reference_manual/distributed.xml
index 38cb99dd0d..832a87c2d4 100644
--- a/system/doc/reference_manual/distributed.xml
+++ b/system/doc/reference_manual/distributed.xml
@@ -4,7 +4,7 @@
 <chapter>
   <header>
     <copyright>
-      <year>2003</year><year>2017</year>
+      <year>2003</year><year>2021</year>
       <holder>Ericsson AB. All Rights Reserved.</holder>
     </copyright>
     <legalnotice>
@@ -273,6 +273,10 @@ dilbert@uab</pre>
         <cell align="left" valign="middle"><c>-setcookie Cookie</c></cell>
         <cell align="left" valign="middle">Same as calling <c>erlang:set_cookie(node(), Cookie)</c>.</cell>
       </row>
+      <row>
+        <cell align="left" valign="middle"><c>-setcookie Node Cookie</c></cell>
+        <cell align="left" valign="middle">Same as calling <c>erlang:set_cookie(Node, Cookie)</c>.</cell>
+      </row>
       <row>
         <cell align="left" valign="middle"><c>-sname Name</c></cell>
         <cell align="left" valign="middle">Makes a runtime system into a node, using short node names.</cell>
-- 
2.31.1

openSUSE Build Service is sponsored by