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@xxxxxxxxxxxxx> Signed-off-by: Bjoern Walk <bwalk@xxxxxxxxxxxxx> --- 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, ¶ms, &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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list