107 lines
3.9 KiB
Diff
107 lines
3.9 KiB
Diff
From 9cf10f41fc8a89cd80f27e3b2674dec7eead60d4 Mon Sep 17 00:00:00 2001
|
|
From: Paolo Bonzini <pbonzini@redhat.com>
|
|
Date: Mon, 8 Mar 2021 10:49:02 -0500
|
|
Subject: [PATCH 05/15] scsi-disk: pass guest recoverable errors through even
|
|
for rerror=stop
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
|
|
Message-id: <20210308104902.149906-6-pbonzini@redhat.com>
|
|
Patchwork-id: 101311
|
|
O-Subject: [RHEL-AV-8.4.0 qemu-kvm PATCH 5/5] scsi-disk: pass guest recoverable errors through even for rerror=stop
|
|
Bugzilla: 1927530
|
|
RH-Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
|
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
|
|
|
Right now, recoverable sense values are only passed directly to the
|
|
guest only for rerror=report. However, when rerror/werror are 'stop'
|
|
we still don't want the host to be involved on every UNIT ATTENTION
|
|
(especially considered that the QMP event will not have enough information
|
|
to act on the report).
|
|
|
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
(cherry picked from commit 782a78c9e994c2be23467262f50e885a0eb0d9fc)
|
|
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
|
---
|
|
hw/scsi/scsi-disk.c | 51 +++++++++++++++++++++++++--------------------
|
|
1 file changed, 28 insertions(+), 23 deletions(-)
|
|
|
|
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
|
|
index c545f0b674..f2abbf0d87 100644
|
|
--- a/hw/scsi/scsi-disk.c
|
|
+++ b/hw/scsi/scsi-disk.c
|
|
@@ -211,39 +211,44 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed)
|
|
}
|
|
}
|
|
|
|
- action = blk_get_error_action(s->qdev.conf.blk, is_read, error);
|
|
- if (action == BLOCK_ERROR_ACTION_REPORT) {
|
|
+ /*
|
|
+ * Check whether the error has to be handled by the guest or should
|
|
+ * rather follow the rerror=/werror= settings. Guest-handled errors
|
|
+ * are usually retried immediately, so do not post them to QMP and
|
|
+ * do not account them as failed I/O.
|
|
+ */
|
|
+ if (req_has_sense &&
|
|
+ scsi_sense_buf_is_guest_recoverable(r->req.sense, sizeof(r->req.sense))) {
|
|
+ action = BLOCK_ERROR_ACTION_REPORT;
|
|
+ acct_failed = false;
|
|
+ } else {
|
|
+ action = blk_get_error_action(s->qdev.conf.blk, is_read, error);
|
|
+ blk_error_action(s->qdev.conf.blk, action, is_read, error);
|
|
+ }
|
|
+
|
|
+ switch (action) {
|
|
+ case BLOCK_ERROR_ACTION_REPORT:
|
|
if (acct_failed) {
|
|
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
|
}
|
|
if (req_has_sense) {
|
|
- /* A passthrough command has run and has produced sense data; check
|
|
- * whether the error has to be handled by the guest or should rather
|
|
- * pause the host.
|
|
- */
|
|
- if (scsi_sense_buf_is_guest_recoverable(r->req.sense, sizeof(r->req.sense))) {
|
|
- /* These errors are handled by guest. */
|
|
- sdc->update_sense(&r->req);
|
|
- scsi_req_complete(&r->req, status);
|
|
- return true;
|
|
- }
|
|
- } else {
|
|
- if (status == CHECK_CONDITION) {
|
|
- scsi_req_build_sense(&r->req, sense);
|
|
- }
|
|
- scsi_req_complete(&r->req, status);
|
|
+ sdc->update_sense(&r->req);
|
|
+ } else if (status == CHECK_CONDITION) {
|
|
+ scsi_req_build_sense(&r->req, sense);
|
|
}
|
|
- }
|
|
+ scsi_req_complete(&r->req, status);
|
|
+ return true;
|
|
|
|
- blk_error_action(s->qdev.conf.blk, action, is_read, error);
|
|
- if (action == BLOCK_ERROR_ACTION_IGNORE) {
|
|
+ case BLOCK_ERROR_ACTION_IGNORE:
|
|
return false;
|
|
- }
|
|
|
|
- if (action == BLOCK_ERROR_ACTION_STOP) {
|
|
+ case BLOCK_ERROR_ACTION_STOP:
|
|
scsi_req_retry(&r->req);
|
|
+ return true;
|
|
+
|
|
+ default:
|
|
+ g_assert_not_reached();
|
|
}
|
|
- return true;
|
|
}
|
|
|
|
static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed)
|
|
--
|
|
2.27.0
|
|
|