[gnome-keyring/wip/dueno/systemd] daemon: Make it systemd-activatable through the control socket




commit d3960931b1d254c1d98cc1dcbeae288459325d44
Author: Daiki Ueno <dueno src gnome org>
Date:   Fri Feb 12 10:14:24 2021 +0100

    daemon: Make it systemd-activatable through the control socket

 configure.ac                           | 25 ++++++++++++++
 daemon/Makefile.am                     | 14 ++++++++
 daemon/control/gkd-control-server.c    | 60 ++++++++++++++++++++++------------
 daemon/gnome-keyring-daemon.service.in | 14 ++++++++
 daemon/gnome-keyring-daemon.socket     | 11 +++++++
 5 files changed, 103 insertions(+), 21 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 5eebff23..f7bbb6cf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -434,6 +434,30 @@ fi
 AC_SUBST(LIBSELINUX)
 AM_CONDITIONAL([HAVE_LIBSELINUX], [test ! -z "$LIBSELINUX"])
 
+# ----------------------------------------------------------------------
+# systemd
+
+AC_ARG_WITH([systemd],
+            AS_HELP_STRING([--without-systemd],
+                           [Disable systemd socket activation]))
+
+AS_IF([test "$with_systemd" != "no"], [
+       PKG_CHECK_MODULES([LIBSYSTEMD], [libsystemd], [],
+               [with_systemd=no])
+
+       PKG_CHECK_VAR([systemduserunitdir], [systemd], [systemduserunitdir], [],
+               [with_systemd=no])
+
+       AS_IF([test "$with_systemd" != "no"], [
+               with_systemd=yes
+               AC_DEFINE_UNQUOTED(WITH_SYSTEMD, 1, [Build with systemd socket activation])
+               DAEMON_CFLAGS="$DAEMON_CFLAGS $LIBSYSTEMD_CFLAGS"
+               DAEMON_LIBS="$DAEMON_LIBS $LIBSYSTEMD_LIBS"
+       ])
+])
+
+AM_CONDITIONAL(WITH_SYSTEMD, [test "$with_systemd" = "yes"])
+
 # ----------------------------------------------------------------------
 # dotlock.c support
 
@@ -662,6 +686,7 @@ echo "OPTIONAL DEPENDENCIES"
 echo "  PAM:                  $pam_status"
 echo "  Linux capabilities:   $libcapng_status"
 echo "  SELinux:              $selinux_status"
+echo "  systemd:              $with_systemd"
 echo
 echo "CONFIGURATION"
 echo "  SSH Agent:            $ssh_status"
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 60b2f794..910f0095 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -37,6 +37,20 @@ service_in_files = \
 servicedir = $(DBUS_SERVICES_DIR)
 service_DATA = $(service_in_files:.service.in=.service)
 
+if WITH_SYSTEMD
+daemon/gnome-keyring-daemon.service: daemon/gnome-keyring-daemon.service.in
+       $(AM_V_GEN)rm -f $@-t $@ && \
+       sed 's|@bindir[@]|$(bindir)|g' $< > $@-t && \
+       mv -f $@-t $@
+
+CLEANFILES += daemon/gnome-keyring-daemon.service
+
+systemduserunit_DATA = \
+       daemon/gnome-keyring-daemon.socket \
+       daemon/gnome-keyring-daemon.service \
+       $(NULL)
+endif
+
 desktopdir = $(sysconfdir)/xdg/autostart
 desktop_in_in_files = \
        daemon/gnome-keyring-pkcs11.desktop.in.in \
diff --git a/daemon/control/gkd-control-server.c b/daemon/control/gkd-control-server.c
index 11254feb..5ef307d6 100644
--- a/daemon/control/gkd-control-server.c
+++ b/daemon/control/gkd-control-server.c
@@ -41,6 +41,10 @@
 #include <sys/types.h>
 #include <sys/un.h>
 
