aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/doc/src/notes.xml30
-rw-r--r--erts/emulator/beam/dist.c23
-rw-r--r--erts/emulator/beam/dist.h2
-rw-r--r--erts/emulator/beam/erl_node_tables.c83
-rw-r--r--erts/emulator/sys/unix/erl_child_setup.c11
-rw-r--r--erts/vsn.mk2
6 files changed, 99 insertions, 52 deletions
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 42d883f269..2d396236cf 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -31,6 +31,36 @@
</header>
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 10.0.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ As of ERTS version 10.0 (OTP 21.0) the
+ <c>erl_child_setup</c> program, which creates port
+ programs, ignores <c>TERM</c> signals. This setting was
+ unintentionally inherited by port programs. Handling of
+ <c>TERM</c> signals in port programs has now been
+ restored to the default behavior. That is, terminate the
+ process.</p>
+ <p>
+ Own Id: OTP-15289 Aux Id: ERIERL-235, OTP-14943, ERL-576 </p>
+ </item>
+ <item>
+ <p>
+ The fix made for OTP-15279 in erts-10.07 (OTP-21.0.8) was
+ not complete. It could cause a new connection attempt to
+ be incorrectly aborted in certain cases. This fix will
+ amend that flaw.</p>
+ <p>
+ Own Id: OTP-15296 Aux Id: OTP-15279, ERIERL-226 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 10.0.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index e7c0ee65dc..1dcda29af9 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -3556,20 +3556,18 @@ BIF_RETTYPE erts_internal_new_connection_1(BIF_ALIST_1)
BIF_RET(TUPLE2(hp, make_small(conn_id), dhandle));
}
-static Sint abort_connection(DistEntry* dep, Uint32 conn_id)
+Sint erts_abort_connection_rwunlock(DistEntry* dep)
{
- erts_de_rwlock(dep);
+ Sint reds = 0;
+ ERTS_LC_ASSERT(erts_lc_is_de_rwlocked(dep));
- if (dep->connection_id != conn_id)
- ;
- else if (dep->state == ERTS_DE_STATE_CONNECTED) {
+ if (dep->state == ERTS_DE_STATE_CONNECTED) {
kill_connection(dep);
}
else if (dep->state == ERTS_DE_STATE_PENDING) {
ErtsAtomCache *cache;
ErtsDistOutputBuf *obuf;
ErtsProcList *resume_procs;
- Sint reds = 0;
ErtsMonLnkDist *mld;
ASSERT(is_nil(dep->cid));
@@ -3614,17 +3612,18 @@ static Sint abort_connection(DistEntry* dep, Uint32 conn_id)
erts_de_rwlock(dep);
ASSERT(dep->state == ERTS_DE_STATE_EXITING);
dep->state = ERTS_DE_STATE_IDLE;
- erts_de_rwunlock(dep);
- return reds;
}
erts_de_rwunlock(dep);
- return 0;
+ return reds;
}
-Sint
-erts_abort_connection(DistEntry *dep, Uint32 conn_id)
+static Sint abort_connection(DistEntry *dep, Uint32 conn_id)
{
- return abort_connection(dep, conn_id);
+ erts_de_rwlock(dep);
+ if (dep->connection_id == conn_id)
+ return erts_abort_connection_rwunlock(dep);
+ erts_de_rwunlock(dep);
+ return 0;
}
BIF_RETTYPE erts_internal_abort_connection_2(BIF_ALIST_2)
diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h
index c8d0407456..e55daa7615 100644
--- a/erts/emulator/beam/dist.h
+++ b/erts/emulator/beam/dist.h
@@ -400,7 +400,7 @@ extern void erts_kill_dist_connection(DistEntry *dep, Uint32);
extern Uint erts_dist_cache_size(void);
-extern Sint erts_abort_connection(DistEntry *dep, Uint32 conn_id);
+extern Sint erts_abort_connection_rwunlock(DistEntry *dep);
#endif
diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c
index 9b34af1480..f4a36d124a 100644
--- a/erts/emulator/beam/erl_node_tables.c
+++ b/erts/emulator/beam/erl_node_tables.c
@@ -60,6 +60,10 @@ static int references_atoms_need_init = 1;
static ErtsMonotonicTime orig_node_tab_delete_delay;
static ErtsMonotonicTime node_tab_delete_delay;
+
+static void report_gc_active_dist_entry(Eterm sysname, enum dist_entry_state);
+
+
/* -- The distribution table ---------------------------------------------- */
#define ErtsBin2DistEntry(B) \
@@ -412,44 +416,6 @@ static void schedule_delete_dist_entry(DistEntry* dep)
static void
start_timer_delete_dist_entry(void *vdep)
{
- DistEntry *dep = vdep;
- Eterm sysname;
- enum dist_entry_state state;
- Uint32 connection_id;
-
- erts_de_rlock(dep);
- state = dep->state;
- connection_id = dep->connection_id;
- sysname = dep->sysname;
- erts_de_runlock(dep);
-
- if (state != ERTS_DE_STATE_IDLE) {
- char *state_str;
- erts_dsprintf_buf_t *dsbuf = erts_create_logger_dsbuf();
- switch (state) {
- case ERTS_DE_STATE_CONNECTED:
- state_str = "connected";
- break;
- case ERTS_DE_STATE_PENDING:
- state_str = "pending connect";
- break;
- case ERTS_DE_STATE_EXITING:
- state_str = "exiting";
- break;
- case ERTS_DE_STATE_IDLE:
- state_str = "idle";
- break;
- default:
- state_str = "unknown";
- break;
- }
- erts_dsprintf(dsbuf, "Garbage collecting distribution "
- "entry for node %T in state: %s",
- sysname, state_str);
- erts_send_error_to_logger_nogl(dsbuf);
- erts_abort_connection(dep, connection_id);
- }
-
if (node_tab_delete_delay == 0) {
prepare_try_delete_dist_entry(vdep);
}
@@ -489,6 +455,19 @@ static void try_delete_dist_entry(DistEntry* dep)
{
erts_aint_t refc;
+ erts_de_rwlock(dep);
+ if (dep->state != ERTS_DE_STATE_IDLE && de_refc_read(dep,0) == 0) {
+ Eterm sysname = dep->sysname;
+ enum dist_entry_state state = dep->state;
+
+ if (dep->state != ERTS_DE_STATE_PENDING)
+ ERTS_INTERNAL_ERROR("Garbage collecting connected distribution entry");
+ erts_abort_connection_rwunlock(dep);
+ report_gc_active_dist_entry(sysname, state);
+ }
+ else
+ erts_de_rwunlock(dep);
+
erts_rwmtx_rwlock(&erts_dist_table_rwmtx);
/*
* Another thread might have looked up this dist entry after
@@ -515,6 +494,34 @@ static void try_delete_dist_entry(DistEntry* dep)
}
}
+static void report_gc_active_dist_entry(Eterm sysname,
+ enum dist_entry_state state)
+{
+ char *state_str;
+ erts_dsprintf_buf_t *dsbuf = erts_create_logger_dsbuf();
+ switch (state) {
+ case ERTS_DE_STATE_CONNECTED:
+ state_str = "connected";
+ break;
+ case ERTS_DE_STATE_PENDING:
+ state_str = "pending connect";
+ break;
+ case ERTS_DE_STATE_EXITING:
+ state_str = "exiting";
+ break;
+ case ERTS_DE_STATE_IDLE:
+ state_str = "idle";
+ break;
+ default:
+ state_str = "unknown";
+ break;
+ }
+ erts_dsprintf(dsbuf, "Garbage collecting distribution "
+ "entry for node %T in state: %s",
+ sysname, state_str);
+ erts_send_error_to_logger_nogl(dsbuf);
+}
+
int erts_dist_entry_destructor(Binary *bin)
{
DistEntry *dep = ErtsBin2DistEntry(bin);
diff --git a/erts/emulator/sys/unix/erl_child_setup.c b/erts/emulator/sys/unix/erl_child_setup.c
index 221ee2a69d..129861ebd5 100644
--- a/erts/emulator/sys/unix/erl_child_setup.c
+++ b/erts/emulator/sys/unix/erl_child_setup.c
@@ -133,6 +133,7 @@ static int sigchld_pipe[2];
static int
start_new_child(int pipes[])
{
+ struct sigaction sa;
int errln = -1;
int size, res, i, pos = 0;
char *buff, *o_buff;
@@ -143,6 +144,16 @@ start_new_child(int pipes[])
/* only child executes here */
+ /* Restore default handling of sigterm... */
+ sa.sa_handler = SIG_DFL;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+
+ if (sigaction(SIGTERM, &sa, 0) == -1) {
+ perror(NULL);
+ exit(1);
+ }
+
do {
res = read(pipes[0], (char*)&size, sizeof(size));
} while(res < 0 && (errno == EINTR || errno == ERRNO_BLOCK));
diff --git a/erts/vsn.mk b/erts/vsn.mk
index 293b555b18..e28716c37f 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -18,7 +18,7 @@
# %CopyrightEnd%
#
-VSN = 10.0.7
+VSN = 10.0.8
# Port number 4365 in 4.2
# Port number 4366 in 4.3