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