|
|
f8bec4 |
From: Peter Lemenkov <lemenkov@gmail.com>
|
|
|
f8bec4 |
Date: Thu, 19 May 2016 16:04:56 +0300
|
|
|
f8bec4 |
Subject: [PATCH] Remove excessive sd_notify code
|
|
|
f8bec4 |
|
|
|
f8bec4 |
Signed-off-by: Peter Lemenkov <lemenkov@gmail.com>
|
|
|
f8bec4 |
|
|
|
f8bec4 |
diff --git a/src/rabbit.erl b/src/rabbit.erl
|
|
|
4e8069 |
index a86fd97..32ff240 100644
|
|
|
f8bec4 |
--- a/src/rabbit.erl
|
|
|
f8bec4 |
+++ b/src/rabbit.erl
|
|
|
4e8069 |
@@ -280,120 +280,8 @@ broker_start() ->
|
|
|
f8bec4 |
Plugins = rabbit_plugins:setup(),
|
|
|
f8bec4 |
ToBeLoaded = Plugins ++ ?APPS,
|
|
|
f8bec4 |
start_apps(ToBeLoaded),
|
|
|
f8bec4 |
- maybe_sd_notify(),
|
|
|
f8bec4 |
ok = log_broker_started(rabbit_plugins:active()).
|
|
|
f8bec4 |
|
|
|
f8bec4 |
-%% Try to send systemd ready notification if it makes sense in the
|
|
|
f8bec4 |
-%% current environment. standard_error is used intentionally in all
|
|
|
f8bec4 |
-%% logging statements, so all this messages will end in systemd
|
|
|
f8bec4 |
-%% journal.
|
|
|
f8bec4 |
-maybe_sd_notify() ->
|
|
|
f8bec4 |
- case sd_notify_ready() of
|
|
|
f8bec4 |
- false ->
|
|
|
f8bec4 |
- io:format(standard_error, "systemd READY notification failed, beware of timeouts~n", []);
|
|
|
f8bec4 |
- _ ->
|
|
|
f8bec4 |
- ok
|
|
|
f8bec4 |
- end.
|
|
|
f8bec4 |
-
|
|
|
f8bec4 |
-sd_notify_ready() ->
|
|
|
f8bec4 |
- case {os:type(), os:getenv("NOTIFY_SOCKET")} of
|
|
|
f8bec4 |
- {{win32, _}, _} ->
|
|
|
f8bec4 |
- true;
|
|
|
f8bec4 |
- {_, [_|_]} -> %% Non-empty NOTIFY_SOCKET, give it a try
|
|
|
f8bec4 |
- sd_notify_legacy() orelse sd_notify_socat();
|
|
|
f8bec4 |
- _ ->
|
|
|
f8bec4 |
- true
|
|
|
f8bec4 |
- end.
|
|
|
f8bec4 |
-
|
|
|
f8bec4 |
-sd_notify_data() ->
|
|
|
f8bec4 |
- "READY=1\nSTATUS=Initialized\nMAINPID=" ++ os:getpid() ++ "\n".
|
|
|
f8bec4 |
-
|
|
|
f8bec4 |
-sd_notify_legacy() ->
|
|
|
f8bec4 |
- case code:load_file(sd_notify) of
|
|
|
f8bec4 |
- {module, sd_notify} ->
|
|
|
f8bec4 |
- SDNotify = sd_notify,
|
|
|
f8bec4 |
- SDNotify:sd_notify(0, sd_notify_data()),
|
|
|
f8bec4 |
- true;
|
|
|
f8bec4 |
- {error, _} ->
|
|
|
f8bec4 |
- false
|
|
|
f8bec4 |
- end.
|
|
|
f8bec4 |
-
|
|
|
f8bec4 |
-%% socat(1) is the most portable way the sd_notify could be
|
|
|
f8bec4 |
-%% implemented in erlang, without introducing some NIF. Currently the
|
|
|
f8bec4 |
-%% following issues prevent us from implementing it in a more
|
|
|
f8bec4 |
-%% reasonable way:
|
|
|
f8bec4 |
-%% - systemd-notify(1) is unstable for non-root users
|
|
|
f8bec4 |
-%% - erlang doesn't support unix domain sockets.
|
|
|
f8bec4 |
-%%
|
|
|
f8bec4 |
-%% Some details on how we ended with such a solution:
|
|
|
f8bec4 |
-%% https://github.com/rabbitmq/rabbitmq-server/issues/664
|
|
|
f8bec4 |
-sd_notify_socat() ->
|
|
|
f8bec4 |
- case sd_current_unit() of
|
|
|
f8bec4 |
- {ok, Unit} ->
|
|
|
f8bec4 |
- io:format(standard_error, "systemd unit for activation check: \"~s\"~n", [Unit]),
|
|
|
f8bec4 |
- sd_notify_socat(Unit);
|
|
|
f8bec4 |
- _ ->
|
|
|
f8bec4 |
- false
|
|
|
f8bec4 |
- end.
|
|
|
f8bec4 |
-
|
|
|
f8bec4 |
-socat_socket_arg("@" ++ AbstractUnixSocket) ->
|
|
|
f8bec4 |
- "abstract-sendto:" ++ AbstractUnixSocket;
|
|
|
f8bec4 |
-socat_socket_arg(UnixSocket) ->
|
|
|
f8bec4 |
- "unix-sendto:" ++ UnixSocket.
|
|
|
f8bec4 |
-
|
|
|
f8bec4 |
-sd_open_port() ->
|
|
|
f8bec4 |
- open_port(
|
|
|
f8bec4 |
- {spawn_executable, os:find_executable("socat")},
|
|
|
f8bec4 |
- [{args, [socat_socket_arg(os:getenv("NOTIFY_SOCKET")), "STDIO"]},
|
|
|
f8bec4 |
- use_stdio, out]).
|
|
|
f8bec4 |
-
|
|
|
f8bec4 |
-sd_notify_socat(Unit) ->
|
|
|
f8bec4 |
- case sd_open_port() of
|
|
|
f8bec4 |
- {'EXIT', Exit} ->
|
|
|
f8bec4 |
- io:format(standard_error, "Failed to start socat ~p~n", [Exit]),
|
|
|
f8bec4 |
- false;
|
|
|
f8bec4 |
- Port ->
|
|
|
f8bec4 |
- Port ! {self(), {command, sd_notify_data()}},
|
|
|
f8bec4 |
- Result = sd_wait_activation(Port, Unit),
|
|
|
f8bec4 |
- port_close(Port),
|
|
|
f8bec4 |
- Result
|
|
|
f8bec4 |
- end.
|
|
|
f8bec4 |
-
|
|
|
f8bec4 |
-sd_current_unit() ->
|
|
|
f8bec4 |
- case catch re:run(os:cmd("systemctl status " ++ os:getpid()), "([-.@0-9a-zA-Z]+)", [unicode, {capture, all_but_first, list}]) of
|
|
|
f8bec4 |
- {'EXIT', _} ->
|
|
|
f8bec4 |
- error;
|
|
|
f8bec4 |
- {match, [Unit]} ->
|
|
|
f8bec4 |
- {ok, Unit};
|
|
|
f8bec4 |
- _ ->
|
|
|
f8bec4 |
- error
|
|
|
f8bec4 |
- end.
|
|
|
f8bec4 |
-
|
|
|
f8bec4 |
-sd_wait_activation(Port, Unit) ->
|
|
|
f8bec4 |
- case os:find_executable("systemctl") of
|
|
|
f8bec4 |
- false ->
|
|
|
f8bec4 |
- io:format(standard_error, "'systemctl' unavailable, falling back to sleep~n", []),
|
|
|
f8bec4 |
- timer:sleep(5000),
|
|
|
f8bec4 |
- true;
|
|
|
f8bec4 |
- _ ->
|
|
|
f8bec4 |
- sd_wait_activation(Port, Unit, 10)
|
|
|
f8bec4 |
- end.
|
|
|
f8bec4 |
-
|
|
|
f8bec4 |
-sd_wait_activation(_, _, 0) ->
|
|
|
f8bec4 |
- io:format(standard_error, "Service still in 'activating' state, bailing out~n", []),
|
|
|
f8bec4 |
- false;
|
|
|
f8bec4 |
-sd_wait_activation(Port, Unit, AttemptsLeft) ->
|
|
|
f8bec4 |
- case os:cmd("systemctl show --property=ActiveState " ++ Unit) of
|
|
|
f8bec4 |
- "ActiveState=activating\n" ->
|
|
|
f8bec4 |
- timer:sleep(1000),
|
|
|
f8bec4 |
- sd_wait_activation(Port, Unit, AttemptsLeft - 1);
|
|
|
f8bec4 |
- "ActiveState=" ++ _ ->
|
|
|
f8bec4 |
- true;
|
|
|
f8bec4 |
- _ = Err->
|
|
|
f8bec4 |
- io:format(standard_error, "Unexpected status from systemd ~p~n", [Err]),
|
|
|
f8bec4 |
- false
|
|
|
f8bec4 |
- end.
|
|
|
f8bec4 |
-
|
|
|
f8bec4 |
start_it(StartFun) ->
|
|
|
f8bec4 |
Marker = spawn_link(fun() -> receive stop -> ok end end),
|
|
|
f8bec4 |
case catch register(rabbit_boot, Marker) of
|