From 4222dc483070614336724183ca4b69e612aee616 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 23 Sep 2015 17:10:10 +0000 Subject: [PATCH] scst_tg: Reject READ and WRITE commands for ports that are in the ALUA state "standby" git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6519 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/README | 4 ---- scst/include/scst_const.h | 1 + scst/src/scst_tg.c | 30 +++++++++++++++++++++++++++++- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/scst/README b/scst/README index a5d14625b..31228e452 100644 --- a/scst/README +++ b/scst/README @@ -1460,10 +1460,6 @@ information about how to associate iSCSI targets with a single physical interface. Notes: -- The ALUA specification allows but does not require that SCSI READ and WRITE - commands are rejected by ports that are not active. SCST processes READ and - WRITE commands unless these are received through a port that is in the - unavailable, transitioning or offline state. - In a H.A. setup it is the responsibility of the user to synchronize ALUA information between the individual systems running SCST. There are no provisions in SCST to exchange ALUA information automatically between diff --git a/scst/include/scst_const.h b/scst/include/scst_const.h index b695f1d4b..7d8ded58d 100644 --- a/scst/include/scst_const.h +++ b/scst/include/scst_const.h @@ -291,6 +291,7 @@ static inline int scst_sense_response_code(const uint8_t *sense) /* NOT_READY is 2 */ #define scst_sense_format_in_progress NOT_READY, 0x04, 0x04 #define scst_sense_tp_transitioning NOT_READY, 0x04, 0x0A +#define scst_sense_tp_standby NOT_READY, 0x04, 0x0B #define scst_sense_tp_unav NOT_READY, 0x04, 0x0C #define scst_sense_no_medium NOT_READY, 0x3a, 0 diff --git a/scst/src/scst_tg.c b/scst/src/scst_tg.c index 2ab483608..3dc891a7a 100644 --- a/scst/src/scst_tg.c +++ b/scst/src/scst_tg.c @@ -297,6 +297,34 @@ static bool scst_tg_accept(struct scst_cmd *cmd) return false; } +/* + * Whether or not to accept a command in the ALUA standby state. + */ +static bool scst_tg_accept_standby(struct scst_cmd *cmd) +{ + bool process_cmd = scst_tg_accept(cmd); + + if (process_cmd) + return process_cmd; + + switch (cmd->cdb[0]) { + case MODE_SELECT: + case MODE_SELECT_10: + case LOG_SELECT: + case LOG_SENSE: + case RECEIVE_DIAGNOSTIC: + case SEND_DIAGNOSTIC: + case PERSISTENT_RESERVE_IN: + case PERSISTENT_RESERVE_OUT: + return true; + } + + scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_tp_standby)); + + return false; +} + + /* * Whether or not to accept a command in the ALUA unavailable state. */ @@ -327,7 +355,7 @@ static bool scst_tg_accept_transitioning(struct scst_cmd *cmd) static bool (*scst_alua_filter[])(struct scst_cmd *cmd) = { [SCST_TG_STATE_OPTIMIZED] = NULL, [SCST_TG_STATE_NONOPTIMIZED] = NULL, - [SCST_TG_STATE_STANDBY] = NULL, + [SCST_TG_STATE_STANDBY] = scst_tg_accept_standby, [SCST_TG_STATE_UNAVAILABLE] = scst_tg_accept_unav, [SCST_TG_STATE_LBA_DEPENDENT] = NULL, [SCST_TG_STATE_OFFLINE] = scst_tg_accept_unav,