[libvirt] [PATCH v2 6/7] virsh: domstate: report detailed state if available

Bjoern Walk bwalk at linux.ibm.com
Mon Mar 25 08:04:56 UTC 2019


Add a new parameter to virsh domstate, --info, to report additional
information for the domain state, e.g. for a QEMU guest running a S390
domain:

    virsh # domstate --info guest-1
    crashed (panicked: s390: core='0' psw-mask='0x0002000180000000' \
             psw-addr='0x000000000010f146' reason='disabled-wait')

When the new API virDomainGetStateParams is not available for the server
or not supported by the hypervisor driver, fall back to the old API
using virDomainGetState function.

The --info parameter implies the --reason parameter and if additional
information is not available, the output is the same.

Reviewed-by: Boris Fiuczynski <fiuczy at linux.ibm.com>
Signed-off-by: Bjoern Walk <bwalk at linux.ibm.com>
---
 tools/virsh-domain-monitor.c | 102 +++++++++++++++++++++++++++++++----
 tools/virsh.pod              |   5 +-
 2 files changed, 95 insertions(+), 12 deletions(-)

diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index ad739a9d..bf9d4970 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -1391,35 +1391,117 @@ static const vshCmdOptDef opts_domstate[] = {
      .type = VSH_OT_BOOL,
      .help = N_("also print reason for the state")
     },
+    {.name = "info",
+     .type = VSH_OT_BOOL,
+     .help = N_("also print reason and information for the state")
+    },
     {.name = NULL}
 };
 
+static char *
+vshStateInfoMsgFormat(virTypedParameterPtr params,
+                      int nparams)
+{
+    char *ret = NULL;
+    int type;
+
+    if (virTypedParamsGetInt(params, nparams,
+                             VIR_DOMAIN_STATE_PARAMS_INFO_TYPE, &type) < 0) {
+        return NULL;
+    }
+
+    switch (type) {
+    case VIR_DOMAIN_STATE_INFO_TYPE_QEMU_HYPERV: {
+        unsigned long long arg1, arg2, arg3, arg4, arg5;
+
+        if (virTypedParamsGetULLong(params, nparams,
+                                    VIR_DOMAIN_STATE_PARAMS_PANIC_INFO_HYPERV_ARG1, &arg1) < 0 ||
+            virTypedParamsGetULLong(params, nparams,
+                                    VIR_DOMAIN_STATE_PARAMS_PANIC_INFO_HYPERV_ARG2, &arg2) < 0 ||
+            virTypedParamsGetULLong(params, nparams,
+                                    VIR_DOMAIN_STATE_PARAMS_PANIC_INFO_HYPERV_ARG3, &arg3) < 0 ||
+            virTypedParamsGetULLong(params, nparams,
+                                    VIR_DOMAIN_STATE_PARAMS_PANIC_INFO_HYPERV_ARG4, &arg4) < 0 ||
+            virTypedParamsGetULLong(params, nparams,
+                                    VIR_DOMAIN_STATE_PARAMS_PANIC_INFO_HYPERV_ARG5, &arg5) < 0) {
+            return NULL;
+        }
+
+        ignore_value(virAsprintf(&ret, "hyper-v: arg1='0x%llx', arg2='0x%llx', "
+                                 "arg3='0x%llx', arg4='0x%llx', arg5='0x%llx'",
+                                 arg1, arg2, arg3, arg4, arg5));
+        }
+        break;
+    case VIR_DOMAIN_STATE_INFO_TYPE_QEMU_S390: {
+        int core;
+        unsigned long long psw_mask;
+        unsigned long long psw_addr;
+        const char *reason;
+
+        if (virTypedParamsGetInt(params, nparams,
+                                 VIR_DOMAIN_STATE_PARAMS_PANIC_INFO_S390_CORE, &core) < 0 ||
+            virTypedParamsGetULLong(params, nparams,
+                                    VIR_DOMAIN_STATE_PARAMS_PANIC_INFO_S390_PSW_MASK, &psw_mask) < 0 ||
+            virTypedParamsGetULLong(params, nparams,
+                                    VIR_DOMAIN_STATE_PARAMS_PANIC_INFO_S390_PSW_ADDR, &psw_addr) < 0 ||
+            virTypedParamsGetString(params, nparams,
+                                    VIR_DOMAIN_STATE_PARAMS_PANIC_INFO_S390_PSW_REASON, &reason) < 0) {
+            return NULL;
+        }
+
+        ignore_value(virAsprintf(&ret, "s390: core='%d' psw-mask='0x%016llx' "
+                                 "psw-addr='0x%016llx' reason='%s'",
+                                 core, psw_mask, psw_addr, reason));
+        }
+        break;
+    case VIR_DOMAIN_STATE_INFO_TYPE_NONE:
+    case VIR_DOMAIN_STATE_INFO_TYPE_LAST:
+        break;
+    }
+
+    return ret;
+}
+
 static bool
 cmdDomstate(vshControl *ctl, const vshCmd *cmd)
 {
     virDomainPtr dom;
     bool ret = true;
     bool showReason = vshCommandOptBool(cmd, "reason");
+    bool showInfo = vshCommandOptBool(cmd, "info");
+    virTypedParameterPtr params = NULL;
+    int nparams = 0;
     int state, reason;
+    char *info = NULL;
 
     if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
         return false;
 
-    if ((state = virshDomainState(ctl, dom, &reason)) < 0) {
-        ret = false;
-        goto cleanup;
+    if (virDomainGetStateParams(dom, &state, &reason, &params, &nparams, 0) < 0) {
+        if ((state = virshDomainState(ctl, dom, &reason)) < 0) {
+            ret = false;
+            goto cleanup;
+        }
     }
 
-    if (showReason) {
-        vshPrint(ctl, "%s (%s)\n",
-                 virshDomainStateToString(state),
-                 virshDomainStateReasonToString(state, reason));
-    } else {
-        vshPrint(ctl, "%s\n",
-                 virshDomainStateToString(state));
+    vshPrint(ctl, "%s", virshDomainStateToString(state));
+
+    if (showReason || showInfo) {
+        vshPrint(ctl, " (%s", virshDomainStateReasonToString(state, reason));
+
+        if (showInfo) {
+            info = vshStateInfoMsgFormat(params, nparams);
+            if (info)
+                vshPrint(ctl, ": %s", info);
+        }
+        vshPrint(ctl, ")");
     }
 
+    vshPrint(ctl, "\n");
+
  cleanup:
+    VIR_FREE(info);
+    virTypedParamsFree(params, nparams);
     virshDomainFree(dom);
     return ret;
 }
diff --git a/tools/virsh.pod b/tools/virsh.pod
index db723431..82ab83a3 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1568,10 +1568,11 @@ specified in the second argument.
 
 B<Note>: Domain must be inactive and without snapshots.
 
-=item B<domstate> I<domain> [I<--reason>]
+=item B<domstate> I<domain> [I<--reason>] [I<--info>]
 
 Returns state about a domain.  I<--reason> tells virsh to also print
-reason for the state.
+reason for the state. I<--info> prints additional state information if
+available, I<--info> implies I<--reason>.
 
 =item B<domcontrol> I<domain>
 
-- 
2.17.0




More information about the libvir-list mailing list