X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-trace.c;h=79c7e0355a16589d6fd8f1e1894536710353db6e;hb=65353dce81a629e042800bb7b86fcd869a76727e;hp=0e285e140516b9a90d5c21bbda08fe96f1d1aacd;hpb=425458b99b65ada911c21ba1896a5733541e5170;p=src%2Fapp-framework-binder.git diff --git a/src/afb-trace.c b/src/afb-trace.c index 0e285e14..79c7e035 100644 --- a/src/afb-trace.c +++ b/src/afb-trace.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016, 2017, 2018 "IoT.bzh" + * Copyright (C) 2015-2020 "IoT.bzh" * Author José Bollo * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,6 +15,8 @@ * limitations under the License. */ +#if WITH_AFB_HOOK && WITH_AFB_TRACE + #define _GNU_SOURCE #include @@ -27,11 +29,15 @@ #include #include +#if !defined(JSON_C_TO_STRING_NOSLASHESCAPE) +#define JSON_C_TO_STRING_NOSLASHESCAPE 0 +#endif #define AFB_BINDING_VERSION 3 #include #include "afb-hook.h" +#include "afb-hook-flags.h" #include "afb-cred.h" #include "afb-session.h" #include "afb-xreq.h" @@ -58,17 +64,10 @@ /***** types *****/ /*******************************************************************************/ -/* structure for searching flags by names */ -struct flag -{ - const char *name; /** the name */ - int value; /** the value */ -}; - /* struct for tags */ struct tag { struct tag *next; /* link to the next */ - char tag[1]; /* name of the tag */ + char tag[]; /* name of the tag */ }; /* struct for events */ @@ -148,38 +147,11 @@ static void ctxt_error(char **errors, const char *format, ...) } } -/* get the value of the flag of 'name' in the array 'flags' of 'count elements */ -static int get_flag(const char *name, struct flag flags[], int count) -{ - /* dichotomic search */ - int lower = 0, upper = count; - while (lower < upper) { - int mid = (lower + upper) >> 1; - int cmp = strcmp(name, flags[mid].name); - if (!cmp) - return flags[mid].value; - if (cmp < 0) - upper = mid; - else - lower = mid + 1; - } - return 0; -} - /* timestamp */ static struct json_object *timestamp(const struct afb_hookid *hookid) { - char ts[50]; - - snprintf(ts, sizeof ts, "%llu.%06lu", - (long long unsigned)hookid->time.tv_sec, - (long unsigned)((hookid->time.tv_nsec + 500) / 1000)); - - return json_object_new_double_s(0.0f, ts); /* the real value isn't used */ -#if 0 - return json_object_new_string(ts); - return json_object_new_double_s(0f, ts); /* the real value isn't used */ -#endif + return json_object_new_double((double)hookid->time.tv_sec + + (double)hookid->time.tv_nsec * .000000001); } /* verbosity level name or NULL */ @@ -225,69 +197,25 @@ static void emit(void *closure, const struct afb_hookid *hookid, const char *typ /***** trace the requests *****/ /*******************************************************************************/ -static struct flag xreq_flags[] = { /* must be sorted by names */ - { "addref", afb_hook_flag_req_addref }, - { "all", afb_hook_flags_req_all }, - { "args", afb_hook_flags_req_args }, - { "begin", afb_hook_flag_req_begin }, - { "common", afb_hook_flags_req_common }, - { "context", afb_hook_flags_req_context }, - { "context_get", afb_hook_flag_req_legacy_context_get }, - { "context_make", afb_hook_flag_req_context_make }, - { "context_set", afb_hook_flag_req_legacy_context_set }, - { "end", afb_hook_flag_req_end }, - { "event", afb_hook_flags_req_event }, - { "extra", afb_hook_flags_req_extra }, - { "get", afb_hook_flag_req_get }, - { "get_application_id", afb_hook_flag_req_get_application_id }, - { "get_client_info", afb_hook_flag_req_get_client_info }, - { "get_uid", afb_hook_flag_req_get_uid }, - { "has_permission", afb_hook_flag_req_has_permission }, - { "json", afb_hook_flag_req_json }, - { "life", afb_hook_flags_req_life }, - { "ref", afb_hook_flags_req_ref }, - { "reply", afb_hook_flag_req_reply }, - { "security", afb_hook_flags_req_security }, - { "session", afb_hook_flags_req_session }, - { "session_close", afb_hook_flag_req_session_close }, - { "session_set_LOA", afb_hook_flag_req_session_set_LOA }, - { "store", afb_hook_flag_req_legacy_store }, - { "stores", afb_hook_flags_req_stores }, - { "subcall", afb_hook_flag_req_subcall }, - { "subcall_result", afb_hook_flag_req_subcall_result }, - { "subcalls", afb_hook_flags_req_subcalls }, - { "subcallsync", afb_hook_flag_req_subcallsync }, - { "subcallsync_result", afb_hook_flag_req_subcallsync_result }, - { "subscribe", afb_hook_flag_req_subscribe }, - { "unref", afb_hook_flag_req_unref }, - { "unstore", afb_hook_flag_req_legacy_unstore }, - { "unsubscribe", afb_hook_flag_req_unsubscribe }, - { "vverbose", afb_hook_flag_req_vverbose }, -}; - -/* get the xreq value for flag of 'name' */ -static int get_xreq_flag(const char *name) -{ - return get_flag(name, xreq_flags, (int)(sizeof xreq_flags / sizeof *xreq_flags)); -} - static void hook_xreq(void *closure, const struct afb_hookid *hookid, const struct afb_xreq *xreq, const char *action, const char *format, ...) { - struct json_object *cred = NULL; + struct afb_cred *cred; + struct json_object *jcred = NULL; const char *session = NULL; va_list ap; if (xreq->context.session) session = afb_session_uuid(xreq->context.session); - if (xreq->cred) - wrap_json_pack(&cred, "{si ss si si ss* ss*}", - "uid", (int)xreq->cred->uid, - "user", xreq->cred->user, - "gid", (int)xreq->cred->gid, - "pid", (int)xreq->cred->pid, - "label", xreq->cred->label, - "id", xreq->cred->id + cred = xreq->context.credentials; + if (cred) + wrap_json_pack(&jcred, "{si ss si si ss* ss*}", + "uid", (int)cred->uid, + "user", cred->user, + "gid", (int)cred->gid, + "pid", (int)cred->pid, + "label", cred->label, + "id", cred->id ); va_start(ap, format); emit(closure, hookid, "request", "{si ss ss ss so* ss*}", format, ap, @@ -295,7 +223,7 @@ static void hook_xreq(void *closure, const struct afb_hookid *hookid, const stru "api", xreq->request.called_api, "verb", xreq->request.called_verb, "action", action, - "credentials", cred, + "credentials", jcred, "session", session); va_end(ap); } @@ -525,94 +453,6 @@ static struct afb_hook_xreq_itf hook_xreq_itf = { /***** trace the api interface *****/ /*******************************************************************************/ -#if !defined(REMOVE_LEGACY_TRACE) -static struct flag legacy_ditf_flags[] = { /* must be sorted by names */ - { "all", afb_hook_flags_api_ditf_all }, - { "common", afb_hook_flags_api_ditf_common }, - { "event_broadcast_after", afb_hook_flag_api_event_broadcast }, - { "event_broadcast_before", afb_hook_flag_api_event_broadcast }, - { "event_make", afb_hook_flag_api_event_make }, - { "extra", afb_hook_flags_api_ditf_extra }, - { "get_event_loop", afb_hook_flag_api_get_event_loop }, - { "get_system_bus", afb_hook_flag_api_get_system_bus }, - { "get_user_bus", afb_hook_flag_api_get_user_bus }, - { "queue_job", afb_hook_flag_api_queue_job }, - { "require_api", afb_hook_flag_api_require_api }, - { "require_api_result", afb_hook_flag_api_require_api }, - { "rootdir_get_fd", afb_hook_flag_api_rootdir_get_fd }, - { "rootdir_open_locale", afb_hook_flag_api_rootdir_open_locale }, - { "unstore_req", afb_hook_flag_api_legacy_unstore_req }, - { "vverbose", afb_hook_flag_api_vverbose }, -}; - -static struct flag legacy_svc_flags[] = { /* must be sorted by names */ - { "all", afb_hook_flags_api_svc_all }, - { "call", afb_hook_flag_api_call }, - { "call_result", afb_hook_flag_api_call }, - { "callsync", afb_hook_flag_api_callsync }, - { "callsync_result", afb_hook_flag_api_callsync }, - { "on_event_after", afb_hook_flag_api_on_event }, - { "on_event_before", afb_hook_flag_api_on_event }, - { "start_after", afb_hook_flag_api_start }, - { "start_before", afb_hook_flag_api_start }, -}; - -/* get the export value for flag of 'name' */ -static int get_legacy_ditf_flag(const char *name) -{ - return get_flag(name, legacy_ditf_flags, (int)(sizeof legacy_ditf_flags / sizeof *legacy_ditf_flags)); -} - -/* get the export value for flag of 'name' */ -static int get_legacy_svc_flag(const char *name) -{ - return get_flag(name, legacy_svc_flags, (int)(sizeof legacy_svc_flags / sizeof *legacy_svc_flags)); -} -#endif - -static struct flag api_flags[] = { /* must be sorted by names */ - { "add_alias", afb_hook_flag_api_add_alias }, - { "all", afb_hook_flags_api_all }, - { "api_add_verb", afb_hook_flag_api_api_add_verb }, - { "api", afb_hook_flags_api_api }, - { "api_del_verb", afb_hook_flag_api_api_del_verb }, - { "api_seal", afb_hook_flag_api_api_seal }, - { "api_set_on_event", afb_hook_flag_api_api_set_on_event }, - { "api_set_on_init", afb_hook_flag_api_api_set_on_init }, - { "api_set_verbs", afb_hook_flag_api_api_set_verbs }, - { "call", afb_hook_flag_api_call }, - { "callsync", afb_hook_flag_api_callsync }, - { "class_provide", afb_hook_flag_api_class_provide }, - { "class_require", afb_hook_flag_api_class_require }, - { "common", afb_hook_flags_api_common }, - { "delete_api", afb_hook_flag_api_delete_api }, - { "event", afb_hook_flags_api_event }, - { "event_broadcast", afb_hook_flag_api_event_broadcast }, - { "event_handler_add", afb_hook_flag_api_event_handler_add }, - { "event_handler_del", afb_hook_flag_api_event_handler_del }, - { "event_make", afb_hook_flag_api_event_make }, - { "extra", afb_hook_flags_api_extra }, - { "get_event_loop", afb_hook_flag_api_get_event_loop }, - { "get_system_bus", afb_hook_flag_api_get_system_bus }, - { "get_user_bus", afb_hook_flag_api_get_user_bus }, - { "legacy_unstore_req", afb_hook_flag_api_legacy_unstore_req }, - { "new_api", afb_hook_flag_api_new_api }, - { "on_event", afb_hook_flag_api_on_event }, - { "on_event_handler", afb_hook_flag_api_on_event_handler }, - { "queue_job", afb_hook_flag_api_queue_job }, - { "require_api", afb_hook_flag_api_require_api }, - { "rootdir_get_fd", afb_hook_flag_api_rootdir_get_fd }, - { "rootdir_open_locale",afb_hook_flag_api_rootdir_open_locale }, - { "start", afb_hook_flag_api_start }, - { "vverbose", afb_hook_flag_api_vverbose }, -}; - -/* get the export value for flag of 'name' */ -static int get_api_flag(const char *name) -{ - return get_flag(name, api_flags, (int)(sizeof api_flags / sizeof *api_flags)); -} - static void hook_api(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *action, const char *format, ...) { va_list ap; @@ -687,10 +527,12 @@ static void hook_api_rootdir_get_fd(void *closure, const struct afb_hookid *hook { char path[PATH_MAX], proc[100]; const char *key, *val; + ssize_t s; if (result >= 0) { snprintf(proc, sizeof proc, "/proc/self/fd/%d", result); - readlink(proc, path, sizeof path); + s = readlink(proc, path, sizeof path); + path[s < 0 ? 0 : s >= sizeof path ? sizeof path - 1 : s] = 0; key = "path"; val = path; } else { @@ -705,10 +547,12 @@ static void hook_api_rootdir_open_locale(void *closure, const struct afb_hookid { char path[PATH_MAX], proc[100]; const char *key, *val; + ssize_t s; if (result >= 0) { snprintf(proc, sizeof proc, "/proc/self/fd/%d", result); - readlink(proc, path, sizeof path); + s = readlink(proc, path, sizeof path); + path[s < 0 ? 0 : s >= sizeof path ? sizeof path - 1 : s] = 0; key = "path"; val = path; } else { @@ -867,6 +711,23 @@ static void hook_api_delete_api(void *closure, const struct afb_hookid *hookid, hook_api(closure, hookid, export, "delete_api", "{si}", "status", result); } +static void hook_api_on_event_handler_before(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *event, int event_x2, struct json_object *object, const char *pattern) +{ + hook_api(closure, hookid, export, "on_event_handler.before", + "{ss ss sO?}", "pattern", pattern, "event", event, "data", object); +} + +static void hook_api_on_event_handler_after(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *event, int event_x2, struct json_object *object, const char *pattern) +{ + hook_api(closure, hookid, export, "on_event_handler.after", + "{ss ss sO?}", "pattern", pattern, "event", event, "data", object); +} + +static void hook_api_settings(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, struct json_object *object) +{ + hook_api(closure, hookid, export, "settings", "{sO}", "settings", object); +} + static struct afb_hook_api_itf hook_api_itf = { .hook_api_event_broadcast_before = hook_api_event_broadcast_before, .hook_api_event_broadcast_after = hook_api_event_broadcast_after, @@ -904,32 +765,15 @@ static struct afb_hook_api_itf hook_api_itf = { .hook_api_class_provide = hook_api_class_provide, .hook_api_class_require = hook_api_class_require, .hook_api_delete_api = hook_api_delete_api, + .hook_api_on_event_handler_before = hook_api_on_event_handler_before, + .hook_api_on_event_handler_after = hook_api_on_event_handler_after, + .hook_api_settings = hook_api_settings, }; /*******************************************************************************/ /***** trace the events *****/ /*******************************************************************************/ -static struct flag evt_flags[] = { /* must be sorted by names */ - { "addref", afb_hook_flag_evt_addref }, - { "all", afb_hook_flags_evt_all }, - { "broadcast_after", afb_hook_flag_evt_broadcast_after }, - { "broadcast_before", afb_hook_flag_evt_broadcast_before }, - { "common", afb_hook_flags_evt_common }, - { "create", afb_hook_flag_evt_create }, - { "extra", afb_hook_flags_evt_extra }, - { "name", afb_hook_flag_evt_name }, - { "push_after", afb_hook_flag_evt_push_after }, - { "push_before", afb_hook_flag_evt_push_before }, - { "unref", afb_hook_flag_evt_unref }, -}; - -/* get the evt value for flag of 'name' */ -static int get_evt_flag(const char *name) -{ - return get_flag(name, evt_flags, (int)(sizeof evt_flags / sizeof *evt_flags)); -} - static void hook_evt(void *closure, const struct afb_hookid *hookid, const char *evt, int id, const char *action, const char *format, ...) { va_list ap; @@ -998,37 +842,20 @@ static struct afb_hook_evt_itf hook_evt_itf = { /***** trace the sessions *****/ /*******************************************************************************/ -static struct flag session_flags[] = { /* must be sorted by names */ - { "addref", afb_hook_flag_session_addref }, - { "all", afb_hook_flags_session_all }, - { "close", afb_hook_flag_session_close }, - { "common", afb_hook_flags_session_common }, - { "create", afb_hook_flag_session_create }, - { "destroy", afb_hook_flag_session_destroy }, - { "renew", afb_hook_flag_session_renew }, - { "unref", afb_hook_flag_session_unref }, -}; - -/* get the session value for flag of 'name' */ -static int get_session_flag(const char *name) -{ - return get_flag(name, session_flags, (int)(sizeof session_flags / sizeof *session_flags)); -} - static void hook_session(void *closure, const struct afb_hookid *hookid, struct afb_session *session, const char *action, const char *format, ...) { va_list ap; va_start(ap, format); emit(closure, hookid, "session", "{ss ss}", format, ap, - "uuid", session, + "uuid", afb_session_uuid(session), "action", action); va_end(ap); } static void hook_session_create(void *closure, const struct afb_hookid *hookid, struct afb_session *session) { - hook_session(closure, hookid, session, "create", "{ss}", "token", afb_session_token(session)); + hook_session(closure, hookid, session, "create", NULL); } static void hook_session_close(void *closure, const struct afb_hookid *hookid, struct afb_session *session) @@ -1041,11 +868,6 @@ static void hook_session_destroy(void *closure, const struct afb_hookid *hookid, hook_session(closure, hookid, session, "destroy", NULL); } -static void hook_session_renew(void *closure, const struct afb_hookid *hookid, struct afb_session *session) -{ - hook_session(closure, hookid, session, "renew", "{ss}", "token", afb_session_token(session)); -} - static void hook_session_addref(void *closure, const struct afb_hookid *hookid, struct afb_session *session) { hook_session(closure, hookid, session, "addref", NULL); @@ -1060,7 +882,6 @@ static struct afb_hook_session_itf hook_session_itf = { .hook_session_create = hook_session_create, .hook_session_close = hook_session_close, .hook_session_destroy = hook_session_destroy, - .hook_session_renew = hook_session_renew, .hook_session_addref = hook_session_addref, .hook_session_unref = hook_session_unref }; @@ -1069,17 +890,6 @@ static struct afb_hook_session_itf hook_session_itf = { /***** trace the globals *****/ /*******************************************************************************/ -static struct flag global_flags[] = { /* must be sorted by names */ - { "all", afb_hook_flags_global_all }, - { "vverbose", afb_hook_flag_global_vverbose }, -}; - -/* get the global value for flag of 'name' */ -static int get_global_flag(const char *name) -{ - return get_flag(name, global_flags, (int)(sizeof global_flags / sizeof *global_flags)); -} - static void hook_global(void *closure, const struct afb_hookid *hookid, const char *action, const char *format, ...) { va_list ap; @@ -1136,44 +946,44 @@ abstracting[Trace_Type_Count] = { .name = "request", .unref = (void(*)(void*))afb_hook_unref_xreq, - .get_flag = get_xreq_flag + .get_flag = afb_hook_flags_xreq_from_text }, [Trace_Type_Api] = { .name = "api", .unref = (void(*)(void*))afb_hook_unref_api, - .get_flag = get_api_flag + .get_flag = afb_hook_flags_api_from_text }, [Trace_Type_Evt] = { .name = "event", .unref = (void(*)(void*))afb_hook_unref_evt, - .get_flag = get_evt_flag + .get_flag = afb_hook_flags_evt_from_text }, [Trace_Type_Session] = { .name = "session", .unref = (void(*)(void*))afb_hook_unref_session, - .get_flag = get_session_flag + .get_flag = afb_hook_flags_session_from_text }, [Trace_Type_Global] = { .name = "global", .unref = (void(*)(void*))afb_hook_unref_global, - .get_flag = get_global_flag + .get_flag = afb_hook_flags_global_from_text }, #if !defined(REMOVE_LEGACY_TRACE) [Trace_Legacy_Type_Ditf] = { .name = "daemon", .unref = (void(*)(void*))afb_hook_unref_api, - .get_flag = get_legacy_ditf_flag + .get_flag = afb_hook_flags_legacy_ditf_from_text }, [Trace_Legacy_Type_Svc] = { .name = "service", .unref = (void(*)(void*))afb_hook_unref_api, - .get_flag = get_legacy_svc_flag + .get_flag = afb_hook_flags_legacy_svc_from_text }, #endif }; @@ -1259,7 +1069,7 @@ static struct tag *trace_get_tag(struct afb_trace *trace, const char *name, int if (!tag && alloc) { /* creation if needed */ - tag = malloc(sizeof * tag + strlen(name)); + tag = malloc(sizeof * tag + 1 + strlen(name)); if (tag) { strcpy(tag->tag, name); tag->next = trace->tags; @@ -1482,7 +1292,7 @@ static void add_flags(void *closure, struct json_object *object, enum trace_type if (wrap_json_unpack(object, "s", &name)) ctxt_error(&desc->context->errors, "unexpected %s value %s", abstracting[type].name, - json_object_to_json_string(object)); + json_object_to_json_string_ext(object, JSON_C_TO_STRING_NOSLASHESCAPE)); else { queried = (name[0] == '*' && !name[1]) ? "all" : name; value = abstracting[type].get_flag(queried); @@ -1595,7 +1405,7 @@ static void add(void *closure, struct json_object *object) wrap_json_optarray_for_all(event, add_evt_flags, &desc); if (session) - wrap_json_optarray_for_all(event, add_session_flags, &desc); + wrap_json_optarray_for_all(session, add_session_flags, &desc); if (global) wrap_json_optarray_for_all(global, add_global_flags, &desc); @@ -1622,7 +1432,7 @@ static void drop_tag(void *closure, struct json_object *object) rc = wrap_json_unpack(object, "s", &name); if (rc) - ctxt_error(&context->errors, "unexpected tag value %s", json_object_to_json_string(object)); + ctxt_error(&context->errors, "unexpected tag value %s", json_object_to_json_string_ext(object, JSON_C_TO_STRING_NOSLASHESCAPE)); else { tag = trace_get_tag(context->trace, name, 0); if (!tag) @@ -1642,7 +1452,7 @@ static void drop_event(void *closure, struct json_object *object) rc = wrap_json_unpack(object, "s", &name); if (rc) - ctxt_error(&context->errors, "unexpected event value %s", json_object_to_json_string(object)); + ctxt_error(&context->errors, "unexpected event value %s", json_object_to_json_string_ext(object, JSON_C_TO_STRING_NOSLASHESCAPE)); else { event = trace_get_event(context->trace, name, 0); if (!event) @@ -1662,7 +1472,7 @@ static void drop_session(void *closure, struct json_object *object) rc = wrap_json_unpack(object, "s", &uuid); if (rc) - ctxt_error(&context->errors, "unexpected session value %s", json_object_to_json_string(object)); + ctxt_error(&context->errors, "unexpected session value %s", json_object_to_json_string_ext(object, JSON_C_TO_STRING_NOSLASHESCAPE)); else { session = trace_get_session_by_uuid(context->trace, uuid, 0); if (!session) @@ -1739,7 +1549,7 @@ int afb_trace_add(afb_req_t req, struct json_object *args, struct afb_trace *tra } /* drop traces */ -extern int afb_trace_drop(afb_req_t req, struct json_object *args, struct afb_trace *trace) +int afb_trace_drop(afb_req_t req, struct json_object *args, struct afb_trace *trace) { int rc; struct context context; @@ -1793,3 +1603,5 @@ extern int afb_trace_drop(afb_req_t req, struct json_object *args, struct afb_tr free(context.errors); return -1; } + +#endif