afb-systemd: Isolate systemd main entries
[src/app-framework-binder.git] / src / afs-supervisor.c
index 32bd995..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
 {
@@ -63,7 +65,8 @@ struct supervised
 };
 
 /* api and apiset name */
-static const char supervision_apiname[] = AFS_SURPERVISION_APINAME;
+static const char supervision_apiname[] = AFS_SURPERVISION_APINAME_INTERNAL;
+static const char supervisor_apiname[] = "supervisor";
 
 /* the main apiset */
 struct afb_apiset *main_apiset;
@@ -209,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'
  */
@@ -251,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
@@ -269,14 +307,14 @@ static int init(const char *spec)
        /* TODO check that value */
 
        /* create the apisets */
-       main_apiset = afb_apiset_create(supervision_apiname, 0);
+       main_apiset = afb_apiset_create(supervisor_apiname, 0);
        if (!main_apiset) {
-               ERROR("Can't create supervision's apiset");
+               ERROR("Can't create supervisor's apiset");
                return -1;
        }
        empty_apiset = afb_apiset_create(supervision_apiname, 0);
        if (!empty_apiset) {
-               ERROR("Can't create supervised apiset");
+               ERROR("Can't create supervision apiset");
                return -1;
        }
 
@@ -301,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) {
@@ -332,6 +370,8 @@ static void start(int signum, void *arg)
                exit(1);
 
        sd_notify(1, "READY=1");
+
+       discover_supervised();
 }
 
 /**
@@ -375,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;
@@ -395,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;
@@ -521,11 +565,18 @@ 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 }
 };
 
 static const struct afb_binding_v2 _afb_binding_v2_supervision = {
-    .api = supervision_apiname,
+    .api = supervisor_apiname,
     .specification = NULL,
     .info = NULL,
     .verbs = _afb_verbs_v2_supervision,