11dde0f48SLluís Vilanova /* 21dde0f48SLluís Vilanova * QMP commands for tracing events. 31dde0f48SLluís Vilanova * 41dde0f48SLluís Vilanova * Copyright (C) 2014 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 10*d38ea87aSPeter Maydell #include "qemu/osdep.h" 111dde0f48SLluís Vilanova #include "qemu/typedefs.h" 121dde0f48SLluís Vilanova #include "qmp-commands.h" 131dde0f48SLluís Vilanova #include "trace/control.h" 141dde0f48SLluís Vilanova 151dde0f48SLluís Vilanova 161dde0f48SLluís Vilanova TraceEventInfoList *qmp_trace_event_get_state(const char *name, Error **errp) 171dde0f48SLluís Vilanova { 181dde0f48SLluís Vilanova TraceEventInfoList *events = NULL; 191dde0f48SLluís Vilanova bool found = false; 201dde0f48SLluís Vilanova TraceEvent *ev; 211dde0f48SLluís Vilanova 221dde0f48SLluís Vilanova ev = NULL; 231dde0f48SLluís Vilanova while ((ev = trace_event_pattern(name, ev)) != NULL) { 241dde0f48SLluís Vilanova TraceEventInfoList *elem = g_new(TraceEventInfoList, 1); 251dde0f48SLluís Vilanova elem->value = g_new(TraceEventInfo, 1); 261dde0f48SLluís Vilanova elem->value->name = g_strdup(trace_event_get_name(ev)); 271dde0f48SLluís Vilanova if (!trace_event_get_state_static(ev)) { 281dde0f48SLluís Vilanova elem->value->state = TRACE_EVENT_STATE_UNAVAILABLE; 291dde0f48SLluís Vilanova } else if (!trace_event_get_state_dynamic(ev)) { 301dde0f48SLluís Vilanova elem->value->state = TRACE_EVENT_STATE_DISABLED; 311dde0f48SLluís Vilanova } else { 321dde0f48SLluís Vilanova elem->value->state = TRACE_EVENT_STATE_ENABLED; 331dde0f48SLluís Vilanova } 341dde0f48SLluís Vilanova elem->next = events; 351dde0f48SLluís Vilanova events = elem; 361dde0f48SLluís Vilanova found = true; 371dde0f48SLluís Vilanova } 381dde0f48SLluís Vilanova 391dde0f48SLluís Vilanova if (!found && !trace_event_is_pattern(name)) { 401dde0f48SLluís Vilanova error_setg(errp, "unknown event \"%s\"", name); 411dde0f48SLluís Vilanova } 421dde0f48SLluís Vilanova 431dde0f48SLluís Vilanova return events; 441dde0f48SLluís Vilanova } 451dde0f48SLluís Vilanova 461dde0f48SLluís Vilanova void qmp_trace_event_set_state(const char *name, bool enable, 471dde0f48SLluís Vilanova bool has_ignore_unavailable, 481dde0f48SLluís Vilanova bool ignore_unavailable, Error **errp) 491dde0f48SLluís Vilanova { 501dde0f48SLluís Vilanova bool found = false; 511dde0f48SLluís Vilanova TraceEvent *ev; 521dde0f48SLluís Vilanova 531dde0f48SLluís Vilanova /* Check all selected events are dynamic */ 541dde0f48SLluís Vilanova ev = NULL; 551dde0f48SLluís Vilanova while ((ev = trace_event_pattern(name, ev)) != NULL) { 561dde0f48SLluís Vilanova found = true; 571dde0f48SLluís Vilanova if (!(has_ignore_unavailable && ignore_unavailable) && 581dde0f48SLluís Vilanova !trace_event_get_state_static(ev)) { 591dde0f48SLluís Vilanova error_setg(errp, "cannot set dynamic tracing state for \"%s\"", 601dde0f48SLluís Vilanova trace_event_get_name(ev)); 611dde0f48SLluís Vilanova return; 621dde0f48SLluís Vilanova } 631dde0f48SLluís Vilanova } 641dde0f48SLluís Vilanova if (!found && !trace_event_is_pattern(name)) { 651dde0f48SLluís Vilanova error_setg(errp, "unknown event \"%s\"", name); 661dde0f48SLluís Vilanova return; 671dde0f48SLluís Vilanova } 681dde0f48SLluís Vilanova 691dde0f48SLluís Vilanova /* Apply changes */ 701dde0f48SLluís Vilanova ev = NULL; 711dde0f48SLluís Vilanova while ((ev = trace_event_pattern(name, ev)) != NULL) { 721dde0f48SLluís Vilanova if (trace_event_get_state_static(ev)) { 731dde0f48SLluís Vilanova trace_event_set_state_dynamic(ev, enable); 741dde0f48SLluís Vilanova } 751dde0f48SLluís Vilanova } 761dde0f48SLluís Vilanova } 77