diff --git a/tools/virsh.c b/tools/virsh.c index 1c0b1dc83c..2e1abbdc82 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -352,6 +352,7 @@ static void vshDebug(vshControl *ctl, int level, const char *format, ...) static int vshDomainState(vshControl *ctl, virDomainPtr dom, int *reason); static const char *vshDomainStateToString(int state); static const char *vshDomainStateReasonToString(int state, int reason); +static const char *vshDomainControlStateToString(int state); static const char *vshDomainVcpuStateToString(int state); static bool vshConnectionUsability(vshControl *ctl, virConnectPtr conn); @@ -978,6 +979,53 @@ cleanup: return ret; } +/* + * "domcontrol" command + */ +static const vshCmdInfo info_domcontrol[] = { + {"help", N_("domain control interface state")}, + {"desc", N_("Returns state of a control interface to the domain.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_domcontrol[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdDomControl(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom; + bool ret = true; + virDomainControlInfo info; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return false; + + if (virDomainGetControlInfo(dom, &info, 0) < 0) { + ret = false; + goto cleanup; + } + + if (info.state != VIR_DOMAIN_CONTROL_OK && + info.state != VIR_DOMAIN_CONTROL_ERROR) { + vshPrint(ctl, "%s (%0.3fs)\n", + _(vshDomainControlStateToString(info.state)), + info.stateTime / 1000.0); + } else { + vshPrint(ctl, "%s\n", + _(vshDomainControlStateToString(info.state))); + } + +cleanup: + virDomainFree(dom); + return ret; +} + /* "domblkstat" command */ static const vshCmdInfo info_domblkstat[] = { @@ -11513,6 +11561,7 @@ static const vshCmdDef domManagementCmds[] = { static const vshCmdDef domMonitoringCmds[] = { {"domblkinfo", cmdDomblkinfo, opts_domblkinfo, info_domblkinfo, 0}, {"domblkstat", cmdDomblkstat, opts_domblkstat, info_domblkstat, 0}, + {"domcontrol", cmdDomControl, opts_domcontrol, info_domcontrol, 0}, {"domifstat", cmdDomIfstat, opts_domifstat, info_domifstat, 0}, {"dominfo", cmdDominfo, opts_dominfo, info_dominfo, 0}, {"dommemstat", cmdDomMemStat, opts_dommemstat, info_dommemstat, 0}, @@ -13041,6 +13090,23 @@ vshDomainStateReasonToString(int state, int reason) return N_("unknown"); } +static const char * +vshDomainControlStateToString(int state) +{ + switch ((virDomainControlState) state) { + case VIR_DOMAIN_CONTROL_OK: + return N_("ok"); + case VIR_DOMAIN_CONTROL_JOB: + return N_("background job"); + case VIR_DOMAIN_CONTROL_OCCUPIED: + return N_("occupied"); + case VIR_DOMAIN_CONTROL_ERROR: + return N_("error"); + } + + return N_("unknown"); +} + static const char * vshDomainVcpuStateToString(int state) { diff --git a/tools/virsh.pod b/tools/virsh.pod index c6879cb7da..755f34a5f9 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -463,6 +463,12 @@ Convert a domain Id (or UUID) to domain name Returns state about a domain. I<--reason> tells virsh to also print reason for the state. +=item B I + +Returns state of an interface to VMM used to control a domain. For +states other than "ok" or "error" the command also prints number of +seconds elapsed since the control interface entered its current state. + =item B I I Convert the file I in the native guest configuration format