All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
To: qemu-devel@nongnu.org
Cc: stefanha@redhat.com, pbonzini@redhat.com, michael.roth@amd.com,
	armbru@redhat.com, vsementsov@virtuozzo.com, den@openvz.org
Subject: [PATCH 5/5] trace: add qmp trace event namespace
Date: Thu, 23 Sep 2021 22:54:51 +0300	[thread overview]
Message-ID: <20210923195451.714796-6-vsementsov@virtuozzo.com> (raw)
In-Reply-To: <20210923195451.714796-1-vsementsov@virtuozzo.com>

Add a possibility to trace some qmp commands by user selection.

User API is simple: it looks like after this patch we have trace-points
for all qmp commands, in format "qmp:<qmp-command>". So user may do

  --trace qmp:drive-backup

or run qmp command trace-event-set-state with arguments

  name="qmp:drive-backup", enable=true

Patterns are supported in the same way as for general trace events, for
example:

  --trace "qmp:query-*"

to cover query-block, query-block-jobs, and a lot of other query-
commands

or

  --trace "qmp:job-*" --trace "qmp:block-job-*"

to cover job manipulation commands.

Trace event qmp covers both qmp command call and its respond.

Implementation details:

In qmp_dispatch() we add two trace points, similar to
trace_handle_qmp_command. We also check for cmd->tracking field being
set, and for handle-qmp-command/monitor-qmp-respond trace points being
disabled, to not print same information twice.

For qmp trace-event-{get,set}-state and for command line
parse additionally new "qmp:" namespace

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
 qapi/qmp-dispatch.c | 20 ++++++++++++++++++++
 softmmu/vl.c        | 21 ++++++++++++++++++++-
 trace/qmp.c         | 20 ++++++++++++++++++++
 qapi/trace-events   |  2 ++
 4 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 59600210ce..40fd008fa8 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -26,6 +26,9 @@
 #include "qemu/coroutine.h"
 #include "qemu/main-loop.h"
 
+#include "trace.h"
+#include "trace/trace-monitor.h"
+
 CompatPolicy compat_policy;
 
 Visitor *qobject_input_visitor_new_qmp(QObject *obj)
@@ -133,6 +136,12 @@ static void do_qmp_dispatch_bh(void *opaque)
     aio_co_wake(data->co);
 }
 
