tizen: notify service readyness after successful config file parsing 57/115757/1
authorKarol Lewandowski <k.lewandowsk@samsung.com>
Fri, 10 Feb 2017 15:16:55 +0000 (16:16 +0100)
committerHyotaek Shim <hyotaek.shim@samsung.com>
Tue, 21 Feb 2017 08:05:35 +0000 (00:05 -0800)
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
bus/main.c

index e8662af..126601b 100644 (file)
@@ -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
index 9711c97..28ea39a 100644 (file)
 #include "apparmor.h"
 #include "audit.h"
 
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#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));