systemd: take over sockets created by systemd
authorFriedrich, Eugen (ADITG/SW1) <efriedrich@de.adit-jv.com>
Tue, 5 Apr 2016 20:43:29 +0000 (20:43 +0000)
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>
Wed, 6 Apr 2016 11:12:02 +0000 (14:12 +0300)
Systemd provides a feature of socket-based activation, details in [1]
This commit adds an implementation to check if sockets were provided by
systemd and adds this as an additional socket to wayland display.
before adding sockets are checked for the correctness:
only AF_UNIX of type SOCK_STREAM are accepted

This is usefull for early rendering use-cases where weston and
early-rendering-application can be started parallel.

[1] https://www.freedesktop.org/software/systemd/man/systemd.socket.html

Signed-off-by: Eugen Friedrich <efriedrich@de.adit-jv.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
configure.ac
src/systemd-notify.c

index 9e8115a7f310c539d782e70b723952abd3944415..447cf6b2bff260a090a97b44d68253e595e2e9b6 100644 (file)
@@ -634,7 +634,10 @@ AC_ARG_ENABLE(systemd_notify,
               AS_HELP_STRING([--enable-systemd-notify],
                              [Enables systemd notifications to
                               notify systemd about weston state
-                              and update watchdog.]),,
+                              and update watchdog.
+                              Also sockets provided by systemd
+                              in case of socket-base activation
+                              are added to wayland display]),,
               enable_systemd_notify=no)
 AM_CONDITIONAL(SYSTEMD_NOTIFY_SUPPORT, test x$enable_systemd_notify = xyes)
 if test "x$enable_systemd_notify" = "xyes"; then
index e61db0fbb7894e790cf8d22c6dd7a01e0948b615..4407059719090b787552b807b06a4489eee1f2be 100644 (file)
@@ -28,6 +28,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <systemd/sd-daemon.h>
+#include <sys/socket.h>
 #include <wayland-server.h>
 #include "shared/helpers.h"
 #include "shared/zalloc.h"
@@ -39,6 +40,47 @@ struct systemd_notifier {
        struct wl_listener compositor_destroy_listener;
 };
 
+static int
+add_systemd_sockets(struct weston_compositor *compositor)
+{
+       int fd;
+       int cnt_systemd_sockets;
+       int current_fd = 0;
+
+       cnt_systemd_sockets = sd_listen_fds(1);
+
+       if (cnt_systemd_sockets < 0) {
+               weston_log("sd_listen_fds failed with: %d\n",
+                               cnt_systemd_sockets);
+               return -1;
+       }
+
+       /* socket-based activation not used, return silently */
+       if (cnt_systemd_sockets == 0)
+               return 0;
+
+       while (current_fd < cnt_systemd_sockets) {
+               fd = SD_LISTEN_FDS_START + current_fd;
+
+               if (sd_is_socket(fd, AF_UNIX, SOCK_STREAM,1) <= 0) {
+                       weston_log("invalid socket provided from systemd\n");
+                       return -1;
+               }
+
+               if (wl_display_add_socket_fd(compositor->wl_display, fd)) {
+                       weston_log("wl_display_add_socket_fd failed"
+                                       "for systemd provided socket\n");
+                       return -1;
+               }
+               current_fd++;
+       }
+
+       weston_log("info: add %d socket(s) provided by systemd\n",
+                       current_fd);
+
+       return current_fd;
+}
+
 static int
 watchdog_handler(void *data)
 {
@@ -89,6 +131,9 @@ module_init(struct weston_compositor *compositor,
        wl_signal_add(&compositor->destroy_signal,
                      &notifier->compositor_destroy_listener);
 
+       if (add_systemd_sockets(compositor) < 0)
+               return -1;
+
        sd_notify(0, "READY=1");
 
        /* 'WATCHDOG_USEC' is environment variable that is set