+static void do_trace_qmp(const char *what, QObject *obj)
+{
+    g_autoptr(GString) req_json = qobject_to_json(obj);
+    trace_qmp(what, req_json->str);
+}
+
 /*
  * Runs outside of coroutine context for OOB commands, but in coroutine
  * context for everything else.
@@ -176,6 +185,11 @@ QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request,
                   "The command %s has not been found", command);
         goto out;
     }
+    if (!trace_event_get_state_backends(TRACE_HANDLE_QMP_COMMAND) &&
+        trace_event_get_state_backends(TRACE_QMP) && cmd->tracing)
+    {
+        do_trace_qmp(">>", request);
+    }
     if (cmd->options & QCO_DEPRECATED) {
         switch (compat_policy.deprecated_input) {
         case COMPAT_POLICY_INPUT_ACCEPT:
@@ -282,5 +296,11 @@ out:
         qdict_put_obj(rsp, "id", qobject_ref(id));
     }
 
+    if (!trace_event_get_state_backends(TRACE_MONITOR_QMP_RESPOND) &&
+        trace_event_get_state_backends(TRACE_QMP) && cmd->tracing)
+    {
+        do_trace_qmp("<<", QOBJECT(rsp));
+    }
+
     return rsp;
 }
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 55ab70eb97..fd452b7013 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -2722,6 +2722,25 @@ void qmp_x_exit_preconfig(Error **errp)
     }
 }
 
+static void trace_opt_parse_with_qmp(const char *optarg)
+{
+    const char *pattern;
+    QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("trace"),
+                                             optarg, true);
+    if (!opts) {
+        exit(1);
+    }
+
+    pattern = qemu_opt_get(opts, "enable");
+    if (pattern && !strncmp(pattern, "qmp:", 4)) {
+        monitor_qmp_set_tracing(pattern + 4, true);
+        qemu_opt_del_all(opts, "enable");
+        qemu_opt_set(opts, "enable", "qmp", &error_abort);
+    }
+
+    trace_opt_parse_opts(opts);
+}
+
 void qemu_init(int argc, char **argv, char **envp)
 {
     QemuOpts *opts;
@@ -3480,7 +3499,7 @@ void qemu_init(int argc, char **argv, char **envp)
                 xen_domid_restrict = true;
                 break;
             case QEMU_OPTION_trace:
-                trace_opt_parse(optarg);
+                trace_opt_parse_with_qmp(optarg);
                 break;
             case QEMU_OPTION_plugin:
                 qemu_plugin_opt_parse(optarg, &plugin_list);
diff --git a/trace/qmp.c b/trace/qmp.c
index 3b4f4702b4..87766422d9 100644
--- a/trace/qmp.c
+++ b/trace/qmp.c
@@ -11,6 +11,7 @@
 #include "qapi/error.h"
 #include "qapi/qapi-commands-trace.h"
 #include "control-vcpu.h"
+#include "monitor/monitor.h"
 
 
 static CPUState *get_cpu(bool has_vcpu, int vcpu, Error **errp)
@@ -77,6 +78,14 @@ TraceEventInfoList *qmp_trace_event_get_state(const char *name,
     bool is_pattern = trace_event_is_pattern(name);
     CPUState *cpu;
 
+    if (!strncmp(name, "qmp:", 4)) {
+        if (!monitor_qmp_is_tracing_enabled(name + 4)) {
+            return NULL;
+        }
+
+        return qmp_trace_event_get_state("qmp", has_vcpu, vcpu, errp);
+    }
+
     /* Check provided vcpu */
     cpu = get_cpu(has_vcpu, vcpu, &err);
     if (err) {
@@ -139,6 +148,17 @@ void qmp_trace_event_set_state(const char *name, bool enable,
     bool is_pattern = trace_event_is_pattern(name);
     CPUState *cpu;
 
+    if (!strncmp(name, "qmp:", 4)) {
+        monitor_qmp_set_tracing(name + 4, enable);
+
+        if (enable || !monitor_qmp_is_tracing_enabled(NULL)) {
+            qmp_trace_event_set_state("qmp", enable, has_ignore_unavailable,
+                                      ignore_unavailable, has_vcpu, vcpu, errp);
+        }
+
+        return;
+    }
+
     /* Check provided vcpu */
     cpu = get_cpu(has_vcpu, vcpu, &err);
     if (err) {
diff --git a/qapi/trace-events b/qapi/trace-events
index cccafc07e5..753433856c 100644
--- a/qapi/trace-events
+++ b/qapi/trace-events
@@ -36,3 +36,5 @@ visit_type_str(void *v, const char *name, char **obj) "v=%p name=%s obj=%p"
 visit_type_number(void *v, const char *name, void *obj) "v=%p name=%s obj=%p"
 visit_type_any(void *v, const char *name, void *obj) "v=%p name=%s obj=%p"
 visit_type_null(void *v, const char *name, void *obj) "v=%p name=%s obj=%p"
+
+qmp(const char *what, const char *json) "%s %s"
-- 
2.29.2



  parent reply	other threads:[~2021-09-23 20:00 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-23 19:54 [PATCH 0/5] trace: inroduce qmp: trace namespace Vladimir Sementsov-Ogievskiy
2021-09-23 19:54 ` [PATCH 1/5] trace/control: introduce trace_opt_parse_opts() Vladimir Sementsov-Ogievskiy
2021-09-23 19:54 ` [PATCH 2/5] qapi/qmp: QmpCommand: add .tracing field and API Vladimir Sementsov-Ogievskiy
2021-09-23 19:54 ` [PATCH 3/5] monitor: add qmp tracing API for qmp_commands Vladimir Sementsov-Ogievskiy
2021-09-23 19:54 ` [PATCH 4/5] util/qemu-option: make qemu_opt_del_all() function public Vladimir Sementsov-Ogievskiy
2021-09-23 19:54 ` Vladimir Sementsov-Ogievskiy [this message]
2021-10-12 11:49 ` [PATCH 0/5] trace: inroduce qmp: trace namespace Markus Armbruster
2021-10-14 15:22   ` Vladimir Sementsov-Ogievskiy
2021-10-25 12:28     ` Stefan Hajnoczi
2021-10-26 10:28       ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210923195451.714796-6-vsementsov@virtuozzo.com \
    --to=vsementsov@virtuozzo.com \
    --cc=armbru@redhat.com \
    --cc=den@openvz.org \
    --cc=michael.roth@amd.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.