Retrying SCSI_STATUS_TIMEOUT up to seven times kept drain and shutdown
blocked for minutes after the target was already gone.

See: https://gitlab.com/qemu-project/qemu/-/work_items/3067
Signed-off-by: Konstantin Nigmatullin <[email protected]>
---
 block/iscsi.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/block/iscsi.c b/block/iscsi.c
index bf74b4cb65..e7f2d54986 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -240,19 +240,21 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int 
status,
 
     if (status != SCSI_STATUS_GOOD) {
         iTask->err_code = -EIO;
-        if (iTask->retries++ < ISCSI_CMD_RETRIES) {
+        if (status == SCSI_STATUS_TIMEOUT) {
+            /*
+             * Do not retry timed-out commands. Retries keep in-flight I/O
+             * alive across a dead session and can block blk_drain_all()
+             * (and thus QEMU exit) for minutes or indefinitely. Kick
+             * reconnect and fail this request.
+             */
+            error_report("iSCSI timed out: %s", iscsi_get_error(iscsi));
+            iscsilun->request_timed_out = true;
+        } else if (iTask->retries++ < ISCSI_CMD_RETRIES) {
             if (status == SCSI_STATUS_BUSY ||
-                status == SCSI_STATUS_TIMEOUT ||
                 status == SCSI_STATUS_TASK_SET_FULL) {
                 unsigned retry_time =
                     exp_random(iscsi_retry_times[iTask->retries - 1]);
-                if (status == SCSI_STATUS_TIMEOUT) {
-                    /* make sure the request is rescheduled AFTER the
-                     * reconnect is initiated */
-                    retry_time = EVENT_INTERVAL * 2;
-                    iTask->iscsilun->request_timed_out = true;
-                }
-                error_report("iSCSI Busy/TaskSetFull/TimeOut"
+                error_report("iSCSI Busy/TaskSetFull"
                              " (retry #%u in %u ms): %s",
                              iTask->retries, retry_time,
                              iscsi_get_error(iscsi));
-- 
2.53.0


Reply via email to