diff --git a/.travis.yml b/.travis.yml index 8ef930b..95786ca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,6 +43,7 @@ script: - ./test-tool/iscsi-test-cu -d -A --test=ALL.Inquiry.MandatoryVPDSBC iscsi://127.0.0.1:3260/${TARGET}/0 - ./test-tool/iscsi-test-cu -d -A --test=ALL.Inquiry.SupportedVPD iscsi://127.0.0.1:3260/${TARGET}/0 - ./test-tool/iscsi-test-cu -d -A --test=ALL.Inquiry.VersionDescriptors iscsi://127.0.0.1:3260/${TARGET}/0 + - ./test-tool/iscsi-test-cu -d -A --test=ALL.Inquiry.EVPD iscsi://127.0.0.1:3260/${TARGET}/0 - ./test-tool/iscsi-test-cu -d -A --test=ALL.Mandatory iscsi://127.0.0.1:3260/${TARGET}/0 - ./test-tool/iscsi-test-cu -d -A --test=ALL.ModeSense6 iscsi://127.0.0.1:3260/${TARGET}/0 - ./test-tool/iscsi-test-cu -d -A --test=ALL.NoMedia iscsi://127.0.0.1:3260/${TARGET}/0 diff --git a/pkg/port/iscsit/cmd.go b/pkg/port/iscsit/cmd.go index 91789fd..4c275be 100644 --- a/pkg/port/iscsit/cmd.go +++ b/pkg/port/iscsit/cmd.go @@ -21,6 +21,7 @@ import ( "fmt" "strings" + log "github.com/Sirupsen/logrus" "github.com/gostor/gotgt/pkg/util" ) @@ -186,7 +187,7 @@ func (m *ISCSICommand) String() string { s = append(s, fmt.Sprintf("Next Stage = %v", m.NSG)) s = append(s, fmt.Sprintf("Status Class = %d", m.StatusClass)) s = append(s, fmt.Sprintf("Status Detail = %d", m.StatusDetail)) - case OpSCSICmd, OpSCSIOut: + case OpSCSICmd, OpSCSIOut, OpSCSIIn: s = append(s, fmt.Sprintf("LUN = %d", m.LUN)) s = append(s, fmt.Sprintf("ExpectedDataLen = %d", m.ExpectedDataLen)) s = append(s, fmt.Sprintf("CmdSN = %d", m.CmdSN)) @@ -281,7 +282,11 @@ func (m *ISCSICommand) scsiCmdRespBytes() []byte { buf.WriteByte(byte(OpSCSIResp)) var flag byte = 0x80 if m.Resid > 0 { - flag |= 0x02 + if m.Resid > m.ExpectedDataLen { + flag |= 0x04 + } else { + flag |= 0x02 + } } buf.WriteByte(flag) buf.WriteByte(byte(m.SCSIResponse)) @@ -325,8 +330,13 @@ func (m *ISCSICommand) dataInBytes() []byte { if m.HasStatus && m.Final == true { flag |= 0x01 } + log.Debugf("resid: %v, ExpectedDataLen: %v", m.Resid, m.ExpectedDataLen) if m.Resid > 0 { - flag |= 0x02 + if m.Resid > m.ExpectedDataLen { + flag |= 0x04 + } else { + flag |= 0x02 + } } buf.WriteByte(flag) buf.WriteByte(0x00) diff --git a/pkg/port/iscsit/conn.go b/pkg/port/iscsit/conn.go index 657c2c0..5330375 100644 --- a/pkg/port/iscsit/conn.go +++ b/pkg/port/iscsit/conn.go @@ -155,10 +155,11 @@ func (conn *iscsiConnection) buildRespPackage(oc OpCode, task *iscsiTask) error task = conn.rxTask } resp := &ISCSICommand{ - StatSN: conn.req.ExpStatSN, - TaskTag: conn.req.TaskTag, - ExpCmdSN: conn.session.ExpCmdSN, - MaxCmdSN: conn.session.ExpCmdSN + conn.session.MaxQueueCommand, + StatSN: conn.req.ExpStatSN, + TaskTag: conn.req.TaskTag, + ExpCmdSN: conn.session.ExpCmdSN, + MaxCmdSN: conn.session.ExpCmdSN + conn.session.MaxQueueCommand, + ExpectedDataLen: conn.req.ExpectedDataLen, } switch oc { case OpReady: diff --git a/pkg/port/iscsit/iscsid.go b/pkg/port/iscsit/iscsid.go index ea26028..1bb7c8f 100644 --- a/pkg/port/iscsit/iscsid.go +++ b/pkg/port/iscsit/iscsid.go @@ -313,8 +313,7 @@ func (s *ISCSITargetDriver) rxHandler(conn *iscsiConnection) { default: iscsiExecReject(conn) } - log.Debugf("connection state is %v", conn.state) - log.Debugf("%#v", conn.resp.String()) + log.Debugf("connection state is %v", conn.State()) s.handler(DATAOUT, conn) } } @@ -476,9 +475,7 @@ SendRemainingData: switch conn.txIOState { case IOSTATE_TX_BHS: log.Debug("ready to write response") - log.Debugf("%s", resp.String()) - log.Debugf("length of RawData is %d", len(resp.RawData)) - log.Debugf("length of resp is %d", len(resp.Bytes())) + log.Debugf("response is %s", resp.String()) if l, err := conn.write(resp.Bytes()); err != nil { log.Error(err) return diff --git a/pkg/port/iscsit/login.go b/pkg/port/iscsit/login.go index 547962a..2b69d9c 100644 --- a/pkg/port/iscsit/login.go +++ b/pkg/port/iscsit/login.go @@ -1,10 +1,25 @@ +/* +Copyright 2017 The GoStor Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package iscsit import ( "bytes" "fmt" - // log "github.com/Sirupsen/logrus" "github.com/gostor/gotgt/pkg/util" ) diff --git a/pkg/scsi/sbc.go b/pkg/scsi/sbc.go index 3dc1662..0a6179b 100644 --- a/pkg/scsi/sbc.go +++ b/pkg/scsi/sbc.go @@ -20,6 +20,7 @@ package scsi import ( "bytes" "encoding/binary" + "fmt" "unsafe" log "github.com/Sirupsen/logrus" @@ -67,6 +68,8 @@ func (sbc SBCSCSIDeviceProtocol) InitLu(lu *api.SCSILu) error { lu.Attrs.VendorID = SCSIVendorID lu.Attrs.ProductID = SCSIProductID lu.Attrs.ProductRev = version.SCSIVersion + lu.Attrs.SCSIID = fmt.Sprintf("gotgt-scsi-%d%d", 0, lu.UUID) + lu.Attrs.SCSISN = fmt.Sprintf("gotgt-beaf-%d%d", 0, lu.UUID) /* SCSIID for PAGE83 T10 VENDOR IDENTIFICATION field diff --git a/pkg/scsi/scsi.go b/pkg/scsi/scsi.go index bfc5c66..132d54c 100644 --- a/pkg/scsi/scsi.go +++ b/pkg/scsi/scsi.go @@ -158,6 +158,7 @@ func BuildSenseData(cmd *api.SCSICommand, key byte, asc SCSISubError) { } if ok { if int64(len(senseBuffer.Bytes())) > inBufLen { + log.Warnf("sense buffer is bigger than in buffer") senseBuffer.Truncate(int(inBufLen)) } } else { diff --git a/pkg/scsi/spc.go b/pkg/scsi/spc.go index 8b0f161..88162db 100644 --- a/pkg/scsi/spc.go +++ b/pkg/scsi/spc.go @@ -86,31 +86,23 @@ func InquiryPage0x00(host int, cmd *api.SCSICommand) (*bytes.Buffer, uint16) { func InquiryPage0x80(host int, cmd *api.SCSICommand) (*bytes.Buffer, uint16) { var ( buf = &bytes.Buffer{} - descBuf = &bytes.Buffer{} - data []byte = []byte{} - pageLength uint16 = 0 + pageLength uint16 = 36 + scsisn = make([]byte, pageLength) ) - descBuf.WriteByte(0x20) - descBuf.WriteByte(0x20) - descBuf.WriteByte(0x20) - descBuf.WriteByte(0x20) - - data = descBuf.Bytes() - pageLength = uint16(len(data)) - //byte 0 if cmd.Device.Attrs.Online { buf.WriteByte(PQ_DEVICE_CONNECTED | byte(cmd.Device.Attrs.DeviceType)) } else { buf.WriteByte(PQ_DEVICE_NOT_CONNECT | byte(cmd.Device.Attrs.DeviceType)) } - //byte 1 - //PAGE CODE + //byte 1: PAGE CODE buf.WriteByte(0x80) - //PAGE LENGTH - binary.Write(buf, binary.BigEndian, pageLength) - buf.Write(data) + //byte 2-3: PAGE LENGTH + buf.WriteByte(uint8(pageLength >> 8)) + buf.WriteByte(uint8(pageLength & 0xff)) + copy(scsisn, []byte(fmt.Sprintf("gotgt-%-36v", cmd.Device.UUID))) + buf.Write(scsisn) return buf, pageLength } @@ -206,7 +198,6 @@ func InquiryPage0x83(host int, cmd *api.SCSICommand) (*bytes.Buffer, uint16) { func SPCInquiry(host int, cmd *api.SCSICommand) api.SAMStat { var ( allocationLength uint16 - pageLength uint16 additionLength byte buf = &bytes.Buffer{} data []byte = []byte{} @@ -235,24 +226,28 @@ func SPCInquiry(host int, cmd *api.SCSICommand) api.SAMStat { if evpd { switch pcode { case 0x00: - buf, pageLength = InquiryPage0x00(host, cmd) + buf, _ = InquiryPage0x00(host, cmd) case 0x80: - buf, pageLength = InquiryPage0x80(host, cmd) + buf, _ = InquiryPage0x80(host, cmd) case 0x83: - buf, pageLength = InquiryPage0x83(host, cmd) + buf, _ = InquiryPage0x83(host, cmd) default: goto sense } data = buf.Bytes() - if allocationLength < pageLength { + if int(allocationLength) < len(data) { cmd.InSDBBuffer.Buffer = bytes.NewBuffer(data[0:allocationLength]) + cmd.InSDBBuffer.Resid = uint32(len(data)) } else { cmd.InSDBBuffer.Buffer = bytes.NewBuffer(data[0:]) } } else { + if pcode != 0 { + goto sense + } //byte 5 //SCCS(0) AAC(0) TPGS(0) 3PC(0) PROTECT(0) addBuf.WriteByte(INQUIRY_TPGS_IMPLICIT) @@ -576,7 +571,9 @@ func SPCModeSense(host int, cmd *api.SCSICommand) api.SAMStat { data[6] = uint8(blkDesctionLen >> 8) data[7] = uint8(blkDesctionLen) } - cmd.InSDBBuffer.Resid = uint32(len(data)) + if rlen := uint32(len(data)); rlen < allocLen { + cmd.InSDBBuffer.Resid = rlen + } cmd.InSDBBuffer.Buffer = bytes.NewBuffer(data) return api.SAMStatGood sense: