afb-systemd: Isolate systemd main entries
[src/app-framework-binder.git] / src / afs-supervisor.c
index 8d76832..be0cdbf 100644 (file)
@@ -36,7 +36,7 @@
 #include <afb/afb-binding-v2.h>
 
 #include "afs-supervision.h"
-#include "afb-common.h"
+#include "afb-systemd.h"
 #include "afb-session.h"
 #include "afb-cred.h"
 #include "afb-stub-ws.h"
@@ -49,6 +49,8 @@
 #include "verbose.h"
 #include "wrap-json.h"
 
+extern void afs_discover(const char *pattern, void (*callback)(void *closure, pid_t pid), void *closure);
+
 /* supervised items */
 struct supervised
 {
@@ -210,6 +212,22 @@ static int make_supervised(int fd, struct afb_cred *cred)
        return 0;
 }
 
+/**
+ * Search the supervised of 'pid', return it or NULL.
+ */
+static struct supervised *supervised_of_pid(pid_t pid)
+{
+       struct supervised *s;
+
+       pthread_mutex_lock(&mutex);
+       s = superviseds;
+       while (s && pid != s->cred->pid)
+               s = s->next;
+       pthread_mutex_unlock(&mutex);
+
+       return s;
+}
+
 /*
  * handles incoming connection on 'sock'
  */
@@ -252,6 +270,25 @@ static int listening(sd_event_source *src, int fd, uint32_t revents, void *closu
        return 0;
 }
 
+/*
+ */
+static void discovered_cb(void *closure, pid_t pid)
+{
+       struct supervised *s;
+
+       s = supervised_of_pid(pid);
+       if (!s) {
+               (*(int*)closure)++;
+               kill(pid, SIGHUP);
+       }
+}
+
+static int discover_supervised()
+{
+       int n = 0;
+       afs_discover("afb-daemon", discovered_cb, &n);
+       return n;
+}
 
 /**
  * initalize the supervision
@@ -302,7 +339,7 @@ static int init(const char *spec)
        }
 
        /* integrate the socket to the loop */
-       rc = sd_event_add_io(afb_common_get_event_loop(),
+       rc = sd_event_add_io(afb_systemd_get_event_loop(),
                                NULL, fd, EPOLLIN,
                                listening, NULL);
        if (rc < 0) {
@@ -333,6 +370,8 @@ static void start(int signum, void *arg)
                exit(1);
 
        sd_notify(1, "READY=1");
+
+       discover_supervised();
 }
 
 /**
@@ -376,6 +415,12 @@ static void f_list(struct afb_req req)
        afb_req_success(req, resu, NULL);
 }
 
+static void f_discover(struct afb_req req)
+{
+       discover_supervised();
+       afb_req_success(req, NULL, NULL);
+}
+
 static void propagate(struct afb_req req, const char *verb)
 {
        struct afb_xreq *xreq;
@@ -396,9 +441,7 @@ static void propagate(struct afb_req req, const char *verb)
                afb_xreq_fail(xreq, "bad-pid", NULL);
                return;
        }
-       s = superviseds;
-       while (s && p != (int)s->cred->pid)
-               s = s->next;
+       s = supervised_of_pid((pid_t)p);
        if (!s) {
                afb_req_fail(req, "unknown-pid", NULL);
                return;
@@ -522,6 +565,13 @@ static const struct afb_verb_v2 _afb_verbs_v2_supervision[] = {
         .info = NULL,
         .session = AFB_SESSION_NONE_V2
     },
+    {
+        .verb = "discover",
+        .callback = f_discover,
+        .auth = &_afb_auths_v2_supervision[0],
+        .info = NULL,
+        .session = AFB_SESSION_NONE_V2
+    },
     { .verb = NULL }
 };