From 3c44092635f47c174f943fa81bb155b47816511c Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Sun, 13 Dec 2015 14:29:32 -0800 Subject: [PATCH] Add a feature to request transparent reconnects without any UA Normal applications want the current behaviour where we have the library consume any/all of the UnitAttentions that the target may have queued on the initial connection, but when we reconnect the session after a failure the library will pass all the UAs back to the application to process. Some applications, such as the test suite or really trivial applications might not want to have to deal with handling of UAs and just "make it work". Those applications can now request that upon any reconnection of the session that libiscsi will automatically consume any and all UAs and hide them from the application. Signed-off-by: Ronnie Sahlberg --- include/iscsi-private.h | 1 + include/iscsi.h | 6 ++++++ lib/connect.c | 19 ++++++++++++++++++- lib/libiscsi.def | 1 + lib/libiscsi.syms | 1 + test-tool/iscsi-test-cu.c | 2 ++ 6 files changed, 29 insertions(+), 1 deletion(-) diff --git a/include/iscsi-private.h b/include/iscsi-private.h index 00f215c..77425b0 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -159,6 +159,7 @@ struct iscsi_context { int scsi_timeout; struct iscsi_context *old_iscsi; int retry_cnt; + int no_ua_on_reconnect; }; #define ISCSI_PDU_IMMEDIATE 0x40 diff --git a/include/iscsi.h b/include/iscsi.h index 5be7080..923e2ab 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -1305,6 +1305,12 @@ iscsi_set_bind_interfaces(struct iscsi_context *iscsi, char * interfaces); EXTERN void iscsi_set_reconnect_max_retries(struct iscsi_context *iscsi, int count); +/* Set to true to have libiscsi use TESTUNITREADY and consume any/all + UnitAttentions that may have triggered in the target. + */ +EXTERN void +iscsi_set_no_ua_on_reconnect(struct iscsi_context *iscsi, int state); + #ifdef __cplusplus } #endif diff --git a/lib/connect.c b/lib/connect.c index c108d3d..7de0d8d 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -130,7 +130,11 @@ iscsi_login_cb(struct iscsi_context *iscsi, int status, void *command_data _U_, return; } - if (ct->lun != -1 && !iscsi->old_iscsi) { + /* If the application has requested no UA on reconnect OR if this is + the initial connection attempt then we need to consume any/all + UAs that might be present. + */ + if (iscsi->no_ua_on_reconnect || (ct->lun != -1 && !iscsi->old_iscsi)) { if (iscsi_testunitready_task(iscsi, ct->lun, iscsi_testunitready_cb, ct) == NULL) { iscsi_set_error(iscsi, "iscsi_testunitready_async failed."); @@ -210,6 +214,18 @@ void iscsi_set_noautoreconnect(struct iscsi_context *iscsi, int state) } } +/* Set ua reconnect status. The default is that we just reconnect and then + any/all UAs that are generated by the target will be passed back to the + application. + + For test applications it can be more convenient to just reconnect + and have any UAs be consumed and ignored by the library. +*/ +void iscsi_set_no_ua_on_reconnect(struct iscsi_context *iscsi, int state) +{ + iscsi->no_ua_on_reconnect = state; +} + void iscsi_set_reconnect_max_retries(struct iscsi_context *iscsi, int count) { iscsi->reconnect_max_retries = count; @@ -413,6 +429,7 @@ int iscsi_reconnect(struct iscsi_context *old_iscsi) iscsi->tcp_syncnt = old_iscsi->tcp_syncnt; iscsi->cache_allocations = old_iscsi->cache_allocations; iscsi->scsi_timeout = old_iscsi->scsi_timeout; + iscsi->no_ua_on_reconnect = old_iscsi->no_ua_on_reconnect; iscsi->reconnect_max_retries = old_iscsi->reconnect_max_retries; diff --git a/lib/libiscsi.def b/lib/libiscsi.def index 6ead7a9..4fc6352 100644 --- a/lib/libiscsi.def +++ b/lib/libiscsi.def @@ -98,6 +98,7 @@ iscsi_set_isid_en iscsi_set_isid_oui iscsi_set_isid_random iscsi_set_isid_reserved +iscsi_set_no_ua_on_reconnect iscsi_set_session_type iscsi_set_target_username_pwd iscsi_set_targetname diff --git a/lib/libiscsi.syms b/lib/libiscsi.syms index ec76288..24dfd5a 100644 --- a/lib/libiscsi.syms +++ b/lib/libiscsi.syms @@ -96,6 +96,7 @@ iscsi_set_isid_en iscsi_set_isid_oui iscsi_set_isid_random iscsi_set_isid_reserved +iscsi_set_no_ua_on_reconnect iscsi_set_session_type iscsi_set_target_username_pwd iscsi_set_targetname diff --git a/test-tool/iscsi-test-cu.c b/test-tool/iscsi-test-cu.c index ae44d3c..64021cb 100644 --- a/test-tool/iscsi-test-cu.c +++ b/test-tool/iscsi-test-cu.c @@ -769,6 +769,7 @@ suite_init(void) "error: Failed to login to target for test set-up\n"); return 1; } + iscsi_set_no_ua_on_reconnect(mp_sds[i]->iscsi_ctx, 1); } #ifndef HAVE_CU_SUITEINFO_PSETUPFUNC /* libcunit version 1 */ @@ -961,6 +962,7 @@ static int connect_scsi_device(struct scsi_device *sdev, const char *initiatorna if (sdev->iscsi_ctx == NULL) { return -1; } + iscsi_set_no_ua_on_reconnect(sdev->iscsi_ctx, 1); return 0; } #ifdef HAVE_SG_IO