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/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,