Page MenuHomeFreeBSD

D32540.id102384.diff
No OneTemporary

D32540.id102384.diff

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

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)

Event Timeline