11dde0f48SLluís Vilanova /* 21dde0f48SLluís Vilanova * QMP commands for tracing events. 31dde0f48SLluís Vilanova * 477e2b172SLluís Vilanova * Copyright (C) 2014-2016 Lluís Vilanova <vilanova@ac.upc.edu> 51dde0f48SLluís Vilanova * 61dde0f48SLluís Vilanova * This work is licensed under the terms of the GNU GPL, version 2 or later. 71dde0f48SLluís Vilanova * See the COPYING file in the top-level directory. 81dde0f48SLluís Vilanova */ 91dde0f48SLluís Vilanova 10d38ea87aSPeter Maydell #include "qemu/osdep.h" 11e688df6bSMarkus Armbruster #include "qapi/error.h" 129af23989SMarkus Armbruster #include "qapi/qapi-commands-trace.h" 13*333df1c6SAlex Bennée #include "control.h" 141dde0f48SLluís Vilanova 151dde0f48SLluís Vilanova 1689aafcf2SAlex Bennée static bool check_events(bool ignore_unavailable, bool is_pattern, 1777e2b172SLluís Vilanova const char *name, Error **errp) 1877e2b172SLluís Vilanova { 1977e2b172SLluís Vilanova if (!is_pattern) { 2077e2b172SLluís Vilanova TraceEvent *ev = trace_event_name(name); 2177e2b172SLluís Vilanova 2277e2b172SLluís Vilanova /* error for non-existing event */ 2377e2b172SLluís Vilanova if (ev == NULL) { 2477e2b172SLluís Vilanova error_setg(errp, "unknown event \"%s\"", name); 2577e2b172SLluís Vilanova return false; 2677e2b172SLluís Vilanova } 2777e2b172SLluís Vilanova 2877e2b172SLluís Vilanova /* error for unavailable event */ 2977e2b172SLluís Vilanova if (!ignore_unavailable && !trace_event_get_state_static(ev)) { 3077e2b172SLluís Vilanova error_setg(errp, "event \"%s\" is disabled", name); 3177e2b172SLluís Vilanova return false; 3277e2b172SLluís Vilanova } 3377e2b172SLluís Vilanova 3477e2b172SLluís Vilanova return true; 3577e2b172SLluís Vilanova } else { 3677e2b172SLluís Vilanova /* error for unavailable events */ 370d4e995cSDaniel P. Berrange TraceEventIter iter; 380d4e995cSDaniel P. Berrange TraceEvent *ev; 39117856c3SGerd Hoffmann trace_event_iter_init_pattern(&iter, name); 400d4e995cSDaniel P. Berrange while ((ev = trace_event_iter_next(&iter)) != NULL) { 4177e2b172SLluís Vilanova if (!ignore_unavailable && !trace_event_get_state_static(ev)) { 4277e2b172SLluís Vilanova error_setg(errp, "event \"%s\" is disabled", trace_event_get_name(ev)); 4377e2b172SLluís Vilanova return false; 4477e2b172SLluís Vilanova } 4577e2b172SLluís Vilanova } 4677e2b172SLluís Vilanova return true; 4777e2b172SLluís Vilanova } 4877e2b172SLluís Vilanova } 4977e2b172SLluís Vilanova 5077e2b172SLluís Vilanova TraceEventInfoList *qmp_trace_event_get_state(const char *name, 5177e2b172SLluís Vilanova bool has_vcpu, int64_t vcpu, 5277e2b172SLluís Vilanova Error **errp) 5377e2b172SLluís Vilanova { 5477e2b172SLluís Vilanova TraceEventInfoList *events = NULL; 550d4e995cSDaniel P. Berrange TraceEventIter iter; 5677e2b172SLluís Vilanova TraceEvent *ev; 5777e2b172SLluís Vilanova bool is_pattern = trace_event_is_pattern(name); 5877e2b172SLluís Vilanova 5977e2b172SLluís Vilanova /* Check events */ 6089aafcf2SAlex Bennée if (!check_events(true, is_pattern, name, errp)) { 6177e2b172SLluís Vilanova return NULL; 6277e2b172SLluís Vilanova } 6377e2b172SLluís Vilanova 6477e2b172SLluís Vilanova /* Get states (all errors checked above) */ 65117856c3SGerd Hoffmann trace_event_iter_init_pattern(&iter, name); 660d4e995cSDaniel P. Berrange while ((ev = trace_event_iter_next(&iter)) != NULL) { 6754aa3de7SEric Blake TraceEventInfo *value; 6877e2b172SLluís Vilanova 6954aa3de7SEric Blake value = g_new(TraceEventInfo, 1); 7054aa3de7SEric Blake value->name = g_strdup(trace_event_get_name(ev)); 7177e2b172SLluís Vilanova 721dde0f48SLluís Vilanova if (!trace_event_get_state_static(ev)) { 7354aa3de7SEric Blake value->state = TRACE_EVENT_STATE_UNAVAILABLE; 741dde0f48SLluís Vilanova } else { 7577e2b172SLluís Vilanova if (trace_event_get_state_dynamic(ev)) { 7654aa3de7SEric Blake value->state = TRACE_EVENT_STATE_ENABLED; 7777e2b172SLluís Vilanova } else { 7854aa3de7SEric Blake value->state = TRACE_EVENT_STATE_DISABLED; 7977e2b172SLluís Vilanova } 8077e2b172SLluís Vilanova } 8154aa3de7SEric Blake QAPI_LIST_PREPEND(events, value); 821dde0f48SLluís Vilanova } 831dde0f48SLluís Vilanova 841dde0f48SLluís Vilanova return events; 851dde0f48SLluís Vilanova } 861dde0f48SLluís Vilanova 871dde0f48SLluís Vilanova void qmp_trace_event_set_state(const char *name, bool enable, 8877e2b172SLluís Vilanova bool has_ignore_unavailable, bool ignore_unavailable, 8977e2b172SLluís Vilanova bool has_vcpu, int64_t vcpu, 9077e2b172SLluís Vilanova Error **errp) 911dde0f48SLluís Vilanova { 920d4e995cSDaniel P. Berrange TraceEventIter iter; 931dde0f48SLluís Vilanova TraceEvent *ev; 9477e2b172SLluís Vilanova bool is_pattern = trace_event_is_pattern(name); 951dde0f48SLluís Vilanova 9677e2b172SLluís Vilanova /* Check events */ 9789aafcf2SAlex Bennée if (!check_events(has_ignore_unavailable && ignore_unavailable, 9877e2b172SLluís Vilanova is_pattern, name, errp)) { 9977e2b172SLluís Vilanova return; 10077e2b172SLluís Vilanova } 10177e2b172SLluís Vilanova 10277e2b172SLluís Vilanova /* Apply changes (all errors checked above) */ 103117856c3SGerd Hoffmann trace_event_iter_init_pattern(&iter, name); 1040d4e995cSDaniel P. Berrange while ((ev = trace_event_iter_next(&iter)) != NULL) { 10589aafcf2SAlex Bennée if (!trace_event_get_state_static(ev)) { 10677e2b172SLluís Vilanova continue; 10777e2b172SLluís Vilanova } 1081dde0f48SLluís Vilanova trace_event_set_state_dynamic(ev, enable); 1091dde0f48SLluís Vilanova } 1101dde0f48SLluís Vilanova } 111