Integration of socket activation for services
authorJosé Bollo <jose.bollo@iot.bzh>
Mon, 13 Mar 2017 15:18:23 +0000 (16:18 +0100)
committerJosé Bollo <jose.bollo@iot.bzh>
Mon, 13 Mar 2017 15:28:25 +0000 (16:28 +0100)
The services provided using the option --ws-server
can now be linked to socket activation of systemd.

When afb-daemon is launched, the api to be provided
by socket activation is declared by adding the
option

   --ws-server=sd:APINAME

Where APINAME is the name of the provided api.

The binder looks to the prefix "sd:" to automatically
use the "listen fd" of name APINAME for serving
the api APINAME.

In the socket activation unit the connection
to this socket must be named using the
directive FileDescriptorName as below:

[socket]
FileDescriptorName=APINAME
...

Change-Id: I281e1a2b9fed3eac3bd0ee27b7f56df99df7bbd6
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
src/afb-api-ws.c

index 4d1f08c..a56cfbe 100644 (file)
@@ -46,6 +46,7 @@
 #include "afb-evt.h"
 #include "afb-subcall.h"
 #include "verbose.h"
+#include "sd-fds.h"
 
 struct api_ws_memo;
 struct api_ws_event;
@@ -212,7 +213,9 @@ static struct api_ws *api_ws_make(const char *path)
        memcpy(api->path, path, length + 1);
 
        /* api name is at the end of the path */
-       api->api = strrchr(api->path, '/');
+       while (length && path[length - 1] != '/' && path[length - 1] != ':')
+               length = length - 1;
+       api->api = &api->path[length];
        if (api->api == NULL || !afb_apis_is_valid_api_name(++api->api)) {
                errno = EINVAL;
                goto error2;
@@ -314,21 +317,29 @@ static int api_ws_socket(const char *path, int server)
 {
        int fd, rc;
 
-       /* check for unix socket */
-       if (0 == strncmp(path, "unix:", 5))
-               fd = api_ws_socket_unix(path + 5, server);
-       else
-               fd = api_ws_socket_inet(path, server);
-
-       if (fd >= 0) {
-               fcntl(fd, F_SETFD, FD_CLOEXEC);
-               fcntl(fd, F_SETFL, O_NONBLOCK);
-               if (server) {
+       /* check for systemd socket */
+       if (0 == strncmp(path, "sd:", 3))
+               fd = sd_fds_for(path + 3);
+       else {
+               /* check for unix socket */
+               if (0 == strncmp(path, "unix:", 5))
+                       /* unix socket */
+                       fd = api_ws_socket_unix(path + 5, server);
+               else
+                       /* inet socket */
+                       fd = api_ws_socket_inet(path, server);
+
+               if (fd >= 0 && server) {
                        rc = 1;
                        setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &rc, sizeof rc);
                        rc = listen(fd, 5);
                }
        }
+       /* configure the socket */
+       if (fd >= 0) {
+               fcntl(fd, F_SETFD, FD_CLOEXEC);
+               fcntl(fd, F_SETFL, O_NONBLOCK);
+       }
        return fd;
 }