diff --git a/share/man/man4/iscsi.4 b/share/man/man4/iscsi.4 --- a/share/man/man4/iscsi.4 +++ b/share/man/man4/iscsi.4 @@ -20,7 +20,7 @@ .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. -.Dd May 28, 2017 +.Dd October 10, 2023 .Dt ISCSI 4 .Os .Sh NAME @@ -72,6 +72,7 @@ forcibly restarted. Set to 0 to disable sending NOP-Out PDUs. Defaults to 5. +This can be set in increments of 0.1 seconds. .It Va kern.iscsi.iscsid_timeout The number of seconds to wait for .Xr iscsid 8 @@ -79,13 +80,13 @@ After that time .Nm will abort and retry. -Defaults to 60. +Defaults to 60 and accepts increments of 0.1. .It Va kern.iscsi.login_timeout The number of seconds to wait for a login attempt to succeed. After that time .Nm will abort and retry. -Defaults to 60. +Defaults to 60 and accepts increments of 0.1. .It Va kern.iscsi.maxtags The maximum number of outstanding IO requests. Defaults to 255. diff --git a/sys/dev/iscsi/iscsi.c b/sys/dev/iscsi/iscsi.c --- a/sys/dev/iscsi/iscsi.c +++ b/sys/dev/iscsi/iscsi.c @@ -102,15 +102,15 @@ SYSCTL_INT(_kern_iscsi, OID_AUTO, debug, CTLFLAG_RWTUN, &debug, 0, "Enable debug messages"); -static int ping_timeout = 5; +static int ping_timeout = 5000; SYSCTL_INT(_kern_iscsi, OID_AUTO, ping_timeout, CTLFLAG_RWTUN, &ping_timeout, - 0, "Timeout for ping (NOP-Out) requests, in seconds"); -static int iscsid_timeout = 60; + 0, "Timeout for ping (NOP-Out) requests, in milliseconds"); +static int iscsid_timeout = 60000; SYSCTL_INT(_kern_iscsi, OID_AUTO, iscsid_timeout, CTLFLAG_RWTUN, &iscsid_timeout, - 0, "Time to wait for iscsid(8) to handle reconnection, in seconds"); -static int login_timeout = 60; + 0, "Time to wait for iscsid(8) to handle reconnection, in milliseconds"); +static int login_timeout = 60000; SYSCTL_INT(_kern_iscsi, OID_AUTO, login_timeout, CTLFLAG_RWTUN, &login_timeout, - 0, "Time to wait for iscsid(8) to finish Login Phase, in seconds"); + 0, "Time to wait for iscsid(8) to finish Login Phase, in milliseconds"); static int maxtags = 255; SYSCTL_INT(_kern_iscsi, OID_AUTO, maxtags, CTLFLAG_RWTUN, &maxtags, 0, "Max number of IO requests queued"); @@ -583,6 +583,8 @@ struct iscsi_session *is; bool reconnect_needed = false; sbintime_t sbt, pr; + bool fast_timer = false; + char tmpstr[5]; is = context; @@ -592,29 +594,38 @@ return; } - sbt = mstosbt(995); + fast_timer = ((is->is_ping_timeout <= 2000) || + (is->is_login_timeout <= 2000)); + sbt = mstosbt(fast_timer ? 95 : 995); pr = mstosbt(10); callout_schedule_sbt(&is->is_callout, sbt, pr, 0); if (is->is_conf.isc_enable == 0) goto out; - is->is_timeout++; + is->is_timeout += (fast_timer ? 100 : 1000); + tmpstr[0] = '\0'; if (is->is_waiting_for_iscsid) { - if (iscsid_timeout > 0 && is->is_timeout > iscsid_timeout) { + if (iscsid_timeout > 0 && is->is_timeout >= iscsid_timeout) { + if (fast_timer && ((is->is_timeout % 1000) != 0)) + snprintf(tmpstr, sizeof(tmpstr), ".%03d", + is->is_timeout % 1000); ISCSI_SESSION_WARN(is, "timed out waiting for iscsid(8) " - "for %d seconds; reconnecting", - is->is_timeout); + "for %d%s seconds; reconnecting", + is->is_timeout/1000, tmpstr); reconnect_needed = true; } goto out; } if (is->is_login_phase) { - if (is->is_login_timeout > 0 && is->is_timeout > is->is_login_timeout) { - ISCSI_SESSION_WARN(is, "login timed out after %d seconds; " - "reconnecting", is->is_timeout); + if (is->is_login_timeout > 0 && is->is_timeout >= is->is_login_timeout) { + if (fast_timer && ((is->is_timeout % 1000) != 0)) + snprintf(tmpstr, sizeof(tmpstr), ".%03d", + is->is_timeout % 1000); + ISCSI_SESSION_WARN(is, "login timed out after %d%s seconds; " + "reconnecting", is->is_timeout/1000, tmpstr); reconnect_needed = true; } goto out; @@ -631,8 +642,11 @@ } if (is->is_timeout >= is->is_ping_timeout) { - ISCSI_SESSION_WARN(is, "no ping reply (NOP-In) after %d seconds; " - "reconnecting", is->is_ping_timeout); + if (fast_timer && ((is->is_timeout % 1000) != 0)) + snprintf(tmpstr, sizeof(tmpstr), ".%03d", + is->is_timeout % 1000); + ISCSI_SESSION_WARN(is, "no ping reply (NOP-In) after %d%s seconds; " + "reconnecting", is->is_timeout/1000, tmpstr); reconnect_needed = true; goto out; } @@ -647,7 +661,7 @@ * (It's 2 - one for one second, and one for incrementing is_timeout * earlier in this routine.) */ - if (is->is_timeout < 2) + if (is->is_timeout < (fast_timer ? 200 : 2000)) return; request = icl_pdu_new(is->is_conn, M_NOWAIT); @@ -1963,6 +1977,7 @@ const struct iscsi_session *is2; int error; sbintime_t sbt, pr; + bool fast_timer; iscsi_sanitize_session_conf(&isa->isa_conf); if (iscsi_valid_session_conf(&isa->isa_conf) == false) @@ -2046,7 +2061,9 @@ if (is->is_login_timeout < 0) is->is_login_timeout = login_timeout; - sbt = mstosbt(995); + fast_timer = ((is->is_ping_timeout <= 2000) || + (is->is_ping_timeout <= 2000)); + sbt = mstosbt(fast_timer ? 95 : 995); pr = mstosbt(10); callout_reset_sbt(&is->is_callout, sbt, pr, iscsi_callout, is, 0); TAILQ_INSERT_TAIL(&sc->sc_sessions, is, is_next); diff --git a/sys/dev/iscsi/iscsi_ioctl.h b/sys/dev/iscsi/iscsi_ioctl.h --- a/sys/dev/iscsi/iscsi_ioctl.h +++ b/sys/dev/iscsi/iscsi_ioctl.h @@ -142,6 +142,8 @@ int idh_max_send_data_segment_length; int idh_max_burst_length; int idh_first_burst_length; + int idh_ping_timeout; + int idh_login_timeout; }; struct iscsi_daemon_fail { diff --git a/usr.bin/iscsictl/iscsi.conf.5 b/usr.bin/iscsictl/iscsi.conf.5 --- a/usr.bin/iscsictl/iscsi.conf.5 +++ b/usr.bin/iscsictl/iscsi.conf.5 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd February 25, 2022 +.Dd October 10, 2023 .Dt ISCSI.CONF 5 .Os .Sh NAME @@ -170,7 +170,7 @@ seconds) is taken by the driver. If present, the PingTimeout can be set to any positive value starting with -.Qq Ar 1 . +.Qq Ar 0.1 . .It Cm LoginTimeout Specify the time in seconds to wait for a login PDU to be sent or received after trying to establish a new session. @@ -181,7 +181,7 @@ seconds is used, as configured by .Qq Ar kern.iscsi.login_timeout . The LoginTimeout can be set to any positive value starting with -.Qq Ar 1 . +.Qq Ar 0.1 . .El .Sh FILES .Bl -tag -width indent diff --git a/usr.bin/iscsictl/iscsictl.c b/usr.bin/iscsictl/iscsictl.c --- a/usr.bin/iscsictl/iscsictl.c +++ b/usr.bin/iscsictl/iscsictl.c @@ -547,13 +547,15 @@ xo_emit("{L:/%-26s}{V:pcp/0x%02x}\n", "Target PCP:", conf->isc_pcp); if (conf->isc_ping_timeout != -1) - xo_emit("{L:/%-26s}{V:PingTimeout/%d}\n", - "Target PingTimeout:", - conf->isc_ping_timeout); + xo_emit("{L:/%-26s}{V:PingTimeout/%d.%d}\n", + "Target Ping Timeout:", + conf->isc_ping_timeout/1000, + conf->isc_ping_timeout%1000); if (conf->isc_login_timeout != -1) - xo_emit("{L:/%-26s}{V:LoginTimeout/%d}\n", - "Target LoginTimeout:", - conf->isc_login_timeout); + xo_emit("{L:/%-26s}{V:LoginTimeout/%d.%d}\n", + "Target Login Timeout:", + conf->isc_login_timeout/1000, + conf->isc_login_timeout%1000); xo_close_container("target"); xo_open_container("auth"); diff --git a/usr.bin/iscsictl/parse.y b/usr.bin/iscsictl/parse.y --- a/usr.bin/iscsictl/parse.y +++ b/usr.bin/iscsictl/parse.y @@ -66,9 +66,11 @@ %union { char *str; + double floating; } %token STR +%token FLOAT %% @@ -381,7 +383,16 @@ free($3); return(1); } - target->t_pingtimeout = tmp; + target->t_pingtimeout = tmp * 1000; + } + | PINGTIMEOUT EQUALS FLOAT + { + float tmp; + + if (target->t_pingtimeout != -1) + xo_errx(1, "duplicated PingTimeout at line %d", lineno); + tmp = $3; + target->t_pingtimeout = 100*(int)(tmp * 10 + 0.5f); } ; @@ -397,7 +408,17 @@ free($3); return(1); } - target->t_logintimeout = tmp; + target->t_logintimeout = tmp * 1000; + } + | LOGINTIMEOUT EQUALS FLOAT + { + float tmp; + + if (target->t_logintimeout != -1) + xo_errx(1, "duplicated LoginTimeout at line %d", lineno); + + tmp = $3; + target->t_logintimeout = 100*(int)(tmp * 10 + 0.5f); } ; diff --git a/usr.bin/iscsictl/token.l b/usr.bin/iscsictl/token.l --- a/usr.bin/iscsictl/token.l +++ b/usr.bin/iscsictl/token.l @@ -111,6 +111,7 @@ cs7 { return CS7; } \"[^"]+\" { yylval.str = strndup(yytext + 1, strlen(yytext) - 2); return STR; } +[0-9]*\.[0-9]+ {yylval.floating = atof(yytext); return FLOAT; } [a-zA-Z0-9\.\-_/\:\[\]]+ { yylval.str = strdup(yytext); return STR; } \{ { return OPENING_BRACKET; } \} { return CLOSING_BRACKET; } diff --git a/usr.sbin/iscsid/iscsid.c b/usr.sbin/iscsid/iscsid.c --- a/usr.sbin/iscsid/iscsid.c +++ b/usr.sbin/iscsid/iscsid.c @@ -358,7 +358,7 @@ int keepinit = 0; if (conn->conn_conf.isc_login_timeout > 0) { keepinit = conn->conn_conf.isc_login_timeout; - log_debugx("session specific LoginTimeout at %d sec", + log_debugx("session specific LoginTimeout at %d ms", keepinit); } if (conn->conn_conf.isc_login_timeout == -1) { @@ -367,11 +367,13 @@ if (sysctlbyname("kern.iscsi.login_timeout", &value, &size, NULL, 0) == 0) { keepinit = value; - log_debugx("global login_timeout at %d sec", + log_debugx("global login_timeout at %d ms", keepinit); } } if (keepinit > 0) { + /* setsockopt only supports full seconds */ + keepinit = (keepinit + 999)/1000; if (setsockopt(conn->conn.conn_socket, IPPROTO_TCP, TCP_KEEPINIT, &keepinit, sizeof(keepinit)) == -1) @@ -477,6 +479,8 @@ conn->conn.conn_max_send_data_segment_length; idh.idh_max_burst_length = conn->conn.conn_max_burst_length; idh.idh_first_burst_length = conn->conn.conn_first_burst_length; + idh.idh_ping_timeout = conn->conn_conf.isc_ping_timeout; + idh.idh_login_timeout = conn->conn_conf.isc_login_timeout; error = ioctl(conn->conn_iscsi_fd, ISCSIDHANDOFF, &idh); if (error != 0)