Support systemd socket activation
Check if systemd passed us a socket when starting obmc-console before
creating the socket ourselves. This will support use cases where we
don't need obmc-console until a SoL is activated by the user.
Tested: Verified that existing unit file installation is unchanged -
statically enabled obmc-console@.service instances will be started.
Then disabled obmc-console@ttyS2.service and enabled
obmc-console@ttyS2.socket (with a drop-in change to override
ListenStream to "obmc-console") and verifed that activating Redfish and
SSH SoL would start obmc-console@ttyS2.service and console redirection
worked.
Change-Id: I42e96af46a5893145abf27761e97fd4f1b73719d
Signed-off-by: Jonathan Doman <jonathan.doman@intel.com>
diff --git a/Makefile.am b/Makefile.am
index 2ee97a2..696fec9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -11,6 +11,7 @@
if WITH_SYSTEMD
systemdsystemunit_DATA = conf/obmc-console@.service \
+ conf/obmc-console@.socket \
conf/obmc-console-ssh@.service
if ENABLE_CONCURRENT_SERVERS
diff --git a/conf/obmc-console@.socket.in b/conf/obmc-console@.socket.in
new file mode 100644
index 0000000..6f374c4
--- /dev/null
+++ b/conf/obmc-console@.socket.in
@@ -0,0 +1,10 @@
+[Unit]
+Description=Console server domain socket listener
+
+[Socket]
+ListenStream=@obmc-console.%i
+Accept=no
+Service=obmc-console@%i.service
+
+[Install]
+WantedBy=sockets.target
diff --git a/configure.ac b/configure.ac
index 045ea36..6b0fb98 100644
--- a/configure.ac
+++ b/configure.ac
@@ -74,6 +74,7 @@
conf/80-obmc-console-uart.rules
conf/client.2200.conf
conf/obmc-console@.service
+ conf/obmc-console@.socket
conf/obmc-console-ssh@.service
conf/obmc-console-ssh@.service.d/use-socket.conf
conf/obmc-console-ssh.socket
diff --git a/socket-handler.c b/socket-handler.c
index a11ab24..42690be 100644
--- a/socket-handler.c
+++ b/socket-handler.c
@@ -29,6 +29,7 @@
#include <sys/socket.h>
#include <sys/un.h>
+#include <systemd/sd-daemon.h>
#include "console-server.h"
@@ -314,12 +315,6 @@
sh->clients = NULL;
sh->n_clients = 0;
- sh->sd = socket(AF_UNIX, SOCK_STREAM, 0);
- if(sh->sd < 0) {
- warn("Can't create socket");
- return -1;
- }
-
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
len = console_socket_path(&addr, config_get_value(config, "socket-id"));
@@ -328,24 +323,36 @@
warn("Failed to configure socket: %s", strerror(errno));
else
warn("Socket name length exceeds buffer limits");
- goto cleanup;
+ return -1;
}
- addrlen = sizeof(addr) - sizeof(addr.sun_path) + len;
+ /* Try to take a socket from systemd first */
+ if (sd_listen_fds(0) == 1 &&
+ sd_is_socket_unix(SD_LISTEN_FDS_START, SOCK_STREAM, 1, addr.sun_path, len) > 0) {
+ sh->sd = SD_LISTEN_FDS_START;
+ } else {
+ sh->sd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if(sh->sd < 0) {
+ warn("Can't create socket");
+ return -1;
+ }
- rc = bind(sh->sd, (struct sockaddr *)&addr, addrlen);
- if (rc) {
- socket_path_t name;
- console_socket_path_readable(&addr, addrlen, name);
- warn("Can't bind to socket path %s (terminated at first null)",
- name);
- goto cleanup;
- }
+ addrlen = sizeof(addr) - sizeof(addr.sun_path) + len;
- rc = listen(sh->sd, 1);
- if (rc) {
- warn("Can't listen for incoming connections");
- goto cleanup;
+ rc = bind(sh->sd, (struct sockaddr *)&addr, addrlen);
+ if (rc) {
+ socket_path_t name;
+ console_socket_path_readable(&addr, addrlen, name);
+ warn("Can't bind to socket path %s (terminated at first null)",
+ name);
+ goto cleanup;
+ }
+
+ rc = listen(sh->sd, 1);
+ if (rc) {
+ warn("Can't listen for incoming connections");
+ goto cleanup;
+ }
}
sh->poller = console_poller_register(console, handler, socket_poll,