File 6642-erts-Dynamic-node-name-alive-fixes.patch of Package erlang

From f3cf7587f9d0725d2c2fbb4934345f071cc8f34d Mon Sep 17 00:00:00 2001
From: Rickard Green <rickard@erlang.org>
Date: Mon, 30 May 2022 02:29:58 +0200
Subject: [PATCH 2/2] [erts] Dynamic node name alive fixes

The monitor_node/2,3 and monitor/2,3 BIFs erroneously failed if called
prior to node name assignment when dynamic node name was used on the node.
---
 erts/emulator/beam/atom.names             |  1 +
 erts/emulator/beam/bif.c                  |  2 +-
 erts/emulator/beam/dist.c                 | 32 ++++++++-
 erts/emulator/beam/dist.h                 |  3 +
 erts/emulator/beam/erl_bif_persistent.c   | 35 +++++----
 erts/emulator/beam/global.h               |  1 +
 erts/emulator/test/distribution_SUITE.erl | 86 ++++++++++++++++++++++-
 7 files changed, 143 insertions(+), 17 deletions(-)

diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index 70b0a6818f..952742fa75 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -245,6 +245,7 @@ atom dsend_continue_trap
 atom duplicate_bag
 atom duplicated
 atom dupnames
+atom dynamic_node_name
 atom einval
 atom emu_flavor
 atom emu_type
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index f359ce7558..a30d6b6a9e 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -765,7 +765,7 @@ static BIF_RETTYPE monitor(Process *c_p, Eterm type, Eterm target,
                 goto badarg;
             if (is_not_atom(tpl[1]) || is_not_atom(tpl[2]))
                 goto badarg;
-            if (!erts_is_alive && tpl[2] != am_Noname)
+            if (tpl[2] != am_Noname && !erts_is_this_node_alive())
                 goto badarg;
             target = tpl[1];
             dep = erts_find_or_insert_dist_entry(tpl[2]);
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index 9d7b035394..4491073830 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -4734,6 +4734,36 @@ BIF_RETTYPE setnode_2(BIF_ALIST_2)
     BIF_ERROR(BIF_P, BADARG);
 }
 
+/*
+ * erts_is_this_node_alive() returns the same result as erlang:is_alive()
+ */
+int
+erts_is_this_node_alive(void)
+{
+    Eterm tmp_heap[3];
+    Eterm dyn_name_key, dyn_name_value;
+
+    /*
+     * erts_is_alive is only non zero if a node name has been set. Not if
+     * dynamic node name has been enabled.
+     */
+    if (erts_is_alive) {
+        return !0;
+    }
+
+    /*
+     * A persistent term with key '{erts_internal, dynamic_node_name}' has been
+     * set if dynamic node name has been enabled.
+     */
+    dyn_name_key = TUPLE2(&tmp_heap[0], am_erts_internal, am_dynamic_node_name);
+    dyn_name_value = erts_persistent_term_get(dyn_name_key);
+    if (is_value(dyn_name_value) && dyn_name_value != am_false) {
+        return !0;
+    }
+
+    return 0;
+}
+
 /*
  * erts_internal:create_dist_channel/4 is used by
  * erlang:setnode/3.
@@ -5970,7 +6000,7 @@ monitor_node(Process* p, Eterm Node, Eterm Bool, Eterm Options)
     if (is_not_atom(Node))
         goto badarg;
 
-    if (erts_this_node->sysname == am_Noname && Node != am_Noname) {
+    if (Node != am_Noname && !erts_is_this_node_alive()) {
         ERTS_BIF_PREP_ERROR(ret, p, EXC_NOTALIVE);
         goto do_return;
     }
diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h
index d3dd91190e..decf7d2ea7 100644
--- a/erts/emulator/beam/dist.h
+++ b/erts/emulator/beam/dist.h
@@ -440,4 +440,7 @@ int erts_auto_connect(DistEntry* dep, Process *proc, ErtsProcLocks proc_locks);
 Uint erts_ttb_iov_size(int use_termv, Sint vlen, Uint fragments);
 void erts_ttb_iov_init(TTBEncodeContext *ctx, int use_termv, char *ptr,
                        Sint vlen, Uint fragments, Uint fragments_size);
+
+int erts_is_this_node_alive(void);
+
 #endif
diff --git a/erts/emulator/beam/erl_bif_persistent.c b/erts/emulator/beam/erl_bif_persistent.c
index 9d9ac45266..08e15f55d6 100644
--- a/erts/emulator/beam/erl_bif_persistent.c
+++ b/erts/emulator/beam/erl_bif_persistent.c
@@ -474,9 +474,9 @@ BIF_RETTYPE persistent_term_get_0(BIF_ALIST_0)
     }
 }
 
-BIF_RETTYPE persistent_term_get_1(BIF_ALIST_1)
+static ERTS_INLINE Eterm
+persistent_term_get(Eterm key)
 {
-    Eterm key = BIF_ARG_1;
     HashTable* hash_table = (HashTable *) erts_atomic_read_nob(&the_hash_table);
     Eterm bucket;
 
@@ -484,24 +484,33 @@ BIF_RETTYPE persistent_term_get_1(BIF_ALIST_1)
 
     if (is_boxed(bucket)) {
         ASSERT(is_tuple_arity(bucket, 2));
-        BIF_RET(tuple_val(bucket)[2]);
+        return tuple_val(bucket)[2];
     }
 
-    BIF_ERROR(BIF_P, BADARG);
+    return THE_NON_VALUE;
 }
 
-BIF_RETTYPE persistent_term_get_2(BIF_ALIST_2)
+Eterm
+erts_persistent_term_get(Eterm key)
 {
-    Eterm key = BIF_ARG_1;
-    Eterm result = BIF_ARG_2;
-    HashTable* hash_table = (HashTable *) erts_atomic_read_nob(&the_hash_table);
-    Eterm bucket;
+    return persistent_term_get(key);
+}
 
-    (void)lookup(hash_table, key, &bucket);
+BIF_RETTYPE persistent_term_get_1(BIF_ALIST_1)
+{
+    Eterm result = persistent_term_get(BIF_ARG_1);
+    if (is_non_value(result)) {
+        BIF_ERROR(BIF_P, BADARG);
+    }
 
-    if (is_boxed(bucket)) {
-        ASSERT(is_tuple_arity(bucket, 2));
-        result = tuple_val(bucket)[2];
+    BIF_RET(result);
+}
+
+BIF_RETTYPE persistent_term_get_2(BIF_ALIST_2)
+{
+    Eterm result = persistent_term_get(BIF_ARG_1);
+    if (is_non_value(result)) {
+        result = BIF_ARG_2;
     }
 
     BIF_RET(result);
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 4847cdcfd0..f892d0dd89 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -1445,6 +1445,7 @@ void erts_init_bif_binary(void);
 Sint erts_binary_set_loop_limit(Sint limit);
 
 /* erl_bif_persistent.c */
+Eterm erts_persistent_term_get(Eterm key);
 void erts_init_bif_persistent_term(void);
 void erts_init_persistent_dumping(void);
 extern ErtsLiteralArea** erts_persistent_areas;
-- 
2.35.3

openSUSE Build Service is sponsored by