From 45a4a46333b1e8e6f66ba923deaf947a67ae7737 Mon Sep 17 00:00:00 2001
From: Simon Cornish <7t9jna402@sneakemail.com>
Date: Mon, 25 Apr 2016 22:21:07 -0700
Subject: Don't kill old erlang if HEART_NO_KILL is set
If the environment variable HEART_NO_KILL is set then
heart won't kill the old erlang process. This is desirable
if the command executed by heart takes care of this.
---
erts/etc/common/heart.c | 9 +++++++++
lib/kernel/doc/src/heart.xml | 10 ++++++++++
lib/kernel/test/heart_SUITE.erl | 40 ++++++++++++++++++++++++++++++++++++++--
3 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/erts/etc/common/heart.c b/erts/etc/common/heart.c
index 1a826221fb..b6fbfd075c 100644
--- a/erts/etc/common/heart.c
+++ b/erts/etc/common/heart.c
@@ -119,6 +119,8 @@
#define HEART_COMMAND_ENV "HEART_COMMAND"
#define ERL_CRASH_DUMP_SECONDS_ENV "ERL_CRASH_DUMP_SECONDS"
#define HEART_KILL_SIGNAL "HEART_KILL_SIGNAL"
+#define HEART_NO_KILL "HEART_NO_KILL"
+
#define MSG_HDR_SIZE (2)
#define MSG_HDR_PLUS_OP_SIZE (3)
@@ -524,6 +526,10 @@ static void
kill_old_erlang(void){
HANDLE erlh;
DWORD exit_code;
+
+ if (is_env_set(HEART_NO_KILL))
+ return;
+
if(heart_beat_kill_pid != 0){
if((erlh = OpenProcess(PROCESS_TERMINATE |
SYNCHRONIZE |
@@ -557,6 +563,9 @@ kill_old_erlang(void){
int sig = SIGKILL;
char *sigenv = NULL;
+ if (is_env_set(HEART_NO_KILL))
+ return;
+
sigenv = get_env(HEART_KILL_SIGNAL);
if (sigenv && strcmp(sigenv, "SIGABRT") == 0) {
print_error("kill signal SIGABRT requested");
diff --git a/lib/kernel/doc/src/heart.xml b/lib/kernel/doc/src/heart.xml
index 9da4773f2d..bfb4ce45e6 100644
--- a/lib/kernel/doc/src/heart.xml
+++ b/lib/kernel/doc/src/heart.xml
@@ -89,6 +89,16 @@
% erl -heart -env HEART_KILL_SIGNAL SIGABRT ...
+
If heart should not kill the Erlang runtime system, this can be indicated
+ using the environment variable .
+ This can be useful if the command executed by heart takes care of this,
+ for example as part of a specific cleanup sequence.
+ If unset, the default behaviour will be to kill as described above.
+
+
+
+% erl -heart -env HEART_NO_KILL 1 ...
+
Furthermore, has the following behaviour on
heart:
diff --git a/lib/kernel/test/heart_SUITE.erl b/lib/kernel/test/heart_SUITE.erl
index 39cd29cea0..a848bc78f7 100644
--- a/lib/kernel/test/heart_SUITE.erl
+++ b/lib/kernel/test/heart_SUITE.erl
@@ -29,11 +29,11 @@
set_cmd/1, clear_cmd/1, get_cmd/1,
callback_api/1,
options_api/1,
- dont_drop/1, kill_pid/1]).
+ dont_drop/1, kill_pid/1, heart_no_kill/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
--export([start_heart_stress/1, mangle/1, suicide_by_heart/0]).
+-export([start_heart_stress/1, mangle/1, suicide_by_heart/0, non_suicide_by_heart/0]).
-define(DEFAULT_TIMEOUT_SECS, 120).
@@ -507,6 +507,30 @@ do_kill_pid(_Config) ->
false
end.
+
+heart_no_kill(suite) ->
+ [];
+heart_no_kill(doc) ->
+ ["Tests that heart doesn't kill the old erlang node when ",
+ "HEART_NO_KILL is set."];
+heart_no_kill(Config) when is_list(Config) ->
+ ok = do_no_kill(Config).
+
+do_no_kill(_Config) ->
+ Name = heart_test,
+ {ok,Node} = start_node_run(Name,[],non_suicide_by_heart,[]),
+ io:format("Node is ~p~n", [Node]),
+ ok = wait_for_node(Node,15),
+ io:format("wait_for_node is ~p~n", [ok]),
+ erlang:monitor_node(Node, true),
+ receive {nodedown,Node} -> false
+ after 30000 ->
+ io:format("Node didn't die..\n"),
+ rpc:call(Node,init,stop,[]),
+ io:format("done init:stop..\n"),
+ ok
+ end.
+
wait_for_node(_,0) ->
false;
wait_for_node(Node,N) ->
@@ -625,6 +649,18 @@ suicide_by_heart() ->
sallad
end.
+non_suicide_by_heart() ->
+ P = open_port({spawn,"heart -ht 11 -pid "++os:getpid()},[exit_status, {env, {"HEART_NO_KILL", "1"}}, {packet,2}]),
+ receive X -> X end,
+ %% Just hang and wait for heart to timeout
+ receive
+ {P,{exit_status,_}} ->
+ ok
+ after
+ 20000 ->
+ exit(timeout)
+ end.
+
%% generate a module from binary
generate(Module, Attributes, FunStrings) ->
--
cgit v1.2.3
From 85996c92853e90cb233a1405b1c8c7bb1b8ca54e Mon Sep 17 00:00:00 2001
From: Lukas Larsson
Date: Fri, 3 Jun 2016 11:43:47 +0200
Subject: erts: make HEART_NO_KILL have to be set to TRUE
---
erts/etc/common/heart.c | 13 ++++++++-----
lib/kernel/doc/src/heart.xml | 5 +++--
lib/kernel/test/heart_SUITE.erl | 2 +-
3 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/erts/etc/common/heart.c b/erts/etc/common/heart.c
index b6fbfd075c..0dd82cc036 100644
--- a/erts/etc/common/heart.c
+++ b/erts/etc/common/heart.c
@@ -526,8 +526,10 @@ static void
kill_old_erlang(void){
HANDLE erlh;
DWORD exit_code;
+ char* envvar = NULL;
- if (is_env_set(HEART_NO_KILL))
+ envvar = get_env(HEART_NO_KILL);
+ if (!envvar || strcmp(envvar, "TRUE") == 0)
return;
if(heart_beat_kill_pid != 0){
@@ -561,13 +563,14 @@ kill_old_erlang(void){
pid_t pid;
int i, res;
int sig = SIGKILL;
- char *sigenv = NULL;
+ char *envvar = NULL;
- if (is_env_set(HEART_NO_KILL))
+ envvar = get_env(HEART_NO_KILL);
+ if (!envvar || strcmp(envvar, "TRUE") == 0)
return;
- sigenv = get_env(HEART_KILL_SIGNAL);
- if (sigenv && strcmp(sigenv, "SIGABRT") == 0) {
+ envvar = get_env(HEART_KILL_SIGNAL);
+ if (envvar && strcmp(envvar, "SIGABRT") == 0) {
print_error("kill signal SIGABRT requested");
sig = SIGABRT;
}
diff --git a/lib/kernel/doc/src/heart.xml b/lib/kernel/doc/src/heart.xml
index bfb4ce45e6..1ad6a04b75 100644
--- a/lib/kernel/doc/src/heart.xml
+++ b/lib/kernel/doc/src/heart.xml
@@ -90,10 +90,11 @@
% erl -heart -env HEART_KILL_SIGNAL SIGABRT ...
If heart should not kill the Erlang runtime system, this can be indicated
- using the environment variable .
+ using the environment variable .
This can be useful if the command executed by heart takes care of this,
for example as part of a specific cleanup sequence.
- If unset, the default behaviour will be to kill as described above.
+ If unset, or not set to , the default behaviour
+ will be to kill as described above.
diff --git a/lib/kernel/test/heart_SUITE.erl b/lib/kernel/test/heart_SUITE.erl
index a848bc78f7..16b9f7a9ee 100644
--- a/lib/kernel/test/heart_SUITE.erl
+++ b/lib/kernel/test/heart_SUITE.erl
@@ -650,7 +650,7 @@ suicide_by_heart() ->
end.
non_suicide_by_heart() ->
- P = open_port({spawn,"heart -ht 11 -pid "++os:getpid()},[exit_status, {env, {"HEART_NO_KILL", "1"}}, {packet,2}]),
+ P = open_port({spawn,"heart -ht 11 -pid "++os:getpid()},[exit_status, {env, {"HEART_NO_KILL", "TRUE"}}, {packet,2}]),
receive X -> X end,
%% Just hang and wait for heart to timeout
receive
--
cgit v1.2.3