svn commit: r278232 - in head: sys/dev/iscsi usr.bin/iscsictl usr.sbin/iscsid

Edward Tomasz Napierala trasz at FreeBSD.org
Thu Feb 5 06:38:04 UTC 2015


Author: trasz
Date: Thu Feb  5 06:37:59 2015
New Revision: 278232
URL: https://svnweb.freebsd.org/changeset/base/278232

Log:
  Make it possible to set (via iscsi.conf(5)) and query (via iscsictl -v)
  initiator iSCSI offload.  Pass maximum data segment size supported by
  chosen offload module to iscsid(8), and make iscsid(8) not try to negotiate
  anything larger than that.
  
  MFC after:	1 month
  Sponsored by:	The FreeBSD Foundation

Modified:
  head/sys/dev/iscsi/icl.h
  head/sys/dev/iscsi/icl_soft.c
  head/sys/dev/iscsi/iscsi.c
  head/sys/dev/iscsi/iscsi_ioctl.h
  head/usr.bin/iscsictl/iscsi.conf.5
  head/usr.bin/iscsictl/iscsictl.c
  head/usr.bin/iscsictl/iscsictl.h
  head/usr.bin/iscsictl/parse.y
  head/usr.bin/iscsictl/token.l
  head/usr.sbin/iscsid/iscsid.c
  head/usr.sbin/iscsid/iscsid.h
  head/usr.sbin/iscsid/login.c

