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 s390.psw-mask = 0x0002000180000000 s390.psw-addr = 0x000000000010f146 s390.reason = disabled-wait When the --info parameter is specified and the new API virDomainGetStateParams is not available for the server or not supported by the hypervisor driver an error is reported. The --info parameter implies the --reason parameter and if additional information is not available, the output is identical. Reviewed-by: Boris Fiuczynski <fiuczy@xxxxxxxxxxxxx> Signed-off-by: Bjoern Walk <bwalk@xxxxxxxxxxxxx> --- tools/virsh-domain-monitor.c | 94 +++++++++++++++++++++++++++++++++--- tools/virsh.pod | 5 +- 2 files changed, 90 insertions(+), 9 deletions(-) diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c index ad739a9d..a26f7371 100644 --- a/tools/virsh-domain-monitor.c +++ b/tools/virsh-domain-monitor.c @@ -1391,35 +1391,115 @@ 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 void +vshStateInfoMsgPrint(vshControl *ctl, + virTypedParameterPtr params, + int nparams) +{ + int type; + + if (virTypedParamsGetInt(params, nparams, + VIR_DOMAIN_STATE_PARAM_TYPE, &type) < 0) { + return; + } + + switch (type) { + case VIR_DOMAIN_STATE_PARAM_TYPE_QEMU_HYPERV: { + unsigned long long arg1, arg2, arg3, arg4, arg5; + + if (virTypedParamsGetULLong(params, nparams, + VIR_DOMAIN_STATE_PARAM_CRASHED_PANICKED_HYPERV_ARG1, &arg1) < 0 || + virTypedParamsGetULLong(params, nparams, + VIR_DOMAIN_STATE_PARAM_CRASHED_PANICKED_HYPERV_ARG2, &arg2) < 0 || + virTypedParamsGetULLong(params, nparams, + VIR_DOMAIN_STATE_PARAM_CRASHED_PANICKED_HYPERV_ARG3, &arg3) < 0 || + virTypedParamsGetULLong(params, nparams, + VIR_DOMAIN_STATE_PARAM_CRASHED_PANICKED_HYPERV_ARG4, &arg4) < 0 || + virTypedParamsGetULLong(params, nparams, + VIR_DOMAIN_STATE_PARAM_CRASHED_PANICKED_HYPERV_ARG5, &arg5) < 0) { + return; + } + + vshPrint(ctl, _("hyperv.arg1 = 0x%llx\n"), arg1); + vshPrint(ctl, _("hyperv.arg2 = 0x%llx\n"), arg2); + vshPrint(ctl, _("hyperv.arg3 = 0x%llx\n"), arg3); + vshPrint(ctl, _("hyperv.arg4 = 0x%llx\n"), arg4); + vshPrint(ctl, _("hyperv.arg5 = 0x%llx\n"), arg5); + + break; + } + case VIR_DOMAIN_STATE_PARAM_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_PARAM_CRASHED_PANICKED_S390_CORE, &core) < 0 || + virTypedParamsGetULLong(params, nparams, + VIR_DOMAIN_STATE_PARAM_CRASHED_PANICKED_S390_PSW_MASK, &psw_mask) < 0 || + virTypedParamsGetULLong(params, nparams, + VIR_DOMAIN_STATE_PARAM_CRASHED_PANICKED_S390_PSW_ADDR, &psw_addr) < 0 || + virTypedParamsGetString(params, nparams, + VIR_DOMAIN_STATE_PARAM_CRASHED_PANICKED_S390_REASON, &reason) < 0) { + return; + } + + vshPrint(ctl, _("s390.core = %d\n"), core); + vshPrint(ctl, _("s390.psw-mask = 0x%016llx\n"), psw_mask); + vshPrint(ctl, _("s390.psw-addr = 0x%016llx\n"), psw_addr); + vshPrint(ctl, _("s390.reason = %s\n"), reason); + + break; + } + case VIR_DOMAIN_STATE_PARAM_TYPE_NONE: + case VIR_DOMAIN_STATE_PARAM_TYPE_LAST: + break; + } +} + 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; if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) return false; - if ((state = virshDomainState(ctl, dom, &reason)) < 0) { + 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)); + vshPrint(ctl, "%s", virshDomainStateToString(state)); + + if (showReason || showInfo) { + vshPrint(ctl, " (%s)\n", virshDomainStateReasonToString(state, reason)); + + if (showInfo) + vshStateInfoMsgPrint(ctl, params, nparams); } else { - vshPrint(ctl, "%s\n", - virshDomainStateToString(state)); + vshPrint(ctl, "\n"); } cleanup: + virTypedParamsFree(params, nparams); virshDomainFree(dom); return ret; } diff --git a/tools/virsh.pod b/tools/virsh.pod index b7ceba8d..d7a06dc9 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1572,10 +1572,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.19.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list