Work around a bug in the OpenSolaris iSCSI target.
authorMichael Brown <mcb30@etherboot.org>
Mon, 5 Nov 2007 13:29:05 +0000 (13:29 +0000)
committerMichael Brown <mcb30@etherboot.org>
Mon, 5 Nov 2007 13:29:05 +0000 (13:29 +0000)
We didn't specify values for MaxRecvDataSegmentLength and
MaxBurstLength (to save space, since we were happy with the
RFC-defined default values of 8kB and 256kB respectively).  However,
the OpenSolaris target (incorrectly) assumes default values of zero
for these parameters.

The upshot was that the OpenSolaris target would get stuck in an
endless loop trying to send us the first 512-byte sector, zero bytes
at a time, and would eventually run out of memory and core-dump.

Fixed by explicitly specifying the default values for these two
parameters.

src/net/tcp/iscsi.c

index ccb6cff..0a24c45 100644 (file)
@@ -421,8 +421,8 @@ static int iscsi_tx_data_out ( struct iscsi_session *iscsi ) {
  *     MaxConnections is irrelevant; we make only one connection anyway
  *     InitialR2T=Yes [1]
  *     ImmediateData is irrelevant; we never send immediate data
- *     MaxRecvDataSegmentLength=8192 (default; we don't care)
- *     MaxBurstLength=262144 (default; we don't care)
+ *     MaxRecvDataSegmentLength=8192 (default; we don't care) [3]
+ *     MaxBurstLength=262144 (default; we don't care) [3]
  *     FirstBurstLength=262144 (default; we don't care)
  *     DefaultTime2Wait=0 [2]
  *     DefaultTime2Retain=0 [2]
@@ -438,6 +438,11 @@ static int iscsi_tx_data_out ( struct iscsi_session *iscsi ) {
  * [2] These ensure that we can safely start a new task once we have
  * reconnected after a failure, without having to manually tidy up
  * after the old one.
+ *
+ * [3] We are quite happy to use the RFC-defined default values for
+ * these parameters, but some targets (notably OpenSolaris)
+ * incorrectly assume a default value of zero, so we explicitly
+ * specify the default values.
  */
 static int iscsi_build_login_request_strings ( struct iscsi_session *iscsi,
                                               void *data, size_t len ) {
@@ -475,13 +480,15 @@ static int iscsi_build_login_request_strings ( struct iscsi_session *iscsi,
                                    "HeaderDigest=None%c"
                                    "DataDigest=None%c"
                                    "InitialR2T=Yes%c"
+                                   "MaxRecvDataSegmentLength=8192%c"
+                                   "MaxBurstLength=262144%c"
                                    "DefaultTime2Wait=0%c"
                                    "DefaultTime2Retain=0%c"
                                    "MaxOutstandingR2T=1%c"
                                    "DataPDUInOrder=Yes%c"
                                    "DataSequenceInOrder=Yes%c"
                                    "ErrorRecoveryLevel=0%c",
-                                   0, 0, 0, 0, 0, 0, 0, 0, 0 );
+                                   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
        }
 
        return used;