Signed-off-by: Lluís Vilanova <vilan...@ac.upc.edu>
---
 qapi-schema.json    |    3 ++
 qapi/trace.json     |   65 ++++++++++++++++++++++++++++++++++++++++++++
 qmp-commands.hx     |   35 ++++++++++++++++++++++++
 trace/Makefile.objs |    1 +
 trace/qmp.c         |   75 +++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 179 insertions(+)
 create mode 100644 qapi/trace.json
 create mode 100644 trace/qmp.c

diff --git a/qapi-schema.json b/qapi-schema.json
index 341f417..42b90df 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -11,6 +11,9 @@
 # QAPI event definitions
 { 'include': 'qapi/event.json' }
 
+# Tracing commands
+{ 'include': 'qapi/trace.json' }
+
 ##
 # LostTickPolicy:
 #
diff --git a/qapi/trace.json b/qapi/trace.json
new file mode 100644
index 0000000..06c613c
--- /dev/null
+++ b/qapi/trace.json
@@ -0,0 +1,65 @@
+# -*- mode: python -*-
+#
+# Copyright (C) 2011-2014 Lluís Vilanova <vilan...@ac.upc.edu>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+
+
+##
+# @TraceEventState:
+#
+# State of a tracing event.
+#
+# @unavailable: The event is statically disabled.
+#
+# @disabled: The event is dynamically disabled.
+#
+# @enabled: The event is dynamically enabled.
+#
+# Since 2.2
+##
+{ 'enum': 'TraceEventState',
+  'data': ['unavailable', 'disabled', 'enabled'] }
+
+##
+# @TraceEventInfo:
+#
+# Information of a tracing event.
+#
+# @name: Event name.
+# @state: Tracing state.
+#
+# Since 2.2
+##
+{ 'type': 'TraceEventInfo',
+  'data': {'name': 'str', 'state': 'TraceEventState'} }
+
+##
+# @trace-event-get-state:
+#
+# Query the state of events.
+#
+# @name: Event name pattern (case-sensitive glob).
+#
+# Returns: a list of @TraceEventInfo for the matching events
+#
+# Since 2.2
+##
+{ 'command': 'trace-event-get-state',
+  'data': {'name': 'str'},
+  'returns': ['TraceEventInfo'] }
+
+##
+# @trace-event-set-state:
+#
+# Set the dynamic tracing state of events.
+#
+# @name: Event name pattern (case-sensitive glob).
+# @enable: Whether to enable tracing.
+# @ignore-unavailable: #optional Do not match unavailable events with @name.
+#
+# Since 2.2
+##
+{ 'command': 'trace-event-set-state',
+  'data': {'name': 'str', 'enable': 'bool', '*ignore-unavailable': 'bool'} }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 4be4765..b605517 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3753,5 +3753,40 @@ Example:
 
 -> { "execute": "rtc-reset-reinjection" }
 <- { "return": {} }
+EQMP
+
+    {
+        .name       = "trace-event-get-state",
+        .args_type  = "name:s",
+        .mhandler.cmd_new = qmp_marshal_input_trace_event_get_state,
+    },
+
+SQMP
+trace-event-get-state
+---------------------
+
+Query the state of events.
+
+Example:
+
+-> { "execute": "trace-event-get-state", "arguments": { "name": 
"qemu_memalign" } }
+<- { "return": [ { "name": "qemu_memalign", "state": "disabled" } ] }
+EQMP
+
+    {
+        .name       = "trace-event-set-state",
+        .args_type  = "name:s,enable:b,ignore-unavailable:b?",
+        .mhandler.cmd_new = qmp_marshal_input_trace_event_set_state,
+    },
 
+SQMP
+trace-event-set-state
+---------------------
+
+Set the state of events.
+
+Example:
+
+-> { "execute": "trace-event-set-state", "arguments": { "name": 
"qemu_memalign", "enable": "true" } }
+<- { "return": {} }
 EQMP
diff --git a/trace/Makefile.objs b/trace/Makefile.objs
index 387f191..01b3718 100644
--- a/trace/Makefile.objs
+++ b/trace/Makefile.objs
@@ -145,3 +145,4 @@ util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o
 util-obj-$(CONFIG_TRACE_UST) += generated-ust.o
 util-obj-y += control.o
 util-obj-y += generated-tracers.o
+util-obj-y += qmp.o
diff --git a/trace/qmp.c b/trace/qmp.c
new file mode 100644
index 0000000..0b19489
--- /dev/null
+++ b/trace/qmp.c
@@ -0,0 +1,75 @@
+/*
+ * QMP commands for tracing events.
+ *
+ * Copyright (C) 2014 Lluís Vilanova <vilan...@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/typedefs.h"
+#include "qmp-commands.h"
+#include "trace/control.h"
+
+
+TraceEventInfoList *qmp_trace_event_get_state(const char *name, Error **errp)
+{
+    TraceEventInfoList *events = NULL;
+    bool found = false;
+    TraceEvent *ev;
+
+    ev = NULL;
+    while ((ev = trace_event_pattern(name, ev)) != NULL) {
+        TraceEventInfoList *elem = g_new(TraceEventInfoList, 1);
+        elem->value = g_new(TraceEventInfo, 1);
+        elem->value->name = g_strdup(trace_event_get_name(ev));
+        if (!trace_event_get_state_static(ev)) {
+            elem->value->state = TRACE_EVENT_STATE_UNAVAILABLE;
+        } else if (!trace_event_get_state_dynamic(ev)) {
+            elem->value->state = TRACE_EVENT_STATE_DISABLED;
+        } else {
+            elem->value->state = TRACE_EVENT_STATE_ENABLED;
+        }
+        elem->next = events;
+        events = elem;
+        found = true;
+    }
+
+    if (!found && !trace_event_is_pattern(name)) {
+        error_setg(errp, "unknown event \"%s\"", name);
+    }
+
+    return events;
+}
+
+void qmp_trace_event_set_state(const char *name, bool enable,
+                               bool has_ignore_unavailable,
+                               bool ignore_unavailable, Error **errp)
+{
+    bool found = false;
+    TraceEvent *ev;
+
+    /* Check all selected events are dynamic */
+    ev = NULL;
+    while ((ev = trace_event_pattern(name, ev)) != NULL) {
+        found = true;
+        if (!(has_ignore_unavailable && ignore_unavailable) &&
+            !trace_event_get_state_static(ev)) {
+            error_setg(errp, "cannot set dynamic tracing state for \"%s\"",
+                       trace_event_get_name(ev));
+            return;
+        }
+    }
+    if (!found && !trace_event_is_pattern(name)) {
+        error_setg(errp, "unknown event \"%s\"", name);
+        return;
+    }
+
+    /* Apply changes */
+    ev = NULL;
+    while ((ev = trace_event_pattern(name, ev)) != NULL) {
+        if (trace_event_get_state_static(ev)) {
+            trace_event_set_state_dynamic(ev, enable);
+        }
+    }
+}


Reply via email to