f7eb6dd
From: "Matwey V. Kornilov" <matwey.kornilov@gmail.com>
f7eb6dd
Date: Tue, 17 Dec 2013 18:57:54 +0400
f7eb6dd
Subject: [PATCH] Add systemd support to epmd
f7eb6dd
f7eb6dd
f7eb6dd
diff --git a/erts/configure.in b/erts/configure.in
f7eb6dd
index 125e579..d9bc1ec 100644
f7eb6dd
--- a/erts/configure.in
f7eb6dd
+++ b/erts/configure.in
f7eb6dd
@@ -969,6 +969,8 @@ AC_CHECK_LIB(dl, dlopen)
f7eb6dd
 AC_CHECK_LIB(inet, main)
f7eb6dd
 AC_CHECK_LIB(util, openpty)
f7eb6dd
 
f7eb6dd
+AC_CHECK_LIB(systemd-daemon, sd_listen_fds)
f7eb6dd
+
f7eb6dd
 dnl Try to find a thread library.
f7eb6dd
 dnl
f7eb6dd
 dnl ETHR_LIB_NAME, ETHR_LIBS, ETHR_X_LIBS, ETHR_THR_LIB_BASE and ETHR_DEFS
f7eb6dd
diff --git a/erts/epmd/src/epmd_int.h b/erts/epmd/src/epmd_int.h
f7eb6dd
index bf1ddd8..363923e 100644
f7eb6dd
--- a/erts/epmd/src/epmd_int.h
f7eb6dd
+++ b/erts/epmd/src/epmd_int.h
f7eb6dd
@@ -110,6 +110,10 @@
f7eb6dd
 
f7eb6dd
 #include <stdarg.h>
f7eb6dd
 
f7eb6dd
+#ifdef HAVE_SYSTEMD_SD_DAEMON_H
f7eb6dd
+#  include <systemd/sd-daemon.h>
f7eb6dd
+#endif
f7eb6dd
+
f7eb6dd
 /* ************************************************************************ */
f7eb6dd
 /* Replace some functions by others by making the function name a macro */
f7eb6dd
 
f7eb6dd
diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c
f7eb6dd
index 90df7cc..cb8ca96 100644
f7eb6dd
--- a/erts/epmd/src/epmd_srv.c
f7eb6dd
+++ b/erts/epmd/src/epmd_srv.c
f7eb6dd
@@ -208,6 +208,39 @@ void run(EpmdVars *g)
f7eb6dd
   node_init(g);
f7eb6dd
   g->conn = conn_init(g);
f7eb6dd
 
f7eb6dd
+#ifdef HAVE_SYSTEMD_SD_DAEMON_H
f7eb6dd
+  if (g->is_systemd)
f7eb6dd
+    {
f7eb6dd
+      int n;
f7eb6dd
+      
f7eb6dd
+      dbg_printf(g,2,"try to obtain sockets from systemd");
f7eb6dd
+
f7eb6dd
+      n = sd_listen_fds(0);
f7eb6dd
+      if (n < 0)
f7eb6dd
+        {
f7eb6dd
+          dbg_perror(g,"cannot obtain sockets from systemd");
f7eb6dd
+          epmd_cleanup_exit(g,1);
f7eb6dd
+        }
f7eb6dd
+      else if (n == 0)
f7eb6dd
+        {
f7eb6dd
+          dbg_tty_printf(g,0,"systemd provides no sockets");
f7eb6dd
+          epmd_cleanup_exit(g,1);
f7eb6dd
+      }
f7eb6dd
+      else if (n > MAX_LISTEN_SOCKETS)
f7eb6dd
+      {
f7eb6dd
+          dbg_tty_printf(g,0,"cannot listen on more than %d IP addresses", MAX_LISTEN_SOCKETS);
f7eb6dd
+          epmd_cleanup_exit(g,1);
f7eb6dd
+      } 
f7eb6dd
+      num_sockets = n;
f7eb6dd
+      for (i = 0; i < num_sockets; i++)
f7eb6dd
+        {
f7eb6dd
+          g->listenfd[i] = listensock[i] = SD_LISTEN_FDS_START + i;
f7eb6dd
+        }
f7eb6dd
+    }
f7eb6dd
+  else
f7eb6dd
+    {
f7eb6dd
+#endif
f7eb6dd
+
f7eb6dd
   dbg_printf(g,2,"try to initiate listening port %d", g->port);
f7eb6dd
 
f7eb6dd
   if (g->addresses != NULL && /* String contains non-separator characters if: */
f7eb6dd
@@ -272,6 +305,9 @@ void run(EpmdVars *g)
f7eb6dd
       SET_ADDR(iserv_addr[0],EPMD_ADDR_ANY,sport);
f7eb6dd
       num_sockets = 1;
f7eb6dd
     }
f7eb6dd
+#ifdef HAVE_SYSTEMD_SD_DAEMON_H
f7eb6dd
+    }
f7eb6dd
+#endif
f7eb6dd
 
f7eb6dd
 #if !defined(__WIN32__)
f7eb6dd
   /* We ignore the SIGPIPE signal that is raised when we call write
f7eb6dd
@@ -289,6 +325,13 @@ void run(EpmdVars *g)
f7eb6dd
   FD_ZERO(&g->orig_read_mask);
f7eb6dd
   g->select_fd_top = 0;
f7eb6dd
 
f7eb6dd
+#ifdef HAVE_SYSTEMD_SD_DAEMON_H
f7eb6dd
+  if (g->is_systemd)
f7eb6dd
+      for (i = 0; i < num_sockets; i++)
f7eb6dd
+          select_fd_set(g, listensock[i]);
f7eb6dd
+  else
f7eb6dd
+    {
f7eb6dd
+#endif
f7eb6dd
   for (i = 0; i < num_sockets; i++)
f7eb6dd
     {
f7eb6dd
       if ((listensock[i] = socket(FAMILY,SOCK_STREAM,0)) < 0)
f7eb6dd
@@ -351,6 +394,9 @@ void run(EpmdVars *g)
f7eb6dd
       }
f7eb6dd
       select_fd_set(g, listensock[i]);
f7eb6dd
     }
f7eb6dd
+#ifdef HAVE_SYSTEMD_SD_DAEMON_H 
f7eb6dd
+    }
f7eb6dd
+#endif
f7eb6dd
 
f7eb6dd
   dbg_tty_printf(g,2,"entering the main select() loop");
f7eb6dd