X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-supervision.c;h=211c3fd0b88cff0d091533defa011532deec016e;hb=65353dce81a629e042800bb7b86fcd869a76727e;hp=a7099a4a87a50ee3698bc535f38531c5b3b81e3e;hpb=b8c9d5de384efcfa53ebdb3f0053d7b3723777e1;p=src%2Fapp-framework-binder.git diff --git a/src/afb-supervision.c b/src/afb-supervision.c index a7099a4a..211c3fd0 100644 --- a/src/afb-supervision.c +++ b/src/afb-supervision.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016, 2017 "IoT.bzh" + * Copyright (C) 2015-2020 "IoT.bzh" * Author José Bollo * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,8 +15,9 @@ * limitations under the License. */ +#if WITH_SUPERVISION + #define _GNU_SOURCE -#define AFB_BINDING_PRAGMA_NO_VERBOSE_MACRO #include #include @@ -29,33 +30,44 @@ #include #include -#include -#include "afb-cred.h" +#define AFB_BINDING_VERSION 3 +#include + #include "afb-api.h" #include "afb-apiset.h" #include "afb-api-so-v2.h" #include "afb-xreq.h" #include "afb-trace.h" #include "afb-session.h" +#include "afb-args.h" #include "afb-supervision.h" #include "afs-supervision.h" #include "afb-stub-ws.h" #include "afb-debug.h" +#include "afb-fdev.h" +#include "afb-error-text.h" #include "verbose.h" #include "wrap-json.h" +#include "jobs.h" /* api and apiset name */ -static const char supervision_apiname[] = AFS_SURPERVISION_APINAME; +static const char supervision_apiname[] = AFS_SUPERVISION_APINAME; +#if WITH_AFB_TRACE +static const char supervisor_apiname[] = AFS_SUPERVISOR_APINAME; +#endif /* path of the supervision socket */ -static const char supervisor_socket_path[] = AFS_SURPERVISION_SOCKET; +static const char supervisor_socket_path[] = AFS_SUPERVISION_SOCKET; /* mutual exclusion */ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /* the standard apiset */ -extern struct afb_apiset *main_apiset; +static struct { + struct afb_apiset *apiset; + struct json_object *config; +} global; /* the supervision apiset (not exported) */ static struct afb_apiset *supervision_apiset; @@ -70,8 +82,10 @@ static struct afb_api_itf supervision_api_itf = /* the supervisor link */ static struct afb_stub_ws *supervisor; +#if WITH_AFB_TRACE /* the trace api */ static struct afb_trace *trace; +#endif /* open the socket */ static int open_supervisor_socket(const char *path) @@ -108,20 +122,26 @@ static int open_supervisor_socket(const char *path) return fd; } -static void cleanup_supervisor(void *nada) +static void disconnect_supervisor() { + struct afb_stub_ws *s; + + INFO("Disconnecting supervision"); + s = __atomic_exchange_n(&supervisor, NULL, __ATOMIC_RELAXED); + if (s) + afb_stub_ws_unref(s); + +#if WITH_AFB_TRACE struct afb_trace *t = __atomic_exchange_n(&trace, NULL, __ATOMIC_RELAXED); if (t) afb_trace_unref(t); - supervisor = NULL; +#endif } -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 */ @@ -130,6 +150,7 @@ static void try_connect_supervisor() int fd; ssize_t srd; struct afs_supervision_initiator initiator; + struct fdev *fdev; /* get the mutex */ pthread_mutex_lock(&mutex); @@ -140,18 +161,18 @@ static void try_connect_supervisor() /* check existing path */ if (supervisor_socket_path[0] != '@' && access(supervisor_socket_path, F_OK)) { - NOTICE("Can't acces socket path %s: %m", supervisor_socket_path); + INFO("Can't acces socket path %s: %m", supervisor_socket_path); goto end; } /* socket connection */ fd = open_supervisor_socket(supervisor_socket_path); if (fd < 0) { - NOTICE("Can't connect supervision socket to %s: %m", supervisor_socket_path); + INFO("Can't connect supervision socket to %s: %m", supervisor_socket_path); goto end; } - /* negociation */ + /* negotiation */ do { srd = read(fd, &initiator, sizeof initiator); } while(srd < 0 && errno == EINTR); if (srd < 0) { NOTICE("Can't read supervisor %s: %m", supervisor_socket_path); @@ -165,7 +186,7 @@ static void try_connect_supervisor() ERROR("Bad interface of supervisor %s", supervisor_socket_path); goto end2; } - if (strcmp(initiator.interface, AFS_SURPERVISION_INTERFACE_1)) { + if (strcmp(initiator.interface, AFS_SUPERVISION_INTERFACE_1)) { ERROR("Unknown interface %s for supervisor %s", initiator.interface, supervisor_socket_path); goto end2; } @@ -187,11 +208,17 @@ static void try_connect_supervisor() } /* make the supervisor link */ - supervisor = afb_stub_ws_create_server(fd, supervision_apiname, supervision_apiset); + fdev = afb_fdev_create(fd); + if (!fdev) { + ERROR("Creation of fdev failed: %m"); + goto end2; + } + supervisor = afb_stub_ws_create_server(fdev, supervision_apiname, supervision_apiset); if (!supervisor) { ERROR("Creation of supervisor failed: %m"); - goto end2; + goto end; } + afb_stub_ws_set_on_hangup(supervisor, on_supervisor_hangup); /* successful termination */ goto end; @@ -202,15 +229,22 @@ 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 + * initialize the supervision */ -int afb_supervision_init() +int afb_supervision_init(struct afb_apiset *apiset, struct json_object *config) { int rc; struct sigaction sa; @@ -228,7 +262,7 @@ int afb_supervision_init() /* init the apiset */ rc = afb_apiset_add(supervision_apiset, supervision_apiname, - (struct afb_api){ .itf = &supervision_api_itf, .closure = NULL}); + (struct afb_api_item){ .itf = &supervision_api_itf, .closure = NULL}); if (rc < 0) { ERROR("Can't create supervision's apiset: %m"); afb_apiset_unref(supervision_apiset); @@ -236,6 +270,10 @@ int afb_supervision_init() return rc; } + /* init the globals */ + global.apiset = apiset; + global.config = config; + /* get SIGHUP */ memset(&sa, 0, sizeof sa); sa.sa_handler = on_sighup; @@ -254,10 +292,8 @@ int afb_supervision_init() static void slist(void *closure, struct afb_session *session) { struct json_object *list = closure; - struct json_object *item; - wrap_json_pack(&item, "{ss}", "token", afb_session_token(session)); - json_object_object_add(list, afb_session_uuid(session), item); + json_object_object_add(list, afb_session_uuid(session), NULL); } /****************************************************************************** @@ -265,24 +301,27 @@ static void slist(void *closure, struct afb_session *session) ******************************************************************************/ static const char *verbs[] = { - "break", "do", "exit", "sclose", "slist", "trace", "wait" }; -enum { Break , Do , Exit , Sclose , Slist , Trace , Wait }; - + "break", "config", "do", "exit", "sclose", "slist", "trace", "wait" }; +enum { Break , Config , Do , Exit , Sclose , Slist , Trace , Wait }; static void on_supervision_call(void *closure, struct afb_xreq *xreq) { - int i, rc; - struct json_object *args, *drop, *add, *sub, *list; + int i; + struct json_object *args, *sub, *list; const char *api, *verb, *uuid; struct afb_session *session; - const struct afb_api *xapi; - struct afb_req req; + const struct afb_api_item *xapi; + afb_req_t req; +#if WITH_AFB_TRACE + struct json_object *drop, *add; + int rc; +#endif /* search the verb */ i = (int)(sizeof verbs / sizeof *verbs); - while(--i >= 0 && strcasecmp(verbs[i], xreq->request.verb)); + while(--i >= 0 && strcasecmp(verbs[i], xreq->request.called_verb)); if (i < 0) { - afb_xreq_fail_unknown_verb(xreq); + afb_xreq_reply_unknown_verb(xreq); return; } @@ -293,7 +332,7 @@ static void on_supervision_call(void *closure, struct afb_xreq *xreq) i = 0; if (wrap_json_unpack(args, "i", &i)) wrap_json_unpack(args, "{si}", "code", &i); - ERROR("existing from supervision with code %d -> %d", i, i & 127); + ERROR("exiting from supervision with code %d -> %d", i, i & 127); exit(i & 127); break; case Sclose: @@ -301,29 +340,34 @@ static void on_supervision_call(void *closure, struct afb_xreq *xreq) if (wrap_json_unpack(args, "s", &uuid)) wrap_json_unpack(args, "{ss}", "uuid", &uuid); if (!uuid) - afb_xreq_fail(xreq, "invalid", NULL); + afb_xreq_reply(xreq, NULL, afb_error_text_invalid_request, NULL); else { session = afb_session_search(uuid); if (!session) - afb_xreq_fail(xreq, "not-found", NULL); + afb_xreq_reply(xreq, NULL, afb_error_text_unknown_session, NULL); else { afb_session_close(session); afb_session_unref(session); afb_session_purge(); - afb_xreq_success(xreq, NULL, NULL); + afb_xreq_reply(xreq, NULL, NULL, NULL); } } break; case Slist: list = json_object_new_object(); afb_session_foreach(slist, list); - afb_xreq_success(xreq, list, NULL); + afb_xreq_reply(xreq, list, NULL, NULL); + break; + case Config: + afb_xreq_reply(xreq, json_object_get(global.config), NULL, NULL); break; case Trace: + req = xreq_to_req_x2(xreq); +#if WITH_AFB_TRACE if (!trace) - trace = afb_trace_create(supervision_apiname, NULL /* not bound to any session */); + trace = afb_trace_create(supervisor_apiname, NULL /* not bound to any session */); - req = afb_xreq_unstore((struct afb_stored_req*)xreq); + add = drop = NULL; wrap_json_unpack(args, "{s?o s?o}", "add", &add, "drop", &drop); if (add) { rc = afb_trace_add(req, add, trace); @@ -336,20 +380,22 @@ static void on_supervision_call(void *closure, struct afb_xreq *xreq) return; } afb_req_success(req, NULL, NULL); +#else + afb_req_reply(req, NULL, afb_error_text_not_available, NULL); +#endif break; case Do: sub = NULL; if (wrap_json_unpack(args, "{ss ss s?o*}", "api", &api, "verb", &verb, "args", &sub)) - afb_xreq_fail(xreq, "error", "bad request"); + afb_xreq_reply(xreq, NULL, afb_error_text_invalid_request, NULL); else { - xapi = afb_apiset_lookup_started(main_apiset, api, 1); + xapi = afb_apiset_lookup_started(global.apiset, api, 1); if (!xapi) - afb_xreq_fail_unknown_api(xreq); + afb_xreq_reply_unknown_api(xreq); else { - afb_cred_unref(xreq->cred); - xreq->cred = NULL; - xreq->request.api = api; - xreq->request.verb = verb; + afb_context_change_cred(&xreq->context, NULL); + xreq->request.called_api = api; + xreq->request.called_verb = verb; xreq->json = json_object_get(sub); xapi->itf->call(xapi->closure, xreq); json_object_put(args); @@ -357,13 +403,14 @@ static void on_supervision_call(void *closure, struct afb_xreq *xreq) } break; case Wait: - afb_req_success(req, NULL, NULL); + afb_xreq_reply(xreq, NULL, NULL, NULL); afb_debug_wait("supervisor"); break; case Break: - afb_req_success(req, NULL, NULL); + afb_xreq_reply(xreq, NULL, NULL, NULL); afb_debug_break("supervisor"); break; } } +#endif