This command lists all disk devices with errors --- tools/virsh.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 7 ++++ 2 files changed, 96 insertions(+), 0 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 3a59746..1b93852 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -16037,6 +16037,94 @@ cleanup: } /* + * "domioerror" command + */ +static const char * +vshDomainIOErrorToString(int error) +{ + switch ((virDomainDiskErrorCode) error) { + case VIR_DOMAIN_DISK_ERROR_NONE: + return _("no error"); + case VIR_DOMAIN_DISK_ERROR_UNSPEC: + return _("unspecified error"); + case VIR_DOMAIN_DISK_ERROR_NO_SPACE: + return _("no space"); + case VIR_DOMAIN_DISK_ERROR_LAST: + ; + } + + return _("unknown error"); +} + +static const vshCmdInfo info_domblkerror[] = { + {"help", N_("Show errors on block devices")}, + {"desc", N_("Show block device errors")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_domblkerror[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id, or uuid")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdDomBlkError(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom; + char *xml; + xmlDocPtr xmldoc = NULL; + xmlXPathContextPtr ctxt = NULL; + virDomainDiskErrorPtr disks = NULL; + int ndisks; + int i; + int count; + bool ret = false; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return false; + + if (!(xml = virDomainGetXMLDesc(dom, 0))) + goto cleanup; + + xmldoc = virXMLParseStringCtxt(xml, _("(domain_definition)"), &ctxt); + VIR_FREE(xml); + if (!xmldoc) + goto cleanup; + + if (virXPathInt("count(./devices/disk)", ctxt, &ndisks) < 0) + goto cleanup; + + if (ndisks < 1) { + vshError(ctl, _("no disks attached to this domain")); + goto cleanup; + } + + if (VIR_ALLOC_N(disks, ndisks) < 0) + goto cleanup; + + if ((count = virDomainGetDiskErrors(dom, disks, ndisks, 0)) == -1) + goto cleanup; + + for (i = 0; i < count; i++) { + vshPrint(ctl, "%s: %s\n", + disks[i].disk, + vshDomainIOErrorToString(disks[i].error)); + } + + 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[] = { @@ -16240,6 +16328,7 @@ static const vshCmdDef domMonitoringCmds[] = { {"domblklist", cmdDomblklist, opts_domblklist, info_domblklist, 0}, {"domblkstat", cmdDomblkstat, opts_domblkstat, info_domblkstat, 0}, {"domcontrol", cmdDomControl, opts_domcontrol, info_domcontrol, 0}, + {"domblkerror", cmdDomBlkError, opts_domblkerror, info_domblkerror, 0}, {"domif-getlink", cmdDomIfGetLink, opts_domif_getlink, info_domif_getlink, 0}, {"domiflist", cmdDomiflist, opts_domiflist, info_domiflist, 0}, {"domifstat", cmdDomIfstat, opts_domifstat, info_domifstat, 0}, diff --git a/tools/virsh.pod b/tools/virsh.pod index 4bc25bf..e9598ac 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -507,6 +507,13 @@ on hypervisor. Get memory stats for a running domain. +=item B<domblkerror> I<domain-id> + +Show errors on block devices. This command usually comes handy when +B<domstate> command says that a domain was paused due to I/O error. +The B<domblkerror> command lists all block devices in error state and +the error seen on each of them. + =item B<domblkinfo> I<domain> I<block-device> Get block device size info for a domain. A I<block-device> corresponds -- 1.7.8.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list