[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, ¶ms, &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, ¶ms, &nparams, 0) < 0) {
- if ((state = virshDomainState(ctl, dom, &reason)) < 0) {
- ret = false;
- goto cleanup;
- }
+ if ((showInfo &&
+ virDomainGetStateParams(dom, &state, &reason, ¶ms, &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