From bbacc6024e474f4e7dd1387618209cab9524a95c Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Fri, 10 Feb 2017 16:16:55 +0100 Subject: [PATCH] tizen: notify service readyness after successful config file parsing This commit works around systemd -> dbus -> (nss) -> systemd deadlock occuring in Tizen. Situation is depicted on diagram below: systemd dbus nss | . . | . . 1> reads config . . | . . 2> reg. nofification . . | for dbus.service . . | . . | . . 3> exec. services . . | | . . | (start srv...) . . | | . . | 4>------------(exec) . | | . *-<---(notification)=<| . \ | . .\> call dbus.serv | . . handler | . . | 4a> read config . . |> conn. to bus | . . | 4b> resolve user . . |> call dbus . and groups . . \ . initgroups() . . ------------>. | . . (blocking) . \---------->select module . . (blocking) based on conf. . . | (below not executed) . |> security-manager . . | module selected . . | . . | [sec-manager.socket]<---------------------<| call security-manager . . (DEADLOCK) . on unix socket . . . Solid line (|) means active thread of execution, dot (.) means code not executed (blocked). The root cause of the problem is that systemd calls external API in blocking manner, which, due to system configuration, requires systemd to handle its request for successful completion. (systemd should start security-manager service via sec-manager.socket activation). The exact place this situation is triggered is in dbus' initialization. This commits works around this problem by delaying dbus.service readyness notification - effectively - resolving the problem. Situation becomes: systemd dbus nss security-manager | . . . | . . . 1> reads config . . . | . . . 2> reg. nofification . . . | for dbus.service . . . | . . . | . . . 3> exec. services . . . | | . . . | (start srv...) . . . | | . . . | 4>------------(exec) . . | | . . | | . . | | . . | | . . | | . . | 4a> read config . . | | . . | 4b> resolve user . . | . and groups . . | . initgroups() . . | . | . . | . \---------->select module . | . (blocking) based on conf. . | . | . | . |> security-manager . | . | module selected . | . | . | . | . [sec-manager.socket]<---------------------<| call security-manager . . | . . on unix socket . . | . . . |> exec service ----------------------------------------------->(exec) . | . . | <--| . |<-------------------------<| handle call | . | | | |<-----------------| | | | . | | | . | .\> call dbus.serv |>finish conf. file. | . handler | parsing . | . | | . | *-<---(notification)-<|> explicitly . | .\ | | notify startup . | . \> call dbus.serv | finished . | | handler | . | . | | . | . |> conn. to bus | . | . | | . | . |> call dbus | . | . \ | . | . ------------>* dispatch loop . | . (blocking) | . | . | . | |<--------------------< handle call . | | | . | Change-Id: Ifeaf299fc8653b583cd06ca9fd4f9f8045a2bde0 --- bus/dbus.service.in | 1 + bus/main.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/bus/dbus.service.in b/bus/dbus.service.in index e8662afd..126601ba 100644 --- a/bus/dbus.service.in +++ b/bus/dbus.service.in @@ -4,6 +4,7 @@ Documentation=man:dbus-daemon(1) Requires=dbus.socket [Service] +Type=notify ExecStart=@EXPANDED_BINDIR@/dbus-daemon --system --address=systemd: --nofork --systemd-activation ExecReload=@EXPANDED_BINDIR@/dbus-send --print-reply --system --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig OOMScoreAdjust=-900 diff --git a/bus/main.c b/bus/main.c index 9711c972..28ea39a1 100644 --- a/bus/main.c +++ b/bus/main.c @@ -42,6 +42,10 @@ #include "apparmor.h" #include "audit.h" +#ifdef HAVE_SYSTEMD +#include +#endif + static BusContext *context; #ifdef DBUS_UNIX @@ -657,6 +661,10 @@ main (int argc, char **argv) dbus_set_protocol_version (DBUS_MAJOR_PROTOCOL_VERSION); +#ifdef HAVE_SYSTEMD + sd_notify(0, "READY=1"); +#endif + _dbus_verbose ("We are on D-Bus...\n"); _dbus_loop_run (bus_context_get_loop (context)); -- 2.34.1