systemd supports git-daemon's existing --inetd mode as well.

v2: actually test...
v3: make optional, switch to libsystemd

shawn@zephyr:~/git/git$ ldd /lib/x86_64-linux-gnu/libsystemd.so.0
        linux-vdso.so.1 (0x00007ffeba7ec000)
        libcap.so.2 => /lib/x86_64-linux-gnu/libcap.so.2 (0x00007fea158fe000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fea155f9000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fea153f0000)
        libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 
(0x00007fea151cb000)
        liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007fea14fa8000)
        libgcrypt.so.20 => /lib/x86_64-linux-gnu/libgcrypt.so.20 
(0x00007fea14cc5000)
        libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 
(0x00007fea14aae000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fea148aa000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 
(0x00007fea1468b000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fea142e7000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fea15d5b000)
        libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007fea140e2000)
        libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fea13e73000)
        libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 
(0x00007fea13c61000)

ewwwww...and only for two tiny functions.

Signed-off-by: Shawn Landden <sh...@churchofgit.com>
---
 Documentation/git-daemon.txt | 25 ++++++++++++++++++++++++
 Makefile                     | 14 ++++++++++++--
 daemon.c                     | 46 ++++++++++++++++++++++++++++++++++++++------
 3 files changed, 77 insertions(+), 8 deletions(-)

diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt
index a69b361..898e01f 100644
--- a/Documentation/git-daemon.txt
+++ b/Documentation/git-daemon.txt
@@ -20,6 +20,7 @@ SYNOPSIS
             [--inetd |
              [--listen=<host_or_ipaddr>] [--port=<n>]
              [--user=<user> [--group=<group>]]]
+             [--systemd]
             [<directory>...]
 
 DESCRIPTION
@@ -190,6 +191,12 @@ Git configuration files in that directory are readable by 
`<user>`.
        exiting with a zero status).  It can also look at the $REMOTE_ADDR
        and $REMOTE_PORT environment variables to learn about the
        requestor when making this decision.
+--systemd::
+       For running git-daemon under systemd(1) which will pass
+       an open connection. This is similar to --inetd, except
+       that more than one address/port can be listened to at once
+       both through systemd and through --listen, and git-daemon doesn't get
+       invoked for every connection. For more details see systemd.socket(5).
 +
 The external command can optionally write a single line to its
 standard output to be sent to the requestor as an error message when
@@ -304,7 +311,25 @@ selectively enable/disable services per repository::
                uploadpack = false
                uploadarch = true
 ----------------------------------------------------------------
++
+systemd configuration example:
+
+# /etc/systemd/system/git-daemon.socket
+[Unit]
+Description=Git Daemon socket
+
+[Socket]
+ListenStream=9418
+
+[Install]
+WantedBy=sockets.target
+# /etc/systemd/system/git-daemon.service
+[Unit]
+Description=Git Daemon
 
+[Service]
+ExecStart=/usr/lib/git-core/git-daemon --systemd --reuseaddr 
--base-path=/var/lib /var/lib/git
+User=gitdaemon
 
 ENVIRONMENT
 -----------
diff --git a/Makefile b/Makefile
index 5f3987f..362af94 100644
--- a/Makefile
+++ b/Makefile
@@ -42,6 +42,9 @@ all::
 # Define NO_EXPAT if you do not have expat installed.  git-http-push is
 # not built, and you cannot push using http:// and https:// transports (dumb).
 #
+# Define NO_SYSTEMD to prevent systemd socket activation support from being
+# built into git-daemon.
+#
 # Define EXPATDIR=/foo/bar if your expat header and library files are in
 # /foo/bar/include and /foo/bar/lib directories.
 #
@@ -995,6 +998,13 @@ ifeq ($(uname_S),Darwin)
        PTHREAD_LIBS =
 endif
 
+ifndef NO_SYSTEMD
+       ifeq ($(shell echo "\#include <systemd/sd-daemon.h>" | $(CC) -E - -o 
/dev/null && echo y),y)
+               BASIC_CFLAGS += -DHAVE_SYSTEMD
+               EXTLIBS += -lsystemd
+       endif
+endif
+
 ifndef CC_LD_DYNPATH
        ifdef NO_R_TO_GCC_LINKER
                # Some gcc does not accept and pass -R to the linker to specify