+#ifdef WITH_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
 typedef struct _ControlData {
        EggBuffer buffer;
        gsize position;
@@ -401,34 +405,48 @@ gkd_control_stop (void)
 gboolean
 gkd_control_listen (void)
 {
-       struct sockaddr_un addr;
        GIOChannel *channel;
        int sock;
 
-       control_path = g_strdup_printf ("%s/control", gkd_util_get_master_directory ());
-       egg_cleanup_register ((GDestroyNotify)gkd_control_stop, NULL);
+#ifdef WITH_SYSTEMD
+       int res;
 
-       unlink (control_path);
-
-       sock = socket (AF_UNIX, SOCK_STREAM, 0);
-       if (sock < 0) {
-               g_warning ("couldn't open socket: %s", g_strerror (errno));
+       res = sd_listen_fds (0);
+       if (res > 1) {
+               g_message ("too many file descriptors received");
                return FALSE;
-       }
+       } else if (res == 1) {
+               sock = SD_LISTEN_FDS_START + 0;
+       } else
+#endif
+       {
+               struct sockaddr_un addr;
 
-       memset (&addr, 0, sizeof (addr));
-       addr.sun_family = AF_UNIX;
-       g_strlcpy (addr.sun_path, control_path, sizeof (addr.sun_path));
-       if (bind (sock, (struct sockaddr*) &addr, sizeof (addr)) < 0) {
-               g_warning ("couldn't bind to control socket: %s: %s", control_path, g_strerror (errno));
-               close (sock);
-               return FALSE;
-       }
+               control_path = g_strdup_printf ("%s/control", gkd_util_get_master_directory ());
+               egg_cleanup_register ((GDestroyNotify)gkd_control_stop, NULL);
 
-       if (listen (sock, 128) < 0) {
-               g_warning ("couldn't listen on control socket: %s: %s", control_path, g_strerror (errno));
-               close (sock);
-               return FALSE;
+               unlink (control_path);
+
+               sock = socket (AF_UNIX, SOCK_STREAM, 0);
+               if (sock < 0) {
+                       g_warning ("couldn't open socket: %s", g_strerror (errno));
+                       return FALSE;
+               }
+
+               memset (&addr, 0, sizeof (addr));
+               addr.sun_family = AF_UNIX;
+               g_strlcpy (addr.sun_path, control_path, sizeof (addr.sun_path));
+               if (bind (sock, (struct sockaddr*) &addr, sizeof (addr)) < 0) {
+                       g_warning ("couldn't bind to control socket: %s: %s", control_path, g_strerror 
(errno));
+                       close (sock);
+                       return FALSE;
+               }
+
+               if (listen (sock, 128) < 0) {
+                       g_warning ("couldn't listen on control socket: %s: %s", control_path, g_strerror 
(errno));
+                       close (sock);
+                       return FALSE;
+               }
        }
 
        if (egg_unix_credentials_setup (sock) < 0) {
diff --git a/daemon/gnome-keyring-daemon.service.in b/daemon/gnome-keyring-daemon.service.in
new file mode 100644
index 00000000..ae24c978
--- /dev/null
+++ b/daemon/gnome-keyring-daemon.service.in
@@ -0,0 +1,14 @@
+[Unit]
+Description=GNOME Keyring daemon
+
+Requires=gnome-keyring-daemon.socket
+
+[Service]
+Type=simple
+StandardError=journal
+ExecStart=@bindir@/gnome-keyring-daemon --start --foreground --components="pkcs11,secrets"
+Restart=on-failure
+
+[Install]
+Also=gnome-keyring-daemon.socket
+WantedBy=default.target
diff --git a/daemon/gnome-keyring-daemon.socket b/daemon/gnome-keyring-daemon.socket
new file mode 100644
index 00000000..13b06fb8
--- /dev/null
+++ b/daemon/gnome-keyring-daemon.socket
@@ -0,0 +1,11 @@
+[Unit]
+Description=GNOME Keyring daemon
+
+[Socket]
+Priority=6
+Backlog=5
+ListenStream=%t/keyring/control
+SocketMode=0600
+
+[Install]
+WantedBy=sockets.target


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]