--- tools/virsh.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 11 +++++ 2 files changed, 122 insertions(+), 0 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index d635b56..92029fd 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -15809,6 +15809,116 @@ cleanup: } /* + * "domioerror" command + */ +static const char * +vshDomainIOErrorToString(int error) +{ + switch ((virDomainIoError) error) { + case VIR_DOMAIN_IOERROR_NONE: + return _("no error"); + case VIR_DOMAIN_IOERROR_NO_SPACE: + return _("no space"); + case VIR_DOMAIN_IOERROR_UNSPEC: + return _("unspecified error"); + case VIR_DOMAIN_IOERROR_LAST: + ; + } + + return _("unknown error"); +} + +static const vshCmdInfo info_domioerror[] = { + {"help", N_("Show I/O error on a disk device")}, + {"desc", N_("Show I/O error")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_domioerror[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id, or uuid")}, + {"disk", VSH_OT_DATA, 0, N_("disk device")}, + {"all", VSH_OT_BOOL, 0, N_("show error on all attached disks")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdDomIOError(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom; + const char *dev = NULL; + bool all = vshCommandOptBool(cmd, "all"); + char *xml; + xmlDocPtr xmldoc = NULL; + xmlXPathContextPtr ctxt = NULL; + xmlNodePtr *disks = NULL; + int ndisks; + int i; + int result; + bool ret = false; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return false; + + if (vshCommandOptString(cmd, "disk", &dev) < 0) + goto cleanup; + if (dev && all) { + vshError(ctl, "%s", + _("--disk and --all options are mutually exclusive")); + goto cleanup; + } + + if (all) { + if (!(xml = virDomainGetXMLDesc(dom, 0))) + goto cleanup; + + xmldoc = virXMLParseStringCtxt(xml, _("(domain_definition)"), &ctxt); + VIR_FREE(xml); + if (!xmldoc) + goto cleanup; + + ndisks = virXPathNodeSet("./devices/disk/target", ctxt, &disks); + if (ndisks < 0) + goto cleanup; + + for (i = 0; i < ndisks; i++) { + char *disk; + + if (!(disk = virXMLPropString(disks[i], "dev"))) + continue; + + if ((result = virDomainGetIoError(dom, disk, 0)) < 0) { + VIR_FREE(disk); + goto cleanup; + } + + vshPrint(ctl, "%s: %s\n", disk, vshDomainIOErrorToString(result)); + VIR_FREE(disk); + } + } else { + if ((result = virDomainGetIoError(dom, dev, 0)) == -1) + goto cleanup; + if (result == -2) { + vshError(ctl, _("there are multiple devices with error")); + goto cleanup; + } + + vshPrint(ctl, "%s", vshDomainIOErrorToString(result)); + } + + ret = true; + +cleanup: + VIR_FREE(disks); + xmlXPathFreeContext(ctxt); + xmlFreeDoc(xmldoc); + virDomainFree(dom); + return ret; +} + +/* * "qemu-monitor-command" command */ static const vshCmdInfo info_qemu_monitor_command[] = { @@ -16014,6 +16124,7 @@ static const vshCmdDef domMonitoringCmds[] = { {"domiflist", cmdDomiflist, opts_domiflist, info_domiflist, 0}, {"domifstat", cmdDomIfstat, opts_domifstat, info_domifstat, 0}, {"dominfo", cmdDominfo, opts_dominfo, info_dominfo, 0}, + {"domioerror", cmdDomIOError, opts_domioerror, info_domioerror, 0}, {"dommemstat", cmdDomMemStat, opts_dommemstat, info_dommemstat, 0}, {"domstate", cmdDomstate, opts_domstate, info_domstate, 0}, {"list", cmdList, opts_list, info_list, 0}, diff --git a/tools/virsh.pod b/tools/virsh.pod index 67f93a9..a8574a5 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -595,6 +595,17 @@ new size in kilobytes Returns basic information about the domain. +=item B<domioerror> I<domain-id> { [I<--all>] | [I<disk>] } + +Show domain I/O error. This command usually comes handy when B<domstate> +command says that a domain was paused due to I/O error. The B<domioerror> +command works in three modes. With I<--all> option, it prints all disk +devices configured for the domain and I/O errors associated with them. In +case I<disk> is specified, this command only prints the I/O error associated +with the specified disk. When neither I<--all> nor I<disk> is specified and +there is at most one disk device in I/O error state, the command prints it. +Otherwise the command fails. + =item B<domuuid> I<domain-name-or-id> Convert a domain name or id to domain UUID -- 1.7.8.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list