small refactor: combine all package response generation

This commit is contained in:
Lei Xue
2016-12-11 18:21:53 +08:00
parent c8d2d89619
commit 42949563ac
3 changed files with 84 additions and 132 deletions

View File

@@ -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
}

View File

@@ -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}

View File

@@ -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