1 /* 2 * QMP commands for tracing events. 3 * 4 * Copyright (C) 2014-2016 Lluís Vilanova <vilanova@ac.upc.edu> 5 * 6 * This work is licensed under the terms of the GNU GPL, version 2 or later. 7 * See the COPYING file in the top-level directory. 8 */ 9 10 #include "qemu/osdep.h" 11 #include "qapi/error.h" 12 #include "qapi/qapi-commands-trace.h" 13 #include "control.h" 14 15 16 static bool check_events(bool ignore_unavailable, bool is_pattern, 17 const char *name, Error **errp) 18 { 19 if (!is_pattern) { 20 TraceEvent *ev = trace_event_name(name); 21 22 /* error for non-existing event */ 23 if (ev == NULL) { 24 error_setg(errp, "unknown event \"%s\"", name); 25 return false; 26 } 27 28 /* error for unavailable event */ 29 if (!ignore_unavailable && !trace_event_get_state_static(ev)) { 30 error_setg(errp, "event \"%s\" is disabled", name); 31 return false; 32 } 33 34 return true; 35 } else { 36 /* error for unavailable events */ 37 TraceEventIter iter; 38 TraceEvent *ev; 39 trace_event_iter_init_pattern(&iter, name); 40 while ((ev = trace_event_iter_next(&iter)) != NULL) { 41 if (!ignore_unavailable && !trace_event_get_state_static(ev)) { 42 error_setg(errp, "event \"%s\" is disabled", trace_event_get_name(ev)); 43 return false; 44 } 45 } 46 return true; 47 } 48 } 49 50 TraceEventInfoList *qmp_trace_event_get_state(const char *name, 51 Error **errp) 52 { 53 TraceEventInfoList *events = NULL; 54 TraceEventIter iter; 55 TraceEvent *ev; 56 bool is_pattern = trace_event_is_pattern(name); 57 58 /* Check events */ 59 if (!check_events(true, is_pattern, name, errp)) { 60 return NULL; 61 } 62 63 /* Get states (all errors checked above) */ 64 trace_event_iter_init_pattern(&iter, name); 65 while ((ev = trace_event_iter_next(&iter)) != NULL) { 66 TraceEventInfo *value; 67 68 value = g_new(TraceEventInfo, 1); 69 value->name = g_strdup(trace_event_get_name(ev)); 70 71 if (!trace_event_get_state_static(ev)) { 72 value->state = TRACE_EVENT_STATE_UNAVAILABLE; 73 } else { 74 if (trace_event_get_state_dynamic(ev)) { 75 value->state = TRACE_EVENT_STATE_ENABLED; 76 } else { 77 value->state = TRACE_EVENT_STATE_DISABLED; 78 } 79 } 80 QAPI_LIST_PREPEND(events, value); 81 } 82 83 return events; 84 } 85 86 void qmp_trace_event_set_state(const char *name, bool enable, 87 bool has_ignore_unavailable, bool ignore_unavailable, 88 Error **errp) 89 { 90 TraceEventIter iter; 91 TraceEvent *ev; 92 bool is_pattern = trace_event_is_pattern(name); 93 94 /* Check events */ 95 if (!check_events(has_ignore_unavailable && ignore_unavailable, 96 is_pattern, name, errp)) { 97 return; 98 } 99 100 /* Apply changes (all errors checked above) */ 101 trace_event_iter_init_pattern(&iter, name); 102 while ((ev = trace_event_iter_next(&iter)) != NULL) { 103 if (!trace_event_get_state_static(ev)) { 104 continue; 105 } 106 trace_event_set_state_dynamic(ev, enable); 107 } 108 } 109