Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136587988
D32540.id102384.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
17 KB
Referenced Files
None
Subscribers
None
D32540.id102384.diff
View Options
Index: lib/libiscsiutil/libiscsiutil.h
===================================================================
--- lib/libiscsiutil/libiscsiutil.h
+++ lib/libiscsiutil/libiscsiutil.h
@@ -54,6 +54,8 @@
int conn_max_send_data_segment_length;
int conn_max_burst_length;
int conn_first_burst_length;
+ int conn_ping_timeout;
+ int conn_login_timeout;
};
struct pdu {
Index: share/man/man4/iscsi.4
===================================================================
--- share/man/man4/iscsi.4
+++ share/man/man4/iscsi.4
@@ -22,7 +22,7 @@
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
-.Dd May 28, 2017
+.Dd February 4, 2022
.Dt ISCSI 4
.Os
.Sh NAME
@@ -74,6 +74,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
@@ -81,13 +82,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.
Index: sys/dev/iscsi/iscsi.h
===================================================================
--- sys/dev/iscsi/iscsi.h
+++ sys/dev/iscsi/iscsi.h
@@ -75,6 +75,8 @@
struct callout is_callout;
unsigned int is_timeout;
+ int is_ping_timeout;
+ int is_login_timeout;
/*
* XXX: This could be rewritten using a single variable,
Index: sys/dev/iscsi/iscsi.c
===================================================================
--- sys/dev/iscsi/iscsi.c
+++ sys/dev/iscsi/iscsi.c
@@ -45,6 +45,7 @@
#include <sys/mutex.h>
#include <sys/module.h>
#include <sys/socket.h>
+#include <sys/sockopt.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/sx.h>
@@ -80,21 +81,27 @@
* Think about how to do this properly.
*/
static struct iscsi_softc *sc;
+static int
+sysctl_handle_deciint(SYSCTL_HANDLER_ARGS);
SYSCTL_NODE(_kern, OID_AUTO, iscsi, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
"iSCSI initiator");
static int debug = 1;
SYSCTL_INT(_kern_iscsi, OID_AUTO, debug, CTLFLAG_RWTUN,
&debug, 0, "Enable debug messages");
-static int ping_timeout = 5;
-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;
-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;
-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");
+
+static int ping_timeout = 50;
+SYSCTL_PROC(_kern_iscsi, OID_AUTO, ping_timeout,
+ CTLFLAG_RWTUN | CTLTYPE_STRING, &ping_timeout, 0, sysctl_handle_deciint,
+ "A", "Timeout for ping (NOP-Out) requests, in seconds");
+static int iscsid_timeout = 600;
+SYSCTL_PROC(_kern_iscsi, OID_AUTO, iscsid_timeout,
+ CTLFLAG_RWTUN | CTLTYPE_STRING, &iscsid_timeout, 0, sysctl_handle_deciint,
+ "A", "Time to wait for iscsid(8) to handle reconnection, in seconds");
+static int login_timeout = 600;
+SYSCTL_PROC(_kern_iscsi, OID_AUTO, login_timeout,
+ CTLFLAG_RWTUN | CTLTYPE_STRING, &login_timeout, 0, sysctl_handle_deciint,
+ "A", "Time to wait for iscsid(8) to finish Login Phase, in seconds");
static int maxtags = 255;
SYSCTL_INT(_kern_iscsi, OID_AUTO, maxtags, CTLFLAG_RWTUN, &maxtags,
0, "Max number of IO requests queued");
@@ -178,6 +185,86 @@
uint32_t *initiator_task_tagp);
static void iscsi_outstanding_remove(struct iscsi_session *is,
struct iscsi_outstanding *io);
+static int
+sysctl_handle_deciint(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ char oldstr[10], newstr[10];
+ char *s, c;
+ int newval = 0;
+ bool havesign = false;
+ bool havenumber = false;
+ bool havedot = false;
+ bool havedecimal = false;
+ bool isnegative = false;
+
+ if ((*(int *)arg1 % 10) == 0)
+ snprintf(oldstr, sizeof(oldstr), "%d", *(int *)arg1/10);
+ else
+ snprintf(oldstr, sizeof(oldstr), "%d.%d", *(int *)arg1/10, *(int *)arg1%10);
+ strncpy(newstr, oldstr, sizeof(newstr));
+ error = sysctl_handle_string(oidp, newstr, sizeof(newstr), req);
+ s = &newstr[0];
+ while ((c=*s++)) {
+ if (c == ' ' || c == '\t') {
+ if (!havenumber) {
+ continue;
+ } else {
+ break;
+ }
+ }
+ if (c == '+') {
+ if (!havesign) {
+ havesign = true;
+ } else {
+ error = EINVAL;
+ break;
+ }
+ }
+ if (c == '-') {
+ if (!havesign) {
+ havesign = true;
+ isnegative = true;
+ } else {
+ error = EINVAL;
+ break;
+ }
+ }
+ if (c == '.') {
+ if (!havedot) {
+ havedot = true;
+ } else {
+ error = EINVAL;
+ break;
+ }
+ }
+ if (c >= '0' && c <= '9') {
+ havenumber = true;
+ if (havedot && havedecimal) {
+ if (c >= '5') /* Round up */
+ newval += 1;
+ break;
+ }
+ if (havedot && !havedecimal)
+ havedecimal = true;
+ newval = newval * 10 + (c - '0');
+ }
+ }
+ if (!havenumber) {
+ error = EINVAL;
+ } else {
+ if (isnegative)
+ newval = -newval;
+ if (!havedot)
+ newval *= 10;
+ *(int *)arg1 = newval;
+ }
+
+ if (newval < 0)
+ error = EINVAL;
+
+ return(error);
+}
static bool
iscsi_pdu_prepare(struct icl_pdu *request)
@@ -380,6 +467,22 @@
static void
iscsi_maintenance_thread_reconnect(struct iscsi_session *is)
{
+ /*
+ * As we will be reconnecting shortly,
+ * discard outstanding data immediately on
+ * close(), also notify peer via RST if
+ * any packets come in.
+ */
+ struct sockopt sopt;
+ struct linger sl;
+ sopt.sopt_dir = SOPT_SET;
+ sopt.sopt_level = SOL_SOCKET;
+ sopt.sopt_name = SO_LINGER;
+ sopt.sopt_val = &sl;
+ sopt.sopt_valsize = sizeof(sl);
+ sl.l_onoff = 1; /* non-zero value enables linger option in kernel */
+ sl.l_linger = 0; /* timeout interval in seconds */
+ sosetopt(is->is_conn->ic_socket, &sopt);
icl_conn_close(is->is_conn);
@@ -546,6 +649,8 @@
struct iscsi_bhs_nop_out *bhsno;
struct iscsi_session *is;
bool reconnect_needed = false;
+ bool fast_timer = false;
+ char tmpstr[4];
is = context;
@@ -555,18 +660,25 @@
return;
}
- callout_schedule(&is->is_callout, 1 * hz);
+ fast_timer = ((is->is_ping_timeout <= 20) ||
+ (is->is_login_timeout <= 20));
+
+ callout_schedule(&is->is_callout, (fast_timer ? hz / 10 : 1 * hz));
if (is->is_conf.isc_enable == 0)
goto out;
- is->is_timeout++;
+ is->is_timeout += (fast_timer ? 1 : 10);
+ tmpstr[0] = '\0';
if (is->is_waiting_for_iscsid) {
if (iscsid_timeout > 0 && is->is_timeout > iscsid_timeout) {
+ if (fast_timer)
+ snprintf(tmpstr, sizof(tmpstr), ".%d",
+ is->is_timeout % 10);
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/10, tmpstr);
reconnect_needed = true;
}
goto out;
@@ -574,14 +686,17 @@
if (is->is_login_phase) {
if (login_timeout > 0 && is->is_timeout > login_timeout) {
- ISCSI_SESSION_WARN(is, "login timed out after %d seconds; "
- "reconnecting", is->is_timeout);
+ if (fast_timer)
+ snprintf(tmpstr, sizeof(tmpstr), ".%d",
+ is->is_timeout % 10);
+ ISCSI_SESSION_WARN(is, "login timed out after %d%s seconds; "
+ "reconnecting", is->is_timeout/10, tmpstr);
reconnect_needed = true;
}
goto out;
}
- if (ping_timeout <= 0) {
+ if (is->is_ping_timeout <= 0) {
/*
* Pings are disabled. Don't send NOP-Out in this case.
* Reset the timeout, to avoid triggering reconnection,
@@ -591,9 +706,12 @@
goto out;
}
- if (is->is_timeout >= ping_timeout) {
- ISCSI_SESSION_WARN(is, "no ping reply (NOP-In) after %d seconds; "
- "reconnecting", ping_timeout);
+ if (is->is_timeout >= is->is_ping_timeout) {
+ if (fast_timer)
+ snprintf(tmpstr, sizeof(tmpstr), ".%d",
+ is->is_ping_timeout % 10);
+ ISCSI_SESSION_WARN(is, "no ping reply (NOP-In) after %d%s seconds; "
+ "reconnecting", is->is_ping_timeout/10, tmpstr);
reconnect_needed = true;
goto out;
}
@@ -1506,6 +1624,12 @@
is->is_waiting_for_iscsid = false;
is->is_login_phase = false;
is->is_timeout = 0;
+ is->is_ping_timeout = handoff->idh_ping_timeout;
+ if (is->is_ping_timeout < 0)
+ is->is_ping_timeout = ping_timeout;
+ is->is_login_timeout = handoff->idh_login_timeout;
+ if (is->is_login_timeout < 0)
+ is->is_login_timeout = login_timeout;
is->is_connected = true;
is->is_reason[0] = '\0';
@@ -1835,6 +1959,7 @@
struct iscsi_session *is;
const struct iscsi_session *is2;
int error;
+ bool fast_timer;
iscsi_sanitize_session_conf(&isa->isa_conf);
if (iscsi_valid_session_conf(&isa->isa_conf) == false)
@@ -1911,8 +2036,16 @@
sx_xunlock(&sc->sc_lock);
return (error);
}
+ is->is_ping_timeout = is->is_conf.isc_ping_timeout;
+ if (is->is_ping_timeout < 0)
+ is->is_ping_timeout = ping_timeout;
+ is->is_login_timeout = is->is_conf.isc_login_timeout;
+ if (is->is_login_timeout < 0)
+ is->is_login_timeout = login_timeout;
- callout_reset(&is->is_callout, 1 * hz, iscsi_callout, is);
+ fast_timer = ((is->is_ping_timeout <= 20) ||
+ (is->is_ping_timeout <= 20));
+ callout_reset(&is->is_callout, (fast_timer ? hz / 10 : 1 * hz), iscsi_callout, is);
TAILQ_INSERT_TAIL(&sc->sc_sessions, is, is_next);
ISCSI_SESSION_LOCK(is);
Index: sys/dev/iscsi/iscsi_ioctl.h
===================================================================
--- sys/dev/iscsi/iscsi_ioctl.h
+++ sys/dev/iscsi/iscsi_ioctl.h
@@ -71,7 +71,8 @@
int isc_enable;
int isc_dscp;
int isc_pcp;
- int isc_spare[2];
+ int isc_ping_timeout;
+ int isc_login_timeout;
};
/*
@@ -138,6 +139,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 {
Index: usr.bin/iscsictl/iscsi.conf.5
===================================================================
--- usr.bin/iscsictl/iscsi.conf.5
+++ usr.bin/iscsictl/iscsi.conf.5
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 6, 2016
+.Dd February 4, 2022
.Dt ISCSI.CONF 5
.Os
.Sh NAME
@@ -160,6 +160,24 @@
to
.Qq Ar 7 .
When omitted, the default for the outgoing interface is used.
+.It Cm PingTimeout
+Specify the time in seconds to wait between pings (SCSI NOP), and
+for a ping response before declaring the session as dead and
+attempting a re-establishment.
+If this entry is not present in the conf file, a default value of
+5 seconds is taken by the driver.
+The PingTimeout can be set to any positive value starting with
+.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.
+When no login PDU is received within this time, the login on a
+particular connection fails and a new reconnection attempt is made.
+If this entry is not present in the conf file, a default value of
+.Qq Ar 60
+secs is used.
+The LoginTimeout can be set to any positive value starting with
+.Qq Ar 0.1 .
.El
.Sh FILES
.Bl -tag -width indent
Index: usr.bin/iscsictl/iscsictl.h
===================================================================
--- usr.bin/iscsictl/iscsictl.h
+++ usr.bin/iscsictl/iscsictl.h
@@ -79,6 +79,8 @@
int t_protocol;
int t_dscp;
int t_pcp;
+ int t_pingtimeout;
+ int t_logintimeout;
char *t_offload;
char *t_user;
char *t_secret;
Index: usr.bin/iscsictl/iscsictl.c
===================================================================
--- usr.bin/iscsictl/iscsictl.c
+++ usr.bin/iscsictl/iscsictl.c
@@ -88,6 +88,8 @@
targ->t_conf = conf;
targ->t_dscp = -1;
targ->t_pcp = -1;
+ targ->t_pingtimeout = -1;
+ targ->t_logintimeout = -1;
TAILQ_INSERT_TAIL(&conf->conf_targets, targ, t_next);
return (targ);
@@ -361,6 +363,8 @@
conf->isc_data_digest = ISCSI_DIGEST_NONE;
conf->isc_dscp = targ->t_dscp;
conf->isc_pcp = targ->t_pcp;
+ conf->isc_ping_timeout = targ->t_pingtimeout;
+ conf->isc_login_timeout = targ->t_logintimeout;
}
static int
@@ -544,6 +548,16 @@
if (conf->isc_pcp != -1)
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.%d}\n",
+ "Target Ping Timeout:",
+ conf->isc_ping_timeout/10,
+ conf->isc_ping_timeout%10);
+ if (conf->isc_login_timeout != -1)
+ xo_emit("{L:/%-26s}{V:LoginTimeout/%d.%d}\n",
+ "Target Login Timeout:",
+ conf->isc_login_timeout/10,
+ conf->isc_login_timeout%10);
xo_close_container("target");
xo_open_container("auth");
Index: usr.bin/iscsictl/parse.y
===================================================================
--- usr.bin/iscsictl/parse.y
+++ usr.bin/iscsictl/parse.y
@@ -61,16 +61,18 @@
%token AUTH_METHOD ENABLE HEADER_DIGEST DATA_DIGEST TARGET_NAME TARGET_ADDRESS
%token INITIATOR_NAME INITIATOR_ADDRESS INITIATOR_ALIAS USER SECRET
%token MUTUAL_USER MUTUAL_SECRET SEMICOLON SESSION_TYPE PROTOCOL OFFLOAD
-%token IGNORED EQUALS OPENING_BRACKET CLOSING_BRACKET DSCP
+%token IGNORED EQUALS OPENING_BRACKET CLOSING_BRACKET DSCP PINGTIMEOUT LOGINTIMEOUT
%token AF11 AF12 AF13 AF21 AF22 AF23 AF31 AF32 AF33 AF41 AF42 AF43
%token BE EF CS0 CS1 CS2 CS3 CS4 CS5 CS6 CS7
%union
{
char *str;
+ double floating;
}
%token <str> STR
+%token <floating> FLOAT
%%
@@ -133,6 +135,10 @@
dscp
|
pcp
+ |
+ ping_timeout
+ |
+ login_timeout
;
target_name: TARGET_NAME EQUALS STR
@@ -367,6 +373,57 @@
}
;
+ping_timeout: PINGTIMEOUT EQUALS STR
+ {
+ uint64_t tmp;
+
+ if (target->t_pingtimeout != -1)
+ xo_errx(1, "duplicated PingTimeout at line %d", lineno);
+
+ if (expand_number($3, &tmp) != 0) {
+ yyerror("invalid numeric value");
+ free($3);
+ return(1);
+ }
+ target->t_pingtimeout = tmp * 10;
+ }
+ | PINGTIMEOUT EQUALS FLOAT
+ {
+ float tmp;
+
+ if (target->t_pingtimeout != -1)
+ xo_errx(1, "duplicated PingTimeout at line %d", lineno);
+ tmp = $3;
+ target->t_pingtimeout = (int)(tmp * 10 + 0.5f);
+ }
+ ;
+
+login_timeout: LOGINTIMEOUT EQUALS STR
+ {
+ uint64_t tmp;
+
+ if (target->t_logintimeout != -1)
+ xo_errx(1, "duplicated LoginTimeout at line %d", lineno);
+
+ if (expand_number($3, &tmp) != 0) {
+ yyerror("invalid numeric value");
+ free($3);
+ return(1);
+ }
+ target->t_logintimeout = tmp * 10;
+ }
+ | LOGINTIMEOUT EQUALS FLOAT
+ {
+ float tmp;
+
+ if (target->t_logintimeout != -1)
+ xo_errx(1, "duplicated LoginTimeout at line %d", lineno);
+
+ tmp = $3;
+ target->t_logintimeout = (int)(tmp * 10 + 0.5f);
+ }
+ ;
+
%%
void
Index: usr.bin/iscsictl/token.l
===================================================================
--- usr.bin/iscsictl/token.l
+++ usr.bin/iscsictl/token.l
@@ -69,6 +69,8 @@
port { return IGNORED; }
dscp { return DSCP; }
pcp { return PCP; }
+PingTimeout { return PINGTIMEOUT; }
+LoginTimeout { return LOGINTIMEOUT; }
MaxConnections { return IGNORED; }
TargetAlias { return IGNORED; }
TargetPortalGroupTag { return IGNORED; }
@@ -111,6 +113,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; }
Index: usr.sbin/iscsid/iscsid.c
===================================================================
--- usr.sbin/iscsid/iscsid.c
+++ usr.sbin/iscsid/iscsid.c
@@ -38,9 +38,11 @@
#include <sys/param.h>
#include <sys/linker.h>
#include <sys/socket.h>
+#include <sys/sysctl.h>
#include <sys/capsicum.h>
#include <sys/wait.h>
#include <netinet/in.h>
+#include <netinet/tcp.h>
#include <assert.h>
#include <capsicum_helpers.h>
#include <errno.h>
@@ -383,6 +385,32 @@
from_addr);
}
}
+ /*
+ * Reduce TCP SYN_SENT timeout while
+ * no connectivity exists, to allow
+ * rapid reuse of the available slots.
+ */
+ int keepinit = 0;
+ if (conn->conn_conf.isc_login_timeout > 0) {
+ keepinit = (conn->conn_conf.isc_login_timeout + 9) / 10;
+ log_debugx("session specific login_timeout at %d sec",
+ keepinit);
+ }
+ if (conn->conn_conf.isc_login_timeout == -1) {
+ char value[8];
+ size_t size = sizeof(value);
+ sysctlbyname("kern.iscsi.login_timeout", &value, &size,
+ NULL, 0);
+ keepinit = strtol(value, NULL, 10);
+ log_debugx("global login_timeout at %d sec", keepinit);
+ }
+ if (keepinit > 0) {
+ if (setsockopt(conn->conn.conn_socket,
+ IPPROTO_TCP, TCP_KEEPINIT,
+ &keepinit, sizeof(keepinit)) == -1)
+ log_warnx("setsockopt(TCP_KEEPINIT) "
+ "failed for %s", to_addr);
+ }
if (from_ai != NULL) {
error = bind(conn->conn.conn_socket, from_ai->ai_addr,
from_ai->ai_addrlen);
@@ -432,6 +460,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)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 19, 11:40 AM (8 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25522546
Default Alt Text
D32540.id102384.diff (17 KB)
Attached To
Mode
D32540: iSCSI: Fast and per-session timeouts
Attached
Detach File
Event Timeline
Log In to Comment