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

Michal Privoznik mprivozn at redhat.com
Wed Mar 27 13:05:11 UTC 2019


On 3/25/19 9:04 AM, Bjoern Walk wrote:
> 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));

Don't we want to print this in some more machine friendly way? For instance one argument per line? Also, we have a function (sort of) that prints out typed params. You may take the inspiration from virshDomainStatsPrintRecord()

> +        }
> +        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;
> +        }
>       }

This looks fishy. Firstly, if --info was requested but we're talking to
an older daemon then virDomainGetStateParams() will fail (the API is not
there) and virshDomainState() is called instead which doesn't fill out
@params and thus we won't print any additional info even though it was
requested.

Also, printing out some error message would be nice:

diff --git i/tools/virsh-domain-monitor.c w/tools/virsh-domain-monitor.c
index bf9d4970a7..27c33f354a 100644
--- i/tools/virsh-domain-monitor.c
+++ w/tools/virsh-domain-monitor.c
@@ -1477,11 +1477,13 @@ cmdDomstate(vshControl *ctl, const vshCmd *cmd)
     if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
         return false;
 
-    if (virDomainGetStateParams(dom, &state, &reason, &params, &nparams, 0) < 0) {
-        if ((state = virshDomainState(ctl, dom, &reason)) < 0) {
-            ret = false;
-            goto cleanup;
-        }
+    if ((showInfo &&
+         virDomainGetStateParams(dom, &state, &reason, &params, &nparams, 0) < 0) ||
+        (!showInfo &&
+         (state = virshDomainState(ctl, dom, &reason)) < 0)) {
+        vshError(ctl, _("Unable to get state of domain %s"), virDomainGetName(dom));
+        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>
>   
> 


Michal




More information about the libvir-list mailing list