[libvirt] [PATCH 02/19] virsh: Allow extracting 'return' section of QMP command in 'qemu-monitor-command'

Peter Krempa pkrempa at redhat.com
Thu Dec 12 17:18:32 UTC 2019


Simplify gathering the actual return value from a passed-through QMP
command when using 'qemu-monitor-command' by adding '--return-value'
switch which just extracts the 'return' section and alternatively
reports an error if the section is not present.

This simplifies gathering of some test data where the full reply would
need to be trimmed just for the actual return value.

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 docs/manpages/virsh.rst |  5 ++++-
 tools/virsh-domain.c    | 44 ++++++++++++++++++++++++++++++++---------
 2 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 697f83e5b2..7ec620f6ee 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -7434,7 +7434,7 @@ qemu-monitor-command

 .. code-block:: shell

-   qemu-monitor-command domain { [--hmp] | [--qmp] [--pretty] } command...
+   qemu-monitor-command domain { [--hmp] | [--qmp] [--pretty] [--return-value] } command...

 Send an arbitrary monitor command *command* to domain *domain* through the
 qemu monitor.  The results of the command will be printed on stdout.
@@ -7451,6 +7451,9 @@ of the QMP command verbatim.
 If *--pretty* is given, and the monitor uses QMP, then the output will be
 pretty-printed.

+If *--return-value* is given the 'return' key of the QMP response object is
+extracted rather than passing through the full reply from qemu.
+
 If *--hmp* is passed, the command is considered to be a human monitor command
 and libvirt will automatically convert it into QMP if needed.  In that case
 the result will also be converted back from QMP.
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 9447fa2904..a592726042 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -9526,6 +9526,10 @@ static const vshCmdOptDef opts_qemu_monitor_command[] = {
      .type = VSH_OT_BOOL,
      .help = N_("wrap the 'cmd' argument in JSON wrapper for QMP")
     },
+    {.name = "return-value",
+     .type = VSH_OT_BOOL,
+     .help = N_("extract the value of the 'return' key from the returned string")
+    },
     {.name = "cmd",
      .type = VSH_OT_ARGV,
      .flags = VSH_OFLAG_REQ,
@@ -9540,13 +9544,19 @@ cmdQemuMonitorCommand(vshControl *ctl, const vshCmd *cmd)
     g_autoptr(virshDomain) dom = NULL;
     g_autofree char *monitor_cmd = NULL;
     g_autofree char *result = NULL;
+    g_autoptr(virJSONValue) resultjson = NULL;
     unsigned int flags = 0;
     const vshCmdOpt *opt = NULL;
     virBuffer buf = VIR_BUFFER_INITIALIZER;
     bool qmp = vshCommandOptBool(cmd, "qmp");
+    bool pretty = vshCommandOptBool(cmd, "pretty");
+    bool returnval = vshCommandOptBool(cmd, "return-value");
+    virJSONValuePtr formatjson;
+    g_autofree char *jsonstr = NULL;

     VSH_EXCLUSIVE_OPTIONS("hmp", "pretty");
     VSH_EXCLUSIVE_OPTIONS("hmp", "qmp");
+    VSH_EXCLUSIVE_OPTIONS("hmp", "return-value");

     if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
         return false;
@@ -9584,17 +9594,33 @@ cmdQemuMonitorCommand(vshControl *ctl, const vshCmd *cmd)
     if (virDomainQemuMonitorCommand(dom, monitor_cmd, &result, flags) < 0)
         return false;

-    if (vshCommandOptBool(cmd, "pretty")) {
-        char *tmp;
-        if ((tmp = virJSONStringReformat(result, true))) {
-            VIR_FREE(result);
-            result = tmp;
-            virTrimSpaces(result, NULL);
-        } else {
-            vshResetLibvirtError();
+    if (returnval || pretty) {
+        resultjson = virJSONValueFromString(result);
+
+        if (returnval && !resultjson) {
+            vshError(ctl, "failed to parse JSON returned by qemu");
+            return false;
         }
     }
-    vshPrint(ctl, "%s\n", result);
+
+    /* print raw non-prettified result */
+    if (!resultjson) {
+        vshPrint(ctl, "%s\n", result);
+        return true;
+    }
+
+    if (returnval) {
+        if (!(formatjson = virJSONValueObjectGet(resultjson, "return"))) {
+            vshError(ctl, "'return' member missing");
+            return false;
+        }
+    } else {
+        formatjson = resultjson;
+    }
+
+    jsonstr = virJSONValueToString(formatjson, pretty);
+    virTrimSpaces(jsonstr, NULL);
+    vshPrint(ctl, "%s", jsonstr);
     return true;
 }

-- 
2.23.0




More information about the libvir-list mailing list