summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJean-Sébastien Pédron <jean-sebastien@rabbitmq.com>2020-02-10 15:21:45 +0100
committerGitHub <noreply@github.com>2020-02-10 15:21:45 +0100
commitcb068d565607146644e07bf42a6c7d323f23256e (patch)
tree4dbe814b4a0ed05aa90eeee51ef41a3450593c94 /src
parenta922e91b0bffaba9f6b09a0305e62c677b75101e (diff)
parent05fb823426b1aeb78a62c46c44ab8c92e1ac9722 (diff)
downloadrabbitmq-server-git-cb068d565607146644e07bf42a6c7d323f23256e.tar.gz
Merge pull request #2231 from rabbitmq/extract_sd_notify
Convert systemd notification to prelaunch steps
Diffstat (limited to 'src')
-rw-r--r--src/rabbit.erl139
1 files changed, 12 insertions, 127 deletions
diff --git a/src/rabbit.erl b/src/rabbit.erl
index 191fbc5320..0f98e50504 100644
--- a/src/rabbit.erl
+++ b/src/rabbit.erl
@@ -373,120 +373,6 @@ run_prelaunch_second_phase() ->
end,
ok.
-%% Try to send systemd ready notification if it makes sense in the
-%% current environment. standard_error is used intentionally in all
-%% logging statements, so all this messages will end in systemd
-%% journal.
-maybe_sd_notify() ->
- case sd_notify_ready() of
- false ->
- io:format(standard_error, "systemd READY notification failed, beware of timeouts~n", []);
- _ ->
- ok
- end.
-
-sd_notify_ready() ->
- case rabbit_prelaunch:get_context() of
- #{systemd_notify_socket := Socket} when Socket =/= undefined ->
- %% Non-empty NOTIFY_SOCKET, give it a try
- sd_notify_legacy() orelse sd_notify_socat();
- _ ->
- true
- end.
-
-sd_notify_data() ->
- "READY=1\nSTATUS=Initialized\nMAINPID=" ++ os:getpid() ++ "\n".
-
-sd_notify_legacy() ->
- case code:load_file(sd_notify) of
- {module, sd_notify} ->
- SDNotify = sd_notify,
- SDNotify:sd_notify(0, sd_notify_data()),
- true;
- {error, _} ->
- false
- end.
-
-%% socat(1) is the most portable way the sd_notify could be
-%% implemented in erlang, without introducing some NIF. Currently the
-%% following issues prevent us from implementing it in a more
-%% reasonable way:
-%% - systemd-notify(1) is unstable for non-root users
-%% - erlang doesn't support unix domain sockets.
-%%
-%% Some details on how we ended with such a solution:
-%% https://github.com/rabbitmq/rabbitmq-server/issues/664
-sd_notify_socat() ->
- case sd_current_unit() of
- {ok, Unit} ->
- io:format(standard_error, "systemd unit for activation check: \"~s\"~n", [Unit]),
- sd_notify_socat(Unit);
- _ ->
- false
- end.
-
-socat_socket_arg("@" ++ AbstractUnixSocket) ->
- "abstract-sendto:" ++ AbstractUnixSocket;
-socat_socket_arg(UnixSocket) ->
- "unix-sendto:" ++ UnixSocket.
-
-sd_open_port() ->
- #{systemd_notify_socket := Socket} = rabbit_prelaunch:get_context(),
- true = Socket =/= undefined,
- open_port(
- {spawn_executable, os:find_executable("socat")},
- [{args, [socat_socket_arg(Socket), "STDIO"]},
- use_stdio, out]).
-
-sd_notify_socat(Unit) ->
- try sd_open_port() of
- Port ->
- Port ! {self(), {command, sd_notify_data()}},
- Result = sd_wait_activation(Port, Unit),
- port_close(Port),
- Result
- catch
- Class:Reason ->
- io:format(standard_error, "Failed to start socat ~p:~p~n", [Class, Reason]),
- false
- end.
-
-sd_current_unit() ->
- CmdOut = os:cmd("ps -o unit= -p " ++ os:getpid()),
- case catch re:run(CmdOut, "([-.@0-9a-zA-Z]+)", [unicode, {capture, all_but_first, list}]) of
- {'EXIT', _} ->
- error;
- {match, [Unit]} ->
- {ok, Unit};
- _ ->
- error
- end.
-
-sd_wait_activation(Port, Unit) ->
- case os:find_executable("systemctl") of
- false ->
- io:format(standard_error, "'systemctl' unavailable, falling back to sleep~n", []),
- timer:sleep(5000),
- true;
- _ ->
- sd_wait_activation(Port, Unit, 10)
- end.
-
-sd_wait_activation(_, _, 0) ->
- io:format(standard_error, "Service still in 'activating' state, bailing out~n", []),
- false;
-sd_wait_activation(Port, Unit, AttemptsLeft) ->
- case os:cmd("systemctl show --property=ActiveState -- '" ++ Unit ++ "'") of
- "ActiveState=activating\n" ->
- timer:sleep(1000),
- sd_wait_activation(Port, Unit, AttemptsLeft - 1);
- "ActiveState=" ++ _ ->
- true;
- _ = Err->
- io:format(standard_error, "Unexpected status from systemd ~p~n", [Err]),
- false
- end.
-
start_it(StartType) ->
case spawn_boot_marker() of
{ok, Marker} ->
@@ -519,12 +405,12 @@ start_it(StartType) ->
end.
wait_for_ready_or_stopped() ->
- ok = rabbit_prelaunch:wait_for_boot_state(ready),
- case rabbit_prelaunch:get_boot_state() of
+ ok = rabbit_boot_state:wait_for(ready, ?BOOT_FINISH_TIMEOUT),
+ case rabbit_boot_state:get() of
ready ->
ok;
_ ->
- ok = rabbit_prelaunch:wait_for_boot_state(stopped),
+ ok = rabbit_boot_state:wait_for(stopped, ?BOOT_FINISH_TIMEOUT),
rabbit_prelaunch:get_stop_reason()
end.
@@ -548,7 +434,7 @@ stop_boot_marker(Marker) ->
stop() ->
case wait_for_ready_or_stopped() of
ok ->
- case rabbit_prelaunch:get_boot_state() of
+ case rabbit_boot_state:get() of
ready ->
rabbit_log:info("RabbitMQ is asked to stop..."),
do_stop(),
@@ -656,7 +542,7 @@ handle_app_error(Term) ->
is_booting() -> is_booting(node()).
is_booting(Node) when Node =:= node() ->
- case rabbit_prelaunch:get_boot_state() of
+ case rabbit_boot_state:get() of
booting -> true;
_ -> false
end;
@@ -855,7 +741,7 @@ is_running() -> is_running(node()).
-spec is_running(node()) -> boolean().
is_running(Node) when Node =:= node() ->
- case rabbit_prelaunch:get_boot_state() of
+ case rabbit_boot_state:get() of
ready -> true;
_ -> false
end;
@@ -925,7 +811,7 @@ start(normal, []) ->
%% This is important if the previous startup attempt failed after
%% rabbitmq_prelaunch was started and the application is still
%% running.
- rabbit_prelaunch:set_boot_state(booting),
+ rabbit_boot_state:set(booting),
rabbit_prelaunch:clear_stop_reason(),
try
@@ -969,7 +855,7 @@ start(normal, []) ->
mnesia:stop(),
rabbit_prelaunch_errors:log_error(Error),
rabbit_prelaunch:set_stop_reason(Error),
- rabbit_prelaunch:set_boot_state(stopped),
+ rabbit_boot_state:set(stopped),
Error;
Class:Exception:Stacktrace ->
mnesia:stop(),
@@ -977,7 +863,7 @@ start(normal, []) ->
Class, Exception, Stacktrace),
Error = {error, Exception},
rabbit_prelaunch:set_stop_reason(Error),
- rabbit_prelaunch:set_boot_state(stopped),
+ rabbit_boot_state:set(stopped),
Error
end.
@@ -1020,8 +906,7 @@ do_run_postlaunch_phase() ->
end, Plugins),
rabbit_log_prelaunch:debug("Marking RabbitMQ as running"),
- rabbit_prelaunch:set_boot_state(ready),
- maybe_sd_notify(),
+ rabbit_boot_state:set(ready),
ok = rabbit_lager:broker_is_started(),
ok = log_broker_started(
@@ -1040,7 +925,7 @@ do_run_postlaunch_phase() ->
end.
prep_stop(State) ->
- rabbit_prelaunch:set_boot_state(stopping),
+ rabbit_boot_state:set(stopping),
rabbit_peer_discovery:maybe_unregister(),
State.
@@ -1056,7 +941,7 @@ stop(State) ->
[] -> rabbit_prelaunch:set_stop_reason(normal);
_ -> rabbit_prelaunch:set_stop_reason(State)
end,
- rabbit_prelaunch:set_boot_state(stopped),
+ rabbit_boot_state:set(stopped),
ok.
%%---------------------------------------------------------------------------