diff --git a/pkg/port/iscsit/conn.go b/pkg/port/iscsit/conn.go index 927e8d6..a8aed77 100644 --- a/pkg/port/iscsit/conn.go +++ b/pkg/port/iscsit/conn.go @@ -22,6 +22,7 @@ import ( "sync" "github.com/gostor/gotgt/pkg/api" + "github.com/gostor/gotgt/pkg/util" ) const ( @@ -140,3 +141,70 @@ func (conn *iscsiConnection) ReInstatement(newConn *iscsiConnection) { conn.close() conn.conn = newConn.conn } + +func (conn *iscsiConnection) buildRespPackage(oc OpCode) error { + conn.txTask = &iscsiTask{conn: conn, cmd: conn.req, tag: conn.req.TaskTag, scmd: &api.SCSICommand{}} + conn.txIOState = IOSTATE_TX_BHS + conn.statSN += 1 + task := conn.rxTask + resp := &ISCSICommand{ + StatSN: conn.req.ExpStatSN, + TaskTag: conn.req.TaskTag, + ExpCmdSN: conn.session.ExpCmdSN, + MaxCmdSN: conn.session.ExpCmdSN + conn.session.MaxQueueCommand, + } + switch oc { + case OpReady: + resp.OpCode = OpReady + resp.R2TSN = task.r2tSN + resp.BufferOffset = uint32(task.offset) + resp.DesiredLength = uint32(task.r2tCount) + if val := conn.loginParam.sessionParam[ISCSI_PARAM_MAX_BURST].Value; task.r2tCount > int(val) { + resp.DesiredLength = uint32(val) + } + case OpSCSIIn, OpSCSIResp: + resp.OpCode = oc + resp.Immediate = true + resp.Final = true + resp.SCSIResponse = 0x00 + resp.HasStatus = true + scmd := task.scmd + resp.Status = scmd.Result + if scmd.Direction == api.SCSIDataRead || scmd.Direction == api.SCSIDataWrite { + if scmd.InSDBBuffer.Buffer != nil { + buf := scmd.InSDBBuffer.Buffer.Bytes() + resp.RawData = buf + } else { + resp.RawData = []byte{} + } + } + if scmd.Result != 0 && scmd.SenseBuffer != nil { + resp.RawData = scmd.SenseBuffer.Bytes() + } + case OpNoopIn, OpSCSITaskResp, OpReject: + resp.OpCode = oc + resp.Final = true + resp.NSG = FullFeaturePhase + resp.ExpCmdSN = conn.req.CmdSN + 1 + case OpLoginResp: + resp.OpCode = OpLoginResp + resp.Transit = conn.loginParam.tgtTrans + resp.CSG = conn.req.CSG + resp.NSG = conn.loginParam.tgtNSG + resp.ExpCmdSN = conn.req.CmdSN + resp.MaxCmdSN = conn.req.CmdSN + negoKeys, err := conn.processLoginData() + if err != nil { + return err + } + if !conn.loginParam.keyDeclared { + negoKeys = loginKVDeclare(conn, negoKeys) + conn.loginParam.keyDeclared = true + } + resp.RawData = util.MarshalKVText(negoKeys) + conn.txTask = nil + } + + conn.resp = resp + return nil +} diff --git a/pkg/port/iscsit/iscsid.go b/pkg/port/iscsit/iscsid.go index c8fb2ad..6feda45 100644 --- a/pkg/port/iscsit/iscsid.go +++ b/pkg/port/iscsit/iscsid.go @@ -320,11 +320,7 @@ func (s *ISCSITargetDriver) rxHandler(conn *iscsiConnection) { } func (s *ISCSITargetDriver) iscsiExecLogin(conn *iscsiConnection) error { - var ( - cmd = conn.req - err error - negoKeys []util.KeyValue - ) + var cmd = conn.req conn.cid = cmd.ConnID conn.loginParam.iniCSG = cmd.CSG @@ -334,23 +330,16 @@ func (s *ISCSITargetDriver) iscsiExecLogin(conn *iscsiConnection) error { conn.loginParam.isid = cmd.ISID conn.loginParam.tsih = cmd.TSIH conn.expCmdSN = cmd.CmdSN - conn.statSN += 1 if conn.loginParam.iniCSG == SecurityNegotiation { conn.state = CONN_STATE_EXIT return fmt.Errorf("Doesn't support Auth") } - pairs := util.ParseKVText(cmd.RawData) - - negoKeys, err = loginKVProcess(conn, pairs) + _, err := conn.processLoginData() if err != nil { return err } - if !conn.loginParam.keyDeclared { - negoKeys = loginKVDeclare(conn, negoKeys) - conn.loginParam.keyDeclared = true - } if !conn.loginParam.paramInit { err = s.BindISCSISession(conn) @@ -367,19 +356,7 @@ func (s *ISCSITargetDriver) iscsiExecLogin(conn *iscsiConnection) error { conn.state = CONN_STATE_LOGIN } - conn.resp = &ISCSICommand{ - OpCode: OpLoginResp, - Transit: conn.loginParam.tgtTrans, - CSG: cmd.CSG, - NSG: conn.loginParam.tgtNSG, - StatSN: cmd.ExpStatSN, - TaskTag: cmd.TaskTag, - ExpCmdSN: cmd.CmdSN, - MaxCmdSN: cmd.CmdSN, - RawData: util.MarshalKVText(negoKeys), - } - - return nil + return conn.buildRespPackage(OpLoginResp) } func iscsiExecLogout(conn *iscsiConnection) error { @@ -394,7 +371,7 @@ func iscsiExecLogout(conn *iscsiConnection) error { conn.resp.MaxCmdSN = cmd.CmdSN } else { conn.resp.ExpCmdSN = conn.session.ExpCmdSN - conn.resp.MaxCmdSN = conn.session.ExpCmdSN + 10 + conn.resp.MaxCmdSN = conn.session.ExpCmdSN + conn.session.MaxQueueCommand } return nil } @@ -434,62 +411,19 @@ func (s *ISCSITargetDriver) iscsiExecText(conn *iscsiConnection) error { } func iscsiExecNoopOut(conn *iscsiConnection) error { - cmd := conn.req - conn.resp = &ISCSICommand{ - OpCode: OpNoopIn, - Final: true, - NSG: FullFeaturePhase, - StatSN: cmd.ExpStatSN, - TaskTag: cmd.TaskTag, - ExpCmdSN: cmd.CmdSN + 1, - MaxCmdSN: cmd.CmdSN + 10, - } - return nil + return conn.buildRespPackage(OpNoopIn) } func iscsiExecTMFunction(conn *iscsiConnection) error { - cmd := conn.req - conn.resp = &ISCSICommand{ - OpCode: OpSCSITaskResp, - Final: true, - NSG: FullFeaturePhase, - StatSN: cmd.ExpStatSN, - TaskTag: cmd.TaskTag, - ExpCmdSN: cmd.CmdSN + 1, - MaxCmdSN: cmd.CmdSN + 10, - } - return nil + return conn.buildRespPackage(OpSCSITaskResp) } func iscsiExecReject(conn *iscsiConnection) error { - conn.resp = &ISCSICommand{ - OpCode: OpReject, - } - return nil + return conn.buildRespPackage(OpReject) } func iscsiExecR2T(conn *iscsiConnection) error { - var val uint - conn.txTask = &iscsiTask{conn: conn, cmd: conn.req, tag: conn.req.TaskTag, scmd: &api.SCSICommand{}} - conn.txIOState = IOSTATE_TX_BHS - conn.statSN += 1 - task := conn.rxTask - resp := &ISCSICommand{ - OpCode: OpReady, - StatSN: conn.req.ExpStatSN, - TaskTag: conn.req.TaskTag, - ExpCmdSN: conn.session.ExpCmdSN, - MaxCmdSN: conn.session.ExpCmdSN + 10, - R2TSN: task.r2tSN, - BufferOffset: uint32(task.offset), - DesiredLength: uint32(task.r2tCount), - } - - if val = conn.loginParam.sessionParam[ISCSI_PARAM_MAX_BURST].Value; task.r2tCount > int(val) { - resp.DesiredLength = uint32(val) - } - conn.resp = resp - return nil + return conn.buildRespPackage(OpReady) } func (s *ISCSITargetDriver) txHandler(conn *iscsiConnection) { @@ -625,46 +559,12 @@ func (s *ISCSITargetDriver) scsiCommandHandler(conn *iscsiConnection) (err error if err = s.iscsiTaskQueueHandler(task); err != nil { return } else { + if scmd.Direction == api.SCSIDataRead { + conn.buildRespPackage(OpSCSIIn) + } else { + conn.buildRespPackage(OpSCSIResp) + } conn.rxTask = nil - conn.txTask = &iscsiTask{conn: conn, cmd: conn.req, tag: conn.req.TaskTag, scmd: &api.SCSICommand{}} - conn.txIOState = IOSTATE_TX_BHS - conn.statSN += 1 - resp := &ISCSICommand{ - Immediate: true, - Final: true, - StatSN: req.ExpStatSN, - TaskTag: req.TaskTag, - ExpCmdSN: conn.session.ExpCmdSN, - MaxCmdSN: conn.session.ExpCmdSN + 10, - Status: scmd.Result, - SCSIResponse: 0x00, - HasStatus: true, - } - switch scmd.Direction { - case api.SCSIDataRead: - resp.OpCode = OpSCSIIn - if scmd.InSDBBuffer.Buffer != nil { - buf := scmd.InSDBBuffer.Buffer.Bytes() - resp.RawData = buf - } else { - resp.RawData = []byte{} - } - case api.SCSIDataWrite: - resp.OpCode = OpSCSIResp - if scmd.InSDBBuffer.Buffer != nil { - buf := scmd.InSDBBuffer.Buffer.Bytes() - resp.RawData = buf - } else { - resp.RawData = []byte{} - } - case api.SCSIDataBidirection: - case api.SCSIDataNone: - resp.OpCode = OpSCSIResp - } - if scmd.Result != 0 && scmd.SenseBuffer != nil { - resp.RawData = scmd.SenseBuffer.Bytes() - } - conn.resp = resp } case OpSCSITaskReq: // task management function @@ -712,27 +612,10 @@ func (s *ISCSITargetDriver) scsiCommandHandler(conn *iscsiConnection) (err error if err = s.iscsiExecTask(task); err != nil { return } else { + conn.buildRespPackage(OpSCSIResp) conn.rxTask = nil - conn.txTask = &iscsiTask{conn: conn, cmd: conn.req, tag: conn.req.TaskTag, scmd: &api.SCSICommand{}, state: taskSCSI} - conn.txIOState = IOSTATE_TX_BHS - conn.statSN += 1 - resp := &ISCSICommand{ - OpCode: OpSCSIResp, - Immediate: true, - Final: true, - StatSN: req.ExpStatSN, - TaskTag: req.TaskTag, - ExpCmdSN: conn.session.ExpCmdSN, - MaxCmdSN: conn.session.ExpCmdSN + 10, - Status: task.scmd.Result, - SCSIResponse: 0x00, - HasStatus: true, - } - conn.resp = resp } case OpNoopOut: - conn.txTask = &iscsiTask{conn: conn, cmd: conn.req, tag: conn.req.TaskTag} - conn.txIOState = IOSTATE_TX_BHS iscsiExecNoopOut(conn) case OpLogoutReq: conn.txTask = &iscsiTask{conn: conn, cmd: conn.req, tag: conn.req.TaskTag} diff --git a/pkg/port/iscsit/login.go b/pkg/port/iscsit/login.go index 044c8a8..55564cb 100644 --- a/pkg/port/iscsit/login.go +++ b/pkg/port/iscsit/login.go @@ -54,7 +54,7 @@ func loginKVDeclare(conn *iscsiConnection, negoKV []util.KeyValue) []util.KeyVal return negoKV } -func loginKVProcess(conn *iscsiConnection, loginKV map[string]string) ([]util.KeyValue, error) { +func (conn *iscsiConnection) processLoginData() ([]util.KeyValue, error) { var ( uintVal uint ok bool @@ -62,6 +62,7 @@ func loginKVProcess(conn *iscsiConnection, loginKV map[string]string) ([]util.Ke negoKV []util.KeyValue kvChanges int ) + loginKV := util.ParseKVText(conn.req.RawData) for key, val := range loginKV { // The MaxRecvDataSegmentLength of initiator