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