@@ -1403,8 +1413,8 @@ ifdef NATIVE_CRLF
 endif
 
 ifdef USE_NED_ALLOCATOR
-       COMPAT_CFLAGS += -Icompat/nedmalloc
-       COMPAT_OBJS += compat/nedmalloc/nedmalloc.o
+       COMPAT_CFLAGS += -Icompat/nedmalloc
+       COMPAT_OBJS += compat/nedmalloc/nedmalloc.o
 endif
 
 ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT
diff --git a/daemon.c b/daemon.c
index 9ee2187..16b9eda 100644
--- a/daemon.c
+++ b/daemon.c
@@ -1,3 +1,7 @@
+#ifdef HAVE_SYSTEMD
+#  include <systemd/sd-daemon.h>
+#endif
+
 #include "cache.h"
 #include "pkt-line.h"
 #include "exec_cmd.h"
@@ -29,6 +33,9 @@ static const char daemon_usage[] =
 "           [--access-hook=<path>]\n"
 "           [--inetd | [--listen=<host_or_ipaddr>] [--port=<n>]\n"
 "                      [--detach] [--user=<user> [--group=<group>]]\n"
+#ifdef HAVE_SYSTEMD
+"           [--systemd]\n"
+#endif
 "           [<directory>...]";
 
 /* List of acceptable pathname prefixes */
@@ -1176,11 +1183,24 @@ static void store_pid(const char *path)
 }
 
 static int serve(struct string_list *listen_addr, int listen_port,
-    struct credentials *cred)
+    struct credentials *cred, int systemd_mode)
 {
        struct socketlist socklist = { NULL, 0, 0 };
 
-       socksetup(listen_addr, listen_port, &socklist);
+#ifdef HAVE_SYSTEMD
+       if (systemd_mode) {
+               int i;
+               int n;
+
+               n = sd_listen_fds(0);
+               ALLOC_GROW(socklist.list, socklist.nr + n, socklist.alloc);
+               for (i = 0; i < n; i++)
+                       socklist.list[socklist.nr++] = SD_LISTEN_FDS_START + i;
+       }
+
+       if (listen_addr->nr > 0 || !systemd_mode)
+#endif
+               socksetup(listen_addr, listen_port, &socklist);
        if (socklist.nr == 0)
                die("unable to allocate any listen sockets on port %u",
                    listen_port);
@@ -1196,7 +1216,7 @@ int main(int argc, char **argv)
 {
        int listen_port = 0;
        struct string_list listen_addr = STRING_LIST_INIT_NODUP;
-       int serve_mode = 0, inetd_mode = 0;
+       int serve_mode = 0, inetd_mode = 0, systemd_mode = 0;
        const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
        int detach = 0;
        struct credentials *cred = NULL;
@@ -1331,6 +1351,12 @@ int main(int argc, char **argv)
                        informative_errors = 0;
                        continue;
                }
+#ifdef HAVE_SYSTEMD
+               if (!strcmp(arg, "--systemd")) {
+                       systemd_mode = 1;
+                       continue;
+               }
+#endif
                if (!strcmp(arg, "--")) {
                        ok_paths = &argv[i+1];
                        break;
@@ -1349,8 +1375,16 @@ int main(int argc, char **argv)
                /* avoid splitting a message in the middle */
                setvbuf(stderr, NULL, _IOFBF, 4096);
 
-       if (inetd_mode && (detach || group_name || user_name))
-               die("--detach, --user and --group are incompatible with 
--inetd");
+       if ((inetd_mode || systemd_mode) && (detach || group_name || user_name))
+               die("--detach, --user and --group are incompatible with --inetd 
and --systemd");
+
+#ifdef HAVE_SYSTEMD
+       if (systemd_mode && inetd_mode)
+               die("--inetd is incompatible with --systemd");
+
+       if (systemd_mode && !sd_booted())
+               die("--systemd passed and not invoked from systemd");
+#endif
 
        if (inetd_mode && (listen_port || (listen_addr.nr > 0)))
                die("--listen= and --port= are incompatible with --inetd");
@@ -1395,5 +1429,5 @@ int main(int argc, char **argv)
                cld_argv[i+1] = argv[i];
        cld_argv[argc+1] = NULL;
 
-       return serve(&listen_addr, listen_port, cred);
+       return serve(&listen_addr, listen_port, cred, systemd_mode);
 }
-- 
2.2.1.209.g41e5f3a

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to