Modified: head/sys/dev/iscsi/icl.h
==============================================================================
--- head/sys/dev/iscsi/icl.h	Thu Feb  5 03:56:49 2015	(r278231)
+++ head/sys/dev/iscsi/icl.h	Thu Feb  5 06:37:59 2015	(r278232)
@@ -113,6 +113,7 @@ struct icl_conn {
 	bool			ic_disconnecting;
 	bool			ic_iser;
 	const char		*ic_name;
+	const char		*ic_offload;
 
 	void			(*ic_receive)(struct icl_pdu *);
 	void			(*ic_error)(struct icl_conn *);

Modified: head/sys/dev/iscsi/icl_soft.c
==============================================================================
--- head/sys/dev/iscsi/icl_soft.c	Thu Feb  5 03:56:49 2015	(r278231)
+++ head/sys/dev/iscsi/icl_soft.c	Thu Feb  5 06:37:59 2015	(r278232)
@@ -1185,6 +1185,7 @@ icl_soft_new_conn(const char *name, stru
 #endif
 	ic->ic_max_data_segment_length = ICL_MAX_DATA_SEGMENT_LENGTH;
 	ic->ic_name = name;
+	ic->ic_offload = "none";
 
 	return (ic);
 }

Modified: head/sys/dev/iscsi/iscsi.c
==============================================================================
--- head/sys/dev/iscsi/iscsi.c	Thu Feb  5 03:56:49 2015	(r278231)
+++ head/sys/dev/iscsi/iscsi.c	Thu Feb  5 06:37:59 2015	(r278232)
@@ -1306,6 +1306,16 @@ iscsi_ioctl_daemon_wait(struct iscsi_sof
 		request->idr_tsih = 0;	/* New or reinstated session. */
 		memcpy(&request->idr_conf, &is->is_conf,
 		    sizeof(request->idr_conf));
+		
+		error = icl_limits(is->is_conf.isc_offload,
+		    &request->idr_limits.isl_max_data_segment_length);
+		if (error != 0) {
+			ISCSI_SESSION_WARN(is, "icl_limits for offload \"%s\" "
+			    "failed with error %d", is->is_conf.isc_offload,
+			    error);
+			sx_sunlock(&sc->sc_lock);
+			return (error);
+		}
 
 		sx_sunlock(&sc->sc_lock);
 		return (0);
@@ -1731,7 +1741,13 @@ iscsi_ioctl_session_add(struct iscsi_sof
 		return (EBUSY);
 	}
 
-	is->is_conn = icl_new_conn(NULL, "iscsi", &is->is_lock);
+	is->is_conn = icl_new_conn(is->is_conf.isc_offload,
+	    "iscsi", &is->is_lock);
+	if (is->is_conn == NULL) {
+		sx_xunlock(&sc->sc_lock);
+		free(is, M_ISCSI);
+		return (EINVAL);
+	}
 	is->is_conn->ic_receive = iscsi_receive_callback;
 	is->is_conn->ic_error = iscsi_error_callback;
 	is->is_conn->ic_prv0 = is;
@@ -1836,6 +1852,7 @@ iscsi_ioctl_session_list(struct iscsi_so
 		iss.iss_id = is->is_id;
 		strlcpy(iss.iss_target_alias, is->is_target_alias, sizeof(iss.iss_target_alias));
 		strlcpy(iss.iss_reason, is->is_reason, sizeof(iss.iss_reason));
+		strlcpy(iss.iss_offload, is->is_conn->ic_offload, sizeof(iss.iss_offload));
 
 		if (is->is_conn->ic_header_crc32c)
 			iss.iss_header_digest = ISCSI_DIGEST_CRC32C;

Modified: head/sys/dev/iscsi/iscsi_ioctl.h
==============================================================================
--- head/sys/dev/iscsi/iscsi_ioctl.h	Thu Feb  5 03:56:49 2015	(r278231)
+++ head/sys/dev/iscsi/iscsi_ioctl.h	Thu Feb  5 06:37:59 2015	(r278232)
@@ -43,6 +43,7 @@
 #define	ISCSI_ADDR_LEN		47	/* INET6_ADDRSTRLEN + '\0' */
 #define	ISCSI_ALIAS_LEN		256	/* XXX: Where did it come from? */
 #define	ISCSI_SECRET_LEN	17	/* 16 + '\0' */
+#define	ISCSI_OFFLOAD_LEN	8
 #define	ISCSI_REASON_LEN	64
 
 #define	ISCSI_DIGEST_NONE	0
@@ -65,7 +66,16 @@ struct iscsi_session_conf {
 	int		isc_header_digest;
 	int		isc_data_digest;
 	int		isc_iser;
-	int		isc_spare[4];
+	char		isc_offload[ISCSI_OFFLOAD_LEN];
+	int		isc_spare[2];
+};
+
+/*
+ * Additional constraints imposed by chosen ICL offload module;
+ * iscsid(8) must obey those when negotiating operational parameters.
+ */
+struct iscsi_session_limits {
+	size_t		isl_max_data_segment_length;
 };
 
 /*
@@ -81,20 +91,21 @@ struct iscsi_session_state {
 	int		iss_immediate_data;
 	int		iss_connected;
 	char		iss_reason[ISCSI_REASON_LEN];
-	int		iss_spare[4];
+	char		iss_offload[ISCSI_OFFLOAD_LEN];
+	int		iss_spare[2];
 };
 
 /*
- * For use with iscsid(8).
+ * The following ioctls are used by iscsid(8).
  */
-
 struct iscsi_daemon_request {
 	unsigned int			idr_session_id;
 	struct iscsi_session_conf	idr_conf;
 	uint8_t				idr_isid[6];
 	uint16_t			idr_tsih;
 	uint16_t			idr_spare_cid;
-	int				idr_spare[4];
+	struct iscsi_session_limits	idr_limits;
+	int				idr_spare[2];
 };
 
 struct iscsi_daemon_handoff {
@@ -182,9 +193,8 @@ struct iscsi_daemon_receive {
 #endif /* ICL_KERNEL_PROXY */
 
 /*
- * For use with iscsictl(8).
+ * The following ioctls are used by iscsictl(8).
  */
-
 struct iscsi_session_add {
 	struct iscsi_session_conf	isa_conf;
 	int				isa_spare[4];

Modified: head/usr.bin/iscsictl/iscsi.conf.5
==============================================================================
--- head/usr.bin/iscsictl/iscsi.conf.5	Thu Feb  5 03:56:49 2015	(r278231)
+++ head/usr.bin/iscsictl/iscsi.conf.5	Thu Feb  5 06:37:59 2015	(r278232)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd December 17, 2013
+.Dd February 4, 2015
 .Dt ISCSI.CONF 5
 .Os
 .Sh NAME
@@ -110,6 +110,8 @@ flag of
 The following are not specified in the
 .Sy RFC 3720
 .Bl -tag -width sockbufsize
+.It Cm offload
+Name of selected iSCSI hardware offload driver.
 .It Cm port
 The iSCSI port used by the iSCSI protocol, defaults to 3260.
 .It Cm tags

Modified: head/usr.bin/iscsictl/iscsictl.c
==============================================================================
--- head/usr.bin/iscsictl/iscsictl.c	Thu Feb  5 03:56:49 2015	(r278231)
+++ head/usr.bin/iscsictl/iscsictl.c	Thu Feb  5 06:37:59 2015	(r278232)
@@ -327,6 +327,9 @@ conf_from_target(struct iscsi_session_co
 		conf->isc_discovery = 1;
 	if (targ->t_protocol == PROTOCOL_ISER)
 		conf->isc_iser = 1;
+	if (targ->t_offload != NULL)
+		strlcpy(conf->isc_offload, targ->t_offload,
+		    sizeof(conf->isc_offload));
 	if (targ->t_header_digest == DIGEST_CRC32C)
 		conf->isc_header_digest = ISCSI_DIGEST_CRC32C;
 	else
@@ -517,6 +520,7 @@ kernel_list(int iscsi_fd, const struct t
 			    state->iss_immediate_data ? "Yes" : "No");
 			printf("iSER (RDMA):      %s\n",
 			    conf->isc_iser ? "Yes" : "No");
+			printf("Offload driver:   %s\n", state->iss_offload);
 			printf("Device nodes:     ");
 			print_periphs(state->iss_id);
 			printf("\n\n");

Modified: head/usr.bin/iscsictl/iscsictl.h
==============================================================================
--- head/usr.bin/iscsictl/iscsictl.h	Thu Feb  5 03:56:49 2015	(r278231)
+++ head/usr.bin/iscsictl/iscsictl.h	Thu Feb  5 06:37:59 2015	(r278232)
@@ -72,6 +72,7 @@ struct target {
 	int			t_auth_method;
 	int			t_session_type;
 	int			t_protocol;
+	char			*t_offload;
 	char			*t_user;
 	char			*t_secret;
 	char			*t_mutual_user;

Modified: head/usr.bin/iscsictl/parse.y
==============================================================================
--- head/usr.bin/iscsictl/parse.y	Thu Feb  5 03:56:49 2015	(r278231)
+++ head/usr.bin/iscsictl/parse.y	Thu Feb  5 06:37:59 2015	(r278232)
@@ -57,8 +57,8 @@ extern void	yyrestart(FILE *);
 
 %token AUTH_METHOD 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 IGNORED
-%token EQUALS OPENING_BRACKET CLOSING_BRACKET
+%token MUTUAL_USER MUTUAL_SECRET SEMICOLON SESSION_TYPE PROTOCOL OFFLOAD
+%token IGNORED EQUALS OPENING_BRACKET CLOSING_BRACKET
 
 %union
 {
@@ -117,6 +117,8 @@ target_entry:
 	|
 	session_type
 	|
+	offload
+	|
 	protocol
 	|
 	ignored
@@ -250,6 +252,14 @@ session_type:	SESSION_TYPE EQUALS STR
 	}
 	;
 
+offload:	OFFLOAD EQUALS STR
+	{
+		if (target->t_offload != NULL)
+			errx(1, "duplicated offload at line %d", lineno);
+		target->t_offload = $3;
+	}
+	;
+
 protocol:	PROTOCOL EQUALS STR
 	{
 		if (target->t_protocol != PROTOCOL_UNSPECIFIED)

Modified: head/usr.bin/iscsictl/token.l
==============================================================================
--- head/usr.bin/iscsictl/token.l	Thu Feb  5 03:56:49 2015	(r278231)
+++ head/usr.bin/iscsictl/token.l	Thu Feb  5 06:37:59 2015	(r278232)
@@ -63,6 +63,7 @@ tgtChapSecret		{ return MUTUAL_SECRET; }
 AuthMethod		{ return AUTH_METHOD; }
 SessionType		{ return SESSION_TYPE; }
 protocol		{ return PROTOCOL; }
+offload			{ return OFFLOAD; }
 port			{ return IGNORED; }
 MaxConnections		{ return IGNORED; }
 TargetAlias		{ return IGNORED; }

Modified: head/usr.sbin/iscsid/iscsid.c
==============================================================================
--- head/usr.sbin/iscsid/iscsid.c	Thu Feb  5 03:56:49 2015	(r278231)
+++ head/usr.sbin/iscsid/iscsid.c	Thu Feb  5 06:37:59 2015	(r278232)
@@ -152,7 +152,8 @@ resolve_addr(const struct connection *co
 
 static struct connection *
 connection_new(unsigned int session_id, const uint8_t isid[8], uint16_t tsih,
-    const struct iscsi_session_conf *conf, int iscsi_fd)
+    const struct iscsi_session_conf *conf, const struct iscsi_session_limits
+    *limits, int iscsi_fd)
 {
 	struct connection *conn;
 	struct addrinfo *from_ai, *to_ai;
@@ -186,6 +187,7 @@ connection_new(unsigned int session_id, 
 	 * XXX: Should we sanitize this somehow?
 	 */
 	memcpy(&conn->conn_conf, conf, sizeof(conn->conn_conf));
+	memcpy(&conn->conn_limits, limits, sizeof(conn->conn_limits));
 
 	from_addr = conn->conn_conf.isc_initiator_addr;
 	to_addr = conn->conn_conf.isc_target_addr;
@@ -443,7 +445,8 @@ handle_request(int iscsi_fd, const struc
 	}
 
 	conn = connection_new(request->idr_session_id, request->idr_isid,
-	    request->idr_tsih, &request->idr_conf, iscsi_fd);
+	    request->idr_tsih, &request->idr_conf, &request->idr_limits,
+	    iscsi_fd);
 	set_timeout(timeout);
 	capsicate(conn);
 	login(conn);

Modified: head/usr.sbin/iscsid/iscsid.h
==============================================================================
--- head/usr.sbin/iscsid/iscsid.h	Thu Feb  5 03:56:49 2015	(r278231)
+++ head/usr.sbin/iscsid/iscsid.h	Thu Feb  5 06:37:59 2015	(r278232)
@@ -51,6 +51,7 @@ struct connection {
 	int			conn_socket;
 	unsigned int		conn_session_id;
 	struct iscsi_session_conf	conn_conf;
+	struct iscsi_session_limits	conn_limits;
 	char			conn_target_alias[ISCSI_ADDR_LEN];
 	uint8_t			conn_isid[6];
 	uint16_t		conn_tsih;

Modified: head/usr.sbin/iscsid/login.c
==============================================================================
--- head/usr.sbin/iscsid/login.c	Thu Feb  5 03:56:49 2015	(r278231)
+++ head/usr.sbin/iscsid/login.c	Thu Feb  5 06:37:59 2015	(r278232)
@@ -441,6 +441,10 @@ login_negotiate(struct connection *conn)
 	request = login_new_request(conn, BHSLR_STAGE_OPERATIONAL_NEGOTIATION);
 	request_keys = keys_new();
 
+	log_debugx("offload \"%s\" limits MaxRecvDataSegmentLength to %zd",
+	    conn->conn_conf.isc_offload,
+	    conn->conn_limits.isl_max_data_segment_length);
+
 	/*
 	 * The following keys are irrelevant for discovery sessions.
 	 */
@@ -456,9 +460,9 @@ login_negotiate(struct connection *conn)
 
 		keys_add(request_keys, "ImmediateData", "Yes");
 		keys_add_int(request_keys, "MaxBurstLength",
-		    2 * ISCSI_MAX_DATA_SEGMENT_LENGTH);
+		    2 * conn->conn_limits.isl_max_data_segment_length);
 		keys_add_int(request_keys, "FirstBurstLength",
-		    ISCSI_MAX_DATA_SEGMENT_LENGTH);
+		    conn->conn_limits.isl_max_data_segment_length);
 		keys_add(request_keys, "InitialR2T", "Yes");
 		keys_add(request_keys, "MaxOutstandingR2T", "1");
 	} else {
@@ -467,7 +471,7 @@ login_negotiate(struct connection *conn)
 	}
 
 	keys_add_int(request_keys, "MaxRecvDataSegmentLength",
-	    ISCSI_MAX_DATA_SEGMENT_LENGTH);
+	    conn->conn_limits.isl_max_data_segment_length);
 	keys_add(request_keys, "DefaultTime2Wait", "0");
 	keys_add(request_keys, "DefaultTime2Retain", "0");
 	keys_add(request_keys, "ErrorRecoveryLevel", "0");


More information about the svn-src-head mailing list