0a122b
From 771a3a333eb0c9299a69a78ddb9c4181850b827d Mon Sep 17 00:00:00 2001
0a122b
From: Laszlo Ersek <lersek@redhat.com>
0a122b
Date: Thu, 21 Nov 2013 16:27:18 +0100
0a122b
Subject: [PATCH 08/14] error reason in BLOCK_IO_ERROR / BLOCK_JOB_ERROR events (RHEL 6->7 fwd)
0a122b
0a122b
RH-Author: Laszlo Ersek <lersek@redhat.com>
0a122b
Message-id: <1385051239-3677-3-git-send-email-lersek@redhat.com>
0a122b
Patchwork-id: 55835
0a122b
O-Subject: [RHEL-7.0 qemu-kvm PATCH 2/3] error reason in BLOCK_IO_ERROR / BLOCK_JOB_ERROR events (RHEL 6->7 fwd)
0a122b
Bugzilla: 971938
0a122b
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
0a122b
RH-Acked-by: Jiri Denemark <jdenemar@redhat.com>
0a122b
RH-Acked-by: Luiz Capitulino <lcapitulino@redhat.com>
0a122b
0a122b
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=971938
0a122b
0a122b
This is the RHEL-7 forward port of the RHEL-6 only commit
0a122b
0a122b
  commit a635efd74e0968dd4402ba87679af3015930a8cb
0a122b
  Author: Luiz Capitulino <lcapitulino@redhat.com>
0a122b
  Date:   Fri May 14 22:49:20 2010 -0300
0a122b
0a122b
      QMP: Add error reason to BLOCK_IO_ERROR event
0a122b
0a122b
The RHEL-6 patch had to be updated due to the following three upstream
0a122b
commits that we have in RHEL-7 by virtue of forking:
0a122b
0a122b
  [v1.1.0]
0a122b
  commit 329c0a48a92664eb48b70993c0f2473b37aa7429
0a122b
  Author: Luiz Capitulino <lcapitulino@redhat.com>
0a122b
  Date:   Wed Jan 25 16:59:43 2012 -0200
0a122b
0a122b
      block: Rename bdrv_mon_event() & BlockMonEventAction
0a122b
0a122b
  [v1.3.0]
0a122b
  commit 3e1caa5f76a9104a0d574b0f28b3dafe986a8408
0a122b
  Author: Paolo Bonzini <pbonzini@redhat.com>
0a122b
  Date:   Fri Sep 28 17:22:57 2012 +0200
0a122b
0a122b
      iostatus: reorganize io error code
0a122b
0a122b
  [v1.3.0]
0a122b
  commit 32c81a4a6ecc3f50efc9c270a269e4d3d8a9fbd5
0a122b
  Author: Paolo Bonzini <pbonzini@redhat.com>
0a122b
  Date:   Fri Sep 28 17:22:58 2012 +0200
0a122b
0a122b
      block: introduce block job error
0a122b
0a122b
The 2nd and 3rd of these actually simplified the RHEL-6 to RHEL-7
0a122b
forward-port because it had concentrated all calls to
0a122b
bdrv_emit_qmp_error_event() to two locations, taking the error code as an
0a122b
input parameter. The forward-ported patch can simply forward the error
0a122b
code now.
0a122b
0a122b
RHEL-6 doesn't have BLOCK_JOB_ERROR at all. This forward-port extends the
0a122b
RH-specific error reason reporting to BLOCK_JOB_ERROR automatically.
0a122b
(Except for "QMP/qmp-events.txt", where BLOCK_JOB_ERROR's documentation
0a122b
needed manual patching.)
0a122b
0a122b
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
0a122b
---
0a122b
 include/block/block_int.h |  4 +++-
0a122b
 block.c                   | 33 +++++++++++++++++++++++++++++++--
0a122b
 blockjob.c                |  3 ++-
0a122b
 QMP/qmp-events.txt        | 18 ++++++++++++++++--
0a122b
 4 files changed, 52 insertions(+), 6 deletions(-)
0a122b
0a122b
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
0a122b
---
0a122b
 QMP/qmp-events.txt        |   18 ++++++++++++++++--
0a122b
 block.c                   |   33 +++++++++++++++++++++++++++++++--
0a122b
 blockjob.c                |    3 ++-
0a122b
 include/block/block_int.h |    4 +++-
0a122b
 4 files changed, 52 insertions(+), 6 deletions(-)
0a122b
0a122b
diff --git a/QMP/qmp-events.txt b/QMP/qmp-events.txt
0a122b
index 79fb1c9..c8c6d75 100644
0a122b
--- a/QMP/qmp-events.txt
0a122b
+++ b/QMP/qmp-events.txt
0a122b
@@ -53,13 +53,20 @@ Data:
0a122b
     "ignore": error has been ignored
0a122b
     "report": error has been reported to the device
0a122b
     "stop": error caused VM to be stopped
0a122b
+- "__com.redhat_reason": error reason, this is a RHEL7 extension, it's one of
0a122b
+  the following (json-string):
0a122b
+    "eio": errno EIO
0a122b
+    "eperm": errno EPERM
0a122b
+    "enospc": errno ENOSPC
0a122b
+    "eother": any other errno (other than EIO, EPERM, ENOSPC)
0a122b
 
0a122b
 Example:
0a122b
 
0a122b
 { "event": "BLOCK_IO_ERROR",
0a122b
     "data": { "device": "ide0-hd1",
0a122b
               "operation": "write",
0a122b
-              "action": "stop" },
0a122b
+              "action": "stop",
0a122b
+              "__com.redhat_reason": "enospc" },
0a122b
     "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
