9119d9
From f7959239dcc411b050db4b5560d7349df7f8f848 Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <f7959239dcc411b050db4b5560d7349df7f8f848@dist-git>
9119d9
From: Eric Blake <eblake@redhat.com>
9119d9
Date: Fri, 3 Oct 2014 08:46:25 -0600
9119d9
Subject: [PATCH] qemu: support nospace reason in io error event
9119d9
9119d9
Aeons ago (commit 34dcbbb4, v0.8.2), we added a new libvirt event
9119d9
(VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON) in order to tell the user WHY
9119d9
the guest halted.  This is because at least VDSM wants to react
9119d9
differently to ENOSPC events (resize the lvm partition to be larger,
9119d9
and resume the guest as if nothing had happened) from all other events
9119d9
(I/O is hosed, throw up our hands and flag things as broken).  At the
9119d9
time this was done, downstream RHEL qemu added a vendor extension
9119d9
'__com.redhat_reason', which would be exactly one of these strings:
9119d9
"enospc", "eperm", "eio", and "eother".  In our stupidity, we exposed
9119d9
those exact strings to clients, rather than an enum, and we also
9119d9
return "" if we did not have access to a reason (which was the case
9119d9
for upstream qemu).
9119d9
9119d9
Fast forward to now: upstream qemu commit c7c2ff0c (will be qemu 2.2)
9119d9
FINALLY adds a 'nospace' boolean, after discussion with multiple
9119d9
projects determined that VDSM really doesn't care about distinction
9119d9
between any other error types.  So this patch converts 'nospace' into
9119d9
the string "enospc" for compatibility with RHEL clients that were
9119d9
already used to the downstream extension, while leaving the reason
9119d9
blank for all other cases (no change from the status quo).
9119d9
9119d9
See also https://bugzilla.redhat.com/show_bug.cgi?id=1119784
9119d9
9119d9
* src/qemu/qemu_monitor_json.c (qewmuMonitorJSONHandleIOError):
9119d9
Parse reason field from modern qemu.
9119d9
* include/libvirt/libvirt.h.in
9119d9
(virConnectDomainEventIOErrorReasonCallback): Document it.
9119d9
9119d9
Signed-off-by: Eric Blake <eblake@redhat.com>
9119d9
(cherry picked from commit e9392e48d4e3b29809da7883b697d5caf3a09680)
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
9119d9
Conflicts:
9119d9
	src/qemu/qemu_monitor_json.c -- RHEL-only addition of
9119d9
        __com.redhat_reason
9119d9
9119d9
This backport removes the RHEL-only __com.redhat_reason to make the code
9119d9
match upstream. The next patch will add the RHEL-only reason back. This
9119d9
is to make future rebases easier. We won't have to rework this once
9119d9
again, we can just drop the old RHEL-only patch and this backport and
9119d9
only keep the new RHEL-only patch.
9119d9
---
9119d9
 include/libvirt/libvirt.h.in |  6 ++++++
9119d9
 src/qemu/qemu_monitor_json.c | 12 ++++++------
9119d9
 2 files changed, 12 insertions(+), 6 deletions(-)
9119d9
9119d9
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
9119d9
index 60b3e0b..3ca935e 100644
9119d9
--- a/include/libvirt/libvirt.h.in
9119d9
+++ b/include/libvirt/libvirt.h.in
9119d9
@@ -4853,6 +4853,12 @@ typedef void (*virConnectDomainEventIOErrorCallback)(virConnectPtr conn,
9119d9
  * The callback signature to use when registering for an event of type
9119d9
  * VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON with virConnectDomainEventRegisterAny()
9119d9
  *
9119d9
+ * If the I/O error is known to be caused by an ENOSPC condition in
9119d9
+ * the host (where resizing the disk to be larger will allow the guest
9119d9
+ * to be resumed as if nothing happened), @reason will be "enospc".
9119d9
+ * Otherwise, @reason will be "", although future strings may be added
9119d9
+ * if determination of other error types becomes possible.
9119d9
+ *
9119d9
  */
9119d9
 typedef void (*virConnectDomainEventIOErrorReasonCallback)(virConnectPtr conn,
9119d9
                                                            virDomainPtr dom,
9119d9
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
9119d9
index adf560a..7dcea2e 100644
9119d9
--- a/src/qemu/qemu_monitor_json.c
9119d9
+++ b/src/qemu/qemu_monitor_json.c
9119d9
@@ -717,11 +717,13 @@ VIR_ENUM_IMPL(qemuMonitorIOErrorAction, VIR_DOMAIN_EVENT_IO_ERROR_LAST,
9119d9
               "ignore", "stop", "report");
9119d9
 
9119d9
 
9119d9
-static void qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr data)
9119d9
+static void
9119d9
+qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr data)
9119d9
 {
9119d9
     const char *device;
9119d9
     const char *action;
9119d9
-    const char *reason;
9119d9
+    const char *reason = "";
9119d9
+    bool nospc = false;
9119d9
     int actionID;
9119d9
 
9119d9
     /* Throughout here we try our best to carry on upon errors,
9119d9
@@ -737,10 +739,8 @@ static void qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr dat
9119d9
         VIR_WARN("missing device in disk io error event");
9119d9
     }
9119d9
 
9119d9
-    if ((reason = virJSONValueObjectGetString(data, "__com.redhat_reason")) == NULL) {
9119d9
-        VIR_WARN("missing __com.redhat_reason in disk io error event");
9119d9
-        reason = "";
9119d9
-    }
9119d9
+    if (virJSONValueObjectGetBoolean(data, "nospace", &nospc) == 0 && nospc)
9119d9
+        reason = "enospc";
9119d9
 
9119d9
     if ((actionID = qemuMonitorIOErrorActionTypeFromString(action)) < 0) {
9119d9
         VIR_WARN("unknown disk io error action '%s'", action);
9119d9
-- 
9119d9
2.1.3
9119d9