From 0731c421fdbddb2c820d51609bda5b803389017f Mon Sep 17 00:00:00 2001 From: Brian M Date: Mon, 16 Mar 2026 20:19:45 -0700 Subject: [PATCH] iscsi-scstd: Return SVC_UNAVAILABLE while logins are suspended SIGUSR1/SIGUSR2 set/clear logins_suspended. While set, any login attempt is rejected with a retriable Target Error instead of the permanent Initiator Error (TGT_NOT_FOUND) that causes initiators to give up. --- iscsi-scst/usr/iscsi_scstd.c | 20 ++++++++++++++++++++ iscsi-scst/usr/iscsid.c | 8 ++++++++ iscsi-scst/usr/iscsid.h | 1 + 3 files changed, 29 insertions(+) diff --git a/iscsi-scst/usr/iscsi_scstd.c b/iscsi-scst/usr/iscsi_scstd.c index 99380c01e..279e9eed5 100644 --- a/iscsi-scst/usr/iscsi_scstd.c +++ b/iscsi-scst/usr/iscsi_scstd.c @@ -858,6 +858,18 @@ static void init_max_params(void) return; } +static void suspend_logins(int sig) +{ + (void)sig; + logins_suspended = 1; +} + +static void resume_logins(int sig) +{ + (void)sig; + logins_suspended = 0; +} + int main(int argc, char **argv) { int ch, longindex; @@ -883,6 +895,14 @@ int main(int argc, char **argv) int rc = sigaction(SIGPIPE, &act, NULL); assert(rc == 0); + act = (struct sigaction) { .sa_handler = suspend_logins }; + rc = sigaction(SIGUSR1, &act, NULL); + assert(rc == 0); + + act = (struct sigaction) { .sa_handler = resume_logins }; + rc = sigaction(SIGUSR2, &act, NULL); + assert(rc == 0); + while ((ch = getopt_long(argc, argv, "c:fd:s:u:g:a:p:vh", long_options, &longindex)) >= 0) { switch (ch) { case 'c': diff --git a/iscsi-scst/usr/iscsid.c b/iscsi-scst/usr/iscsid.c index d32b672ff..1c089ab53 100644 --- a/iscsi-scst/usr/iscsid.c +++ b/iscsi-scst/usr/iscsid.c @@ -28,6 +28,7 @@ int iscsi_enabled; char *internal_portal; +int logins_suspended; static u32 ttt; @@ -811,6 +812,13 @@ static void login_start(struct connection *conn) return; } + if (logins_suspended) { + log_info("Initiator %s login rejected: service temporarily unavailable", + conn->initiator); + login_rsp_tgt_err(conn, ISCSI_STATUS_SVC_UNAVAILABLE); + return; + } + session_type = text_key_find(conn, "SessionType"); target_name = text_key_find(conn, "TargetName"); diff --git a/iscsi-scst/usr/iscsid.h b/iscsi-scst/usr/iscsid.h index 63ffab278..2240cfcbd 100644 --- a/iscsi-scst/usr/iscsid.h +++ b/iscsi-scst/usr/iscsid.h @@ -263,6 +263,7 @@ extern const char *get_error_str(int error); /* iscsid.c */ extern int iscsi_enabled; extern char *internal_portal; +extern int logins_suspended; extern int cmnd_execute(struct connection *conn); extern void cmnd_finish(struct connection *conn);