aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/configure.in4
-rw-r--r--erts/epmd/src/epmd.c16
-rw-r--r--erts/epmd/src/epmd_int.h6
-rw-r--r--erts/epmd/src/epmd_srv.c46
4 files changed, 70 insertions, 2 deletions
diff --git a/erts/configure.in b/erts/configure.in
index 208c294106..9ebb56e3bc 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -1042,6 +1042,8 @@ AC_CHECK_LIB(dl, dlopen)
AC_CHECK_LIB(inet, main)
AC_CHECK_LIB(util, openpty)
+AC_CHECK_LIB(systemd-daemon, sd_listen_fds)
+
dnl Try to find a thread library.
dnl
dnl ETHR_LIB_NAME, ETHR_LIBS, ETHR_X_LIBS, ETHR_THR_LIB_BASE and ETHR_DEFS
@@ -1677,6 +1679,8 @@ AC_CHECK_MEMBERS([struct ifreq.ifr_enaddr], [], [],
#endif
])
+AC_CHECK_HEADERS(systemd/sd-daemon.h)
+
dnl ----------------------------------------------------------------------
dnl Check the availability for libdlpi
dnl ----------------------------------------------------------------------
diff --git a/erts/epmd/src/epmd.c b/erts/epmd/src/epmd.c
index 1678d537d1..3cfa7a782f 100644
--- a/erts/epmd/src/epmd.c
+++ b/erts/epmd/src/epmd.c
@@ -175,6 +175,9 @@ int main(int argc, char** argv)
g->nodes.reg = g->nodes.unreg = g->nodes.unreg_tail = NULL;
g->nodes.unreg_count = 0;
g->active_conn = 0;
+#ifdef HAVE_SYSTEMD_SD_DAEMON_H
+ g->is_systemd = 0;
+#endif
for (i = 0; i < MAX_LISTEN_SOCKETS; i++)
g->listenfd[i] = -1;
@@ -248,8 +251,12 @@ int main(int argc, char** argv)
else
usage(g);
epmd_cleanup_exit(g,0);
- }
- else
+#ifdef HAVE_SYSTEMD_SD_DAEMON_H
+ } else if (strcmp(argv[0], "-systemd") == 0) {
+ g->is_systemd = 1;
+ argv++; argc--;
+#endif
+ } else
usage(g);
}
dbg_printf(g,1,"epmd running - daemon = %d",g->is_daemon);
@@ -454,6 +461,11 @@ static void usage(EpmdVars *g)
fprintf(stderr, " Forcibly unregisters a name with epmd\n");
fprintf(stderr, " (only allowed if -relaxed_command_check was given when \n");
fprintf(stderr, " epmd was started).\n");
+#ifdef HAVE_SYSTEMD_SD_DAEMON_H
+ fprintf(stderr, " -systemd\n");
+ fprintf(stderr, " Wait for socket from systemd. The option makes sense\n");
+ fprintf(stderr, " when started from .socket unit.\n");
+#endif
epmd_cleanup_exit(g,1);
}
diff --git a/erts/epmd/src/epmd_int.h b/erts/epmd/src/epmd_int.h
index d4597be30c..c8f2192f7f 100644
--- a/erts/epmd/src/epmd_int.h
+++ b/erts/epmd/src/epmd_int.h
@@ -125,6 +125,9 @@
# include "sys/select.h"
#endif
+#ifdef HAVE_SYSTEMD_SD_DAEMON_H
+# include <systemd/sd-daemon.h>
+#endif
/* ************************************************************************ */
/* Replace some functions by others by making the function name a macro */
@@ -337,6 +340,9 @@ typedef struct {
int listenfd[MAX_LISTEN_SOCKETS];
char *addresses;
char **argv;
+#ifdef HAVE_SYSTEMD_SD_DAEMON_H
+ int is_systemd;
+#endif
} EpmdVars;
void dbg_printf(EpmdVars*,int,const char*,...);
diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c
index 247fd34d5a..93982c2f60 100644
--- a/erts/epmd/src/epmd_srv.c
+++ b/erts/epmd/src/epmd_srv.c
@@ -213,6 +213,39 @@ void run(EpmdVars *g)
node_init(g);
g->conn = conn_init(g);
+#ifdef HAVE_SYSTEMD_SD_DAEMON_H
+ if (g->is_systemd)
+ {
+ int n;
+
+ dbg_printf(g,2,"try to obtain sockets from systemd");
+
+ n = sd_listen_fds(0);
+ if (n < 0)
+ {
+ dbg_perror(g,"cannot obtain sockets from systemd");
+ epmd_cleanup_exit(g,1);
+ }
+ else if (n == 0)
+ {
+ dbg_tty_printf(g,0,"systemd provides no sockets");
+ epmd_cleanup_exit(g,1);
+ }
+ else if (n > MAX_LISTEN_SOCKETS)
+ {
+ dbg_tty_printf(g,0,"cannot listen on more than %d IP addresses", MAX_LISTEN_SOCKETS);
+ epmd_cleanup_exit(g,1);
+ }
+ num_sockets = n;
+ for (i = 0; i < num_sockets; i++)
+ {
+ g->listenfd[i] = listensock[i] = SD_LISTEN_FDS_START + i;
+ }
+ }
+ else
+ {
+#endif
+
dbg_printf(g,2,"try to initiate listening port %d", g->port);
if (g->addresses != NULL && /* String contains non-separator characters if: */
@@ -277,6 +310,9 @@ void run(EpmdVars *g)
SET_ADDR(iserv_addr[0],EPMD_ADDR_ANY,sport);
num_sockets = 1;
}
+#ifdef HAVE_SYSTEMD_SD_DAEMON_H
+ }
+#endif
#if !defined(__WIN32__) && !defined(__OSE__)
/* We ignore the SIGPIPE signal that is raised when we call write
@@ -294,6 +330,13 @@ void run(EpmdVars *g)
FD_ZERO(&g->orig_read_mask);
g->select_fd_top = 0;
+#ifdef HAVE_SYSTEMD_SD_DAEMON_H
+ if (g->is_systemd)
+ for (i = 0; i < num_sockets; i++)
+ select_fd_set(g, listensock[i]);
+ else
+ {
+#endif
for (i = 0; i < num_sockets; i++)
{
if ((listensock[i] = socket(FAMILY,SOCK_STREAM,0)) < 0)
@@ -356,6 +399,9 @@ void run(EpmdVars *g)
}
select_fd_set(g, listensock[i]);
}
+#ifdef HAVE_SYSTEMD_SD_DAEMON_H
+ }
+#endif
dbg_tty_printf(g,2,"entering the main select() loop");