###########################################
# build and install afb-daemon
###########################################
-ADD_EXECUTABLE(afs-supervisor afs-supervisor.c)
+ADD_EXECUTABLE(afs-supervisor afs-supervisor.c afs-discover.c)
TARGET_LINK_LIBRARIES(afs-supervisor
afb-lib
${link_libraries}
#include "afb-debug.h"
#include "verbose.h"
#include "wrap-json.h"
+#include "jobs.h"
extern struct afb_config *main_config;
return fd;
}
-static void cleanup_supervisor(void *nada)
+static void disconnect_supervisor()
{
- struct afb_trace *t = __atomic_exchange_n(&trace, NULL, __ATOMIC_RELAXED);
+ struct afb_stub_ws *s;
+ struct afb_trace *t;
+
+ INFO("Disconnecting supervision");
+ s = __atomic_exchange_n(&supervisor, NULL, __ATOMIC_RELAXED);
+ t = __atomic_exchange_n(&trace, NULL, __ATOMIC_RELAXED);
+ if (s)
+ afb_stub_ws_unref(s);
if (t)
afb_trace_unref(t);
- supervisor = NULL;
}
-static void disconnect_supervisor()
+static void on_supervisor_hangup(struct afb_stub_ws *s)
{
- struct afb_stub_ws *s = __atomic_exchange_n(&supervisor, NULL, __ATOMIC_RELAXED);
-
- if (s)
- afb_stub_ws_unref(s);
+ if (s && s == supervisor)
+ disconnect_supervisor();
}
/* try to connect to supervisor */
ERROR("Creation of supervisor failed: %m");
goto end2;
}
+ afb_stub_ws_on_hangup(supervisor, on_supervisor_hangup);
/* successful termination */
goto end;
pthread_mutex_unlock(&mutex);
}
-static void on_sighup(int signum)
+static void try_connect_supervisor_job(int signum, void *args)
{
+ INFO("Try to connect supervisor after SIGHUP");
try_connect_supervisor();
}
+static void on_sighup(int signum)
+{
+ INFO("Supervision received a SIGHUP");
+ jobs_queue(NULL, 0, try_connect_supervisor_job, NULL);
+}
+
/**
* initalize the supervision
*/
--- /dev/null
+/*
+ * Copyright (C) 2016, 2017 "IoT.bzh"
+ * Author José Bollo <jose.bollo@iot.bzh>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <ctype.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+void afs_discover(const char *pattern, void (*callback)(void *closure, pid_t pid), void *closure)
+{
+ intmax_t n;
+ DIR *dir;
+ struct dirent *ent;
+ char *name;
+ char exe[PATH_MAX], lnk[PATH_MAX];
+
+ dir = opendir("/proc");
+ while ((ent = readdir(dir))) {
+ name = ent->d_name;
+ while (isdigit(*name))
+ name++;
+ if (*name)
+ continue;
+ n = snprintf(exe, sizeof exe, "/proc/%s/exe", ent->d_name);
+ if (n < 0 || (size_t)n >= sizeof exe)
+ continue;
+ n = readlink(exe, lnk, sizeof lnk);
+ if (n < 0 || (size_t)n >= sizeof lnk)
+ continue;
+ lnk[n] = 0;
+ name = lnk;
+ while(*name) {
+ while(*name == '/')
+ name++;
+ if (*name) {
+ if (!strcmp(name, pattern)) {
+ callback(closure, (pid_t)atoi(ent->d_name));
+ break;
+ }
+ while(*++name && *name != '/');
+ }
+ }
+ }
+ closedir(dir);
+}
+
#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
{
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'
*/
return 0;
}
+/*
+ */
+static void discovered_cb(void *closure, pid_t pid)
+{
+ struct supervised *s;
+
+ s = supervised_of_pid(pid);
+ if (!s)
+ kill(pid, SIGHUP);
+}
+
+static void discover_supervised()
+{
+ afs_discover("afb-daemon", discovered_cb, NULL);
+}
/**
* initalize the supervision
exit(1);
sd_notify(1, "READY=1");
+
+ discover_supervised();
}
/**
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;