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(a)linux.ibm.com>
Signed-off-by: Bjoern Walk <bwalk(a)linux.ibm.com>
---
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