qemu-kvm/kvm-scsi-disk-pass-guest-recoverable-errors-through-even.patch
2021-03-22 07:55:49 +01:00

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