0a122b
 
0a122b
 Note: If action is "stop", a STOP event will eventually follow the
0a122b
@@ -131,13 +138,20 @@ Data:
0a122b
     "ignore": error has been ignored, the job may fail later
0a122b
     "report": error will be reported and the job canceled
0a122b
     "stop": error caused job to be paused
0a122b
+- "__com.redhat_reason": error reason, this is a RHEL7 extension, it's one of
0a122b
+  the following (json-string):
0a122b
+    "eio": errno EIO
0a122b
+    "eperm": errno EPERM
0a122b
+    "enospc": errno ENOSPC
0a122b
+    "eother": any other errno (other than EIO, EPERM, ENOSPC)
0a122b
 
0a122b
 Example:
0a122b
 
0a122b
 { "event": "BLOCK_JOB_ERROR",
0a122b
     "data": { "device": "ide0-hd1",
0a122b
               "operation": "write",
0a122b
-              "action": "stop" },
0a122b
+              "action": "stop",
0a122b
+              "__com.redhat_reason": "enospc" },
0a122b
     "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
0a122b
 
0a122b
 BLOCK_JOB_READY
0a122b
diff --git a/block.c b/block.c
0a122b
index 72ab36c..68755bf 100644
0a122b
--- a/block.c
0a122b
+++ b/block.c
0a122b
@@ -1723,9 +1723,36 @@ void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
0a122b
     bs->dev_opaque = opaque;
0a122b
 }
0a122b
 
0a122b
+#define BDRV_REASON_KEY RFQDN_REDHAT "reason"
0a122b
+
0a122b
+/* RHEL7 vendor extension */
0a122b
+static void bdrv_put_rhel7_reason(QDict *event, int error)
0a122b
+{
0a122b
+    const char *reason;
0a122b
+
0a122b
+    switch (error) {
0a122b
+    case ENOSPC:
0a122b
+        reason = "enospc";
0a122b
+        break;
0a122b
+    case EPERM:
0a122b
+        reason = "eperm";
0a122b
+        break;
0a122b
+    case EIO:
0a122b
+        reason = "eio";
0a122b
+        break;
0a122b
+    default:
0a122b
+        reason = "eother";
0a122b
+        break;
0a122b
+    }
0a122b
+
0a122b
+    qdict_put(event, BDRV_REASON_KEY, qstring_from_str(reason));
0a122b
+}
0a122b
+
0a122b
 void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv,
0a122b
                                enum MonitorEvent ev,
0a122b
-                               BlockErrorAction action, bool is_read)
0a122b
+                               BlockErrorAction action,
0a122b
+                               int error,
0a122b
+                               bool is_read)
0a122b
 {
0a122b
     QObject *data;
0a122b
     const char *action_str;
0a122b
@@ -1748,6 +1775,7 @@ void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv,
0a122b
                               bdrv->device_name,
0a122b
                               action_str,
0a122b
                               is_read ? "read" : "write");
0a122b
+    bdrv_put_rhel7_reason(qobject_to_qdict(data), error);
0a122b
     monitor_protocol_event(ev, data);
0a122b
 
0a122b
     qobject_decref(data);
0a122b
@@ -2905,7 +2933,8 @@ void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action,
0a122b
                        bool is_read, int error)
0a122b
 {
0a122b
     assert(error >= 0);
0a122b
-    bdrv_emit_qmp_error_event(bs, QEVENT_BLOCK_IO_ERROR, action, is_read);
0a122b
+    bdrv_emit_qmp_error_event(bs, QEVENT_BLOCK_IO_ERROR, action, error,
0a122b
+                              is_read);
0a122b
     if (action == BDRV_ACTION_STOP) {
0a122b
         vm_stop(RUN_STATE_IO_ERROR);
0a122b
         bdrv_iostatus_set_err(bs, error);
0a122b
diff --git a/blockjob.c b/blockjob.c
0a122b
index ca80df1..c0a22d9 100644
0a122b
--- a/blockjob.c
0a122b
+++ b/blockjob.c
0a122b
@@ -271,7 +271,8 @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs,
0a122b
     default:
0a122b
         abort();
0a122b
     }
0a122b
-    bdrv_emit_qmp_error_event(job->bs, QEVENT_BLOCK_JOB_ERROR, action, is_read);
0a122b
+    bdrv_emit_qmp_error_event(job->bs, QEVENT_BLOCK_JOB_ERROR, action, error,
0a122b
+                              is_read);
0a122b
     if (action == BDRV_ACTION_STOP) {
0a122b
         block_job_pause(job);
0a122b
         block_job_iostatus_set_err(job, error);
0a122b
diff --git a/include/block/block_int.h b/include/block/block_int.h
0a122b
index 54708c6..8223f5b 100644
0a122b
--- a/include/block/block_int.h
0a122b
+++ b/include/block/block_int.h
0a122b
@@ -320,7 +320,9 @@ int is_windows_drive(const char *filename);
0a122b
 #endif
0a122b
 void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv,
0a122b
                                enum MonitorEvent ev,
0a122b
-                               BlockErrorAction action, bool is_read);
0a122b
+                               BlockErrorAction action,
0a122b
+                               int error,
0a122b
+                               bool is_read);
0a122b
 
0a122b
 /**
0a122b
  * stream_start:
0a122b
-- 
0a122b
1.7.1
0a122b