date: 2016-08-30/22:00
This commit is contained in:
@@ -90,7 +90,7 @@ type ISCSICommand struct {
|
|||||||
Status byte
|
Status byte
|
||||||
SCSIResponse byte
|
SCSIResponse byte
|
||||||
|
|
||||||
// Data-In
|
// Data-In/Out
|
||||||
HasStatus bool
|
HasStatus bool
|
||||||
DataSN uint32
|
DataSN uint32
|
||||||
BufferOffset uint32
|
BufferOffset uint32
|
||||||
@@ -187,6 +187,11 @@ func parseHeader(data []byte) (*ISCSICommand, error) {
|
|||||||
m.CDB = data[32:48]
|
m.CDB = data[32:48]
|
||||||
m.ExpStatSN = uint32(ParseUint(data[28:32]))
|
m.ExpStatSN = uint32(ParseUint(data[28:32]))
|
||||||
case OpSCSIResp:
|
case OpSCSIResp:
|
||||||
|
case OpSCSIOut:
|
||||||
|
m.LUN = [8]uint8{data[9]}
|
||||||
|
m.ExpStatSN = uint32(ParseUint(data[28:32]))
|
||||||
|
m.DataSN = uint32(ParseUint(data[36:40]))
|
||||||
|
m.BufferOffset = uint32(ParseUint(data[40:44]))
|
||||||
case OpLoginReq, OpTextReq, OpNoopOut, OpLogoutReq:
|
case OpLoginReq, OpTextReq, OpNoopOut, OpLogoutReq:
|
||||||
m.Transit = m.Final
|
m.Transit = m.Final
|
||||||
m.Cont = data[1]&0x40 == 0x40
|
m.Cont = data[1]&0x40 == 0x40
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package iscsit
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/gostor/gotgt/pkg/api"
|
"github.com/gostor/gotgt/pkg/api"
|
||||||
)
|
)
|
||||||
@@ -81,6 +82,8 @@ type iscsiConnection struct {
|
|||||||
txTask *iscsiTask
|
txTask *iscsiTask
|
||||||
|
|
||||||
authMethod AuthMethod
|
authMethod AuthMethod
|
||||||
|
|
||||||
|
readLock *sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
type taskState int
|
type taskState int
|
||||||
@@ -101,6 +104,7 @@ type iscsiTask struct {
|
|||||||
func (c *iscsiConnection) init() {
|
func (c *iscsiConnection) init() {
|
||||||
c.state = CONN_STATE_FREE
|
c.state = CONN_STATE_FREE
|
||||||
c.refcount = 1
|
c.refcount = 1
|
||||||
|
c.readLock = new(sync.RWMutex)
|
||||||
c.sessionParam = []ISCSISessionParam{}
|
c.sessionParam = []ISCSISessionParam{}
|
||||||
for _, param := range sessionKeys {
|
for _, param := range sessionKeys {
|
||||||
c.sessionParam = append(c.sessionParam, ISCSISessionParam{Value: param.def})
|
c.sessionParam = append(c.sessionParam, ISCSISessionParam{Value: param.def})
|
||||||
|
|||||||
@@ -110,6 +110,8 @@ func (s *ISCSITargetService) rxHandler(conn *iscsiConnection) {
|
|||||||
final bool = false
|
final bool = false
|
||||||
cmd *ISCSICommand
|
cmd *ISCSICommand
|
||||||
)
|
)
|
||||||
|
conn.readLock.Lock()
|
||||||
|
defer conn.readLock.Unlock()
|
||||||
if conn.state == CONN_STATE_SCSI {
|
if conn.state == CONN_STATE_SCSI {
|
||||||
hdigest = conn.sessionParam[ISCSI_PARAM_HDRDGST_EN].Value & DIGEST_CRC32C
|
hdigest = conn.sessionParam[ISCSI_PARAM_HDRDGST_EN].Value & DIGEST_CRC32C
|
||||||
ddigest = conn.sessionParam[ISCSI_PARAM_DATADGST_EN].Value & DIGEST_CRC32C
|
ddigest = conn.sessionParam[ISCSI_PARAM_DATADGST_EN].Value & DIGEST_CRC32C
|
||||||
@@ -124,6 +126,7 @@ func (s *ISCSITargetService) rxHandler(conn *iscsiConnection) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if length == 0 {
|
if length == 0 {
|
||||||
|
glog.Warningf("set connection to close")
|
||||||
conn.state = CONN_STATE_CLOSE
|
conn.state = CONN_STATE_CLOSE
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -131,6 +134,7 @@ func (s *ISCSITargetService) rxHandler(conn *iscsiConnection) {
|
|||||||
cmd, err = parseHeader(buf)
|
cmd, err = parseHeader(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Error(err)
|
glog.Error(err)
|
||||||
|
glog.Warningf("set connection to close")
|
||||||
conn.state = CONN_STATE_CLOSE
|
conn.state = CONN_STATE_CLOSE
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -162,10 +166,12 @@ func (s *ISCSITargetService) rxHandler(conn *iscsiConnection) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if length != dl {
|
if length != dl {
|
||||||
|
glog.V(2).Infof("get length is %d, but expected %d", length, dl)
|
||||||
|
glog.Warningf("set connection to close")
|
||||||
conn.state = CONN_STATE_CLOSE
|
conn.state = CONN_STATE_CLOSE
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cmd.RawData = buf[:cmd.DataLen]
|
cmd.RawData = buf[:length]
|
||||||
conn.rxBuffer = append(conn.rxBuffer, buf...)
|
conn.rxBuffer = append(conn.rxBuffer, buf...)
|
||||||
final = true
|
final = true
|
||||||
glog.Infof("got command: \n%s", cmd.String())
|
glog.Infof("got command: \n%s", cmd.String())
|
||||||
@@ -189,16 +195,19 @@ func (s *ISCSITargetService) rxHandler(conn *iscsiConnection) {
|
|||||||
glog.Infof("OpLoginReq")
|
glog.Infof("OpLoginReq")
|
||||||
if err := s.iscsiExecLogin(conn); err != nil {
|
if err := s.iscsiExecLogin(conn); err != nil {
|
||||||
glog.Error(err)
|
glog.Error(err)
|
||||||
|
glog.Warningf("set connection to close")
|
||||||
conn.state = CONN_STATE_CLOSE
|
conn.state = CONN_STATE_CLOSE
|
||||||
}
|
}
|
||||||
case OpLogoutReq:
|
case OpLogoutReq:
|
||||||
glog.Infof("OpLogoutReq")
|
glog.Infof("OpLogoutReq")
|
||||||
if err := iscsiExecLogout(conn); err != nil {
|
if err := iscsiExecLogout(conn); err != nil {
|
||||||
|
glog.Warningf("set connection to close")
|
||||||
conn.state = CONN_STATE_CLOSE
|
conn.state = CONN_STATE_CLOSE
|
||||||
}
|
}
|
||||||
case OpTextReq:
|
case OpTextReq:
|
||||||
glog.Infof("OpTextReq")
|
glog.Infof("OpTextReq")
|
||||||
if err := s.iscsiExecText(conn); err != nil {
|
if err := s.iscsiExecText(conn); err != nil {
|
||||||
|
glog.Warningf("set connection to close")
|
||||||
conn.state = CONN_STATE_CLOSE
|
conn.state = CONN_STATE_CLOSE
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -426,8 +435,10 @@ func (s *ISCSITargetService) txHandler(conn *iscsiConnection) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glog.Infof("connection state: %d", conn.state)
|
||||||
switch conn.state {
|
switch conn.state {
|
||||||
case CONN_STATE_CLOSE, CONN_STATE_EXIT:
|
case CONN_STATE_CLOSE, CONN_STATE_EXIT:
|
||||||
|
glog.Warningf("set connection to close")
|
||||||
conn.state = CONN_STATE_CLOSE
|
conn.state = CONN_STATE_CLOSE
|
||||||
case CONN_STATE_SECURITY_LOGIN:
|
case CONN_STATE_SECURITY_LOGIN:
|
||||||
conn.state = CONN_STATE_LOGIN
|
conn.state = CONN_STATE_LOGIN
|
||||||
@@ -509,6 +520,32 @@ func (s *ISCSITargetService) scsiCommandHandler(conn *iscsiConnection) (err erro
|
|||||||
conn.txIOState = IOSTATE_TX_BHS
|
conn.txIOState = IOSTATE_TX_BHS
|
||||||
iscsiExecTMFunction(conn)
|
iscsiExecTMFunction(conn)
|
||||||
case OpSCSIOut:
|
case OpSCSIOut:
|
||||||
|
glog.Infof("scsi out operation")
|
||||||
|
scmd := &api.SCSICommand{}
|
||||||
|
conn.req.Write = true
|
||||||
|
conn.req.CDB = []byte{api.Write_10}
|
||||||
|
task := &iscsiTask{conn: conn, cmd: conn.req, tag: conn.req.TaskTag, scmd: scmd}
|
||||||
|
conn.rxTask = task
|
||||||
|
if err = s.iscsiExecTask(task); err != nil {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
conn.resp = resp
|
||||||
|
}
|
||||||
case OpNoopOut:
|
case OpNoopOut:
|
||||||
conn.txTask = &iscsiTask{conn: conn, cmd: conn.req, tag: conn.req.TaskTag}
|
conn.txTask = &iscsiTask{conn: conn, cmd: conn.req, tag: conn.req.TaskTag}
|
||||||
conn.txIOState = IOSTATE_TX_BHS
|
conn.txIOState = IOSTATE_TX_BHS
|
||||||
@@ -579,7 +616,7 @@ func (s *ISCSITargetService) iscsiTaskQueueHandler(task *iscsiTask) error {
|
|||||||
func (s *ISCSITargetService) iscsiExecTask(task *iscsiTask) error {
|
func (s *ISCSITargetService) iscsiExecTask(task *iscsiTask) error {
|
||||||
cmd := task.cmd
|
cmd := task.cmd
|
||||||
switch cmd.OpCode {
|
switch cmd.OpCode {
|
||||||
case OpSCSICmd:
|
case OpSCSICmd, OpSCSIOut:
|
||||||
if cmd.Read {
|
if cmd.Read {
|
||||||
if cmd.Write {
|
if cmd.Write {
|
||||||
task.scmd.Direction = api.SCSIDataBidirection
|
task.scmd.Direction = api.SCSIDataBidirection
|
||||||
|
|||||||
Reference in New Issue
Block a user