diff options
author | Erlang/OTP <[email protected]> | 2018-09-05 20:53:23 +0200 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2018-09-05 20:53:23 +0200 |
commit | 578af0ffd9d8cbcef86ae140f3dabc96c291d4b2 (patch) | |
tree | 1d742b7d9ef471ae50f0baf9eb500ebe856a7a04 /erts/emulator/beam | |
parent | f47b61279e884586707f09d2bdd2f411434801da (diff) | |
parent | a31216200bdee2c04b3fb3ae5e26607674715c8a (diff) | |
download | otp-578af0ffd9d8cbcef86ae140f3dabc96c291d4b2.tar.gz otp-578af0ffd9d8cbcef86ae140f3dabc96c291d4b2.tar.bz2 otp-578af0ffd9d8cbcef86ae140f3dabc96c291d4b2.zip |
Merge branch 'rickard/dist-entry-gc-fix/OTP-15279' into maint-21
* rickard/dist-entry-gc-fix/OTP-15279:
Prevent inconsistent node lists
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r-- | erts/emulator/beam/dist.c | 6 | ||||
-rw-r--r-- | erts/emulator/beam/dist.h | 2 | ||||
-rw-r--r-- | erts/emulator/beam/erl_node_tables.c | 38 |
3 files changed, 46 insertions, 0 deletions
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c index 70474898b2..16c4d689a5 100644 --- a/erts/emulator/beam/dist.c +++ b/erts/emulator/beam/dist.c @@ -3628,6 +3628,12 @@ static Sint abort_connection(DistEntry* dep, Uint32 conn_id) return 0; } +Sint +erts_abort_connection(DistEntry *dep, Uint32 conn_id) +{ + return abort_connection(dep, conn_id); +} + BIF_RETTYPE erts_internal_abort_connection_2(BIF_ALIST_2) { DistEntry* dep; diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h index dda2029a4c..30b4b35c20 100644 --- a/erts/emulator/beam/dist.h +++ b/erts/emulator/beam/dist.h @@ -399,5 +399,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); + #endif diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c index 1f147011a8..9b34af1480 100644 --- a/erts/emulator/beam/erl_node_tables.c +++ b/erts/emulator/beam/erl_node_tables.c @@ -412,6 +412,44 @@ 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); } |