mctp-demux-daemon: Use systemd socket activation

Take advantage of lazy initialisation.

However, this also allows (one) daemon providing services over MCTP
(pldmd) an opportunity to start prior to MCTP interfaces coming up. This
is a stunted way to provide capabilities that might be assumed by other
components (the host) without implementing some required messages from
the MCTP standard.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Change-Id: I4b1c21f4fd42f84e2c85a453570a74330fc70ecf
diff --git a/Makefile.am b/Makefile.am
index f4c8017..5306074 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -18,7 +18,8 @@
 
 if HAVE_SYSTEMD
 systemdsystemunit_DATA = \
-	systemd/system/mctp-demux.service
+	systemd/system/mctp-demux.service \
+	systemd/system/mctp-demux.socket
 endif
 
 bin_PROGRAMS = utils/mctp-demux-daemon
diff --git a/configure.ac b/configure.ac
index 1e8a419..bbdc7b7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -48,6 +48,12 @@
            [with_systemdsystemunitdir="$def_systemdsystemunitdir"]
      )]
 )
+
+AC_CHECK_HEADER([systemd/sd-daemon.h],
+                [AC_DEFINE([HAVE_SYSTEMD_SD_DAEMON_H], [1],
+                           [Define to 1 if you have <systemd/sd-daemon.h>.])],
+                [])
+AC_CHECK_LIB([systemd], [sd_listen_fds])
 AS_IF([test "x$with_systemdsystemunitdir" != "xno"],
       [AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])]
 )
diff --git a/systemd/system/mctp-demux.service b/systemd/system/mctp-demux.service
index c13e871..afe70bf 100644
--- a/systemd/system/mctp-demux.service
+++ b/systemd/system/mctp-demux.service
@@ -1,7 +1,5 @@
 [Unit]
 Description=MCTP demultiplexer daemon
-Wants=pldmd.service
-Before=pldmd.service
 
 [Service]
 Restart=always
@@ -9,6 +7,3 @@
 EnvironmentFile=-/etc/default/mctp
 ExecStart=/usr/bin/mctp-demux-daemon $DEMUX_BINDING_OPTS
 SyslogIdentifier=mctp-demux
-
-[Install]
-WantedBy=multi-user.target
diff --git a/systemd/system/mctp-demux.socket b/systemd/system/mctp-demux.socket
new file mode 100644
index 0000000..8b42b5d
--- /dev/null
+++ b/systemd/system/mctp-demux.socket
@@ -0,0 +1,9 @@
+[Unit]
+Description=MCTP demux Unix domain socket
+
+[Socket]
+ListenSequentialPacket=@mctp-mux
+Accept=no
+
+[Install]
+WantedBy=sockets.target
diff --git a/utils/mctp-demux-daemon.c b/utils/mctp-demux-daemon.c
index 0774350..4467fe3 100644
--- a/utils/mctp-demux-daemon.c
+++ b/utils/mctp-demux-daemon.c
@@ -2,6 +2,8 @@
 
 #define _GNU_SOURCE
 
+#include "config.h"
+
 #include <assert.h>
 #include <err.h>
 #include <errno.h>
@@ -17,6 +19,8 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 
+#define SD_LISTEN_FDS_START 3
+
 #include "libmctp.h"
 #include "libmctp-serial.h"
 #include "libmctp-astlpc.h"
@@ -24,6 +28,15 @@
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 #define __unused __attribute__((unused))
 
+#if HAVE_SYSTEMD_SD_DAEMON_H
+#include <systemd/sd-daemon.h>
+#else
+static inline int sd_listen_fds(int i __unused)
+{
+	return -1;
+}
+#endif
+
 static const mctp_eid_t local_eid_default = 8;
 static char sockname[] = "\0mctp-mux";
 
@@ -551,9 +564,14 @@
 	if (rc)
 		return EXIT_FAILURE;
 
-	rc = socket_init(ctx);
-	if (rc)
-		return EXIT_FAILURE;
+	rc = sd_listen_fds(true);
+	if (rc <= 0) {
+		rc = socket_init(ctx);
+		if (rc)
+			return EXIT_FAILURE;
+	} else {
+		ctx->sock = SD_LISTEN_FDS_START;
+	}
 
 	rc = run_daemon(ctx);