date: 2016-08-30/22:00

This commit is contained in:
Lei Xue
2016-08-30 22:07:32 +08:00
parent ca14aab4c2
commit 11aad6c253
3 changed files with 49 additions and 3 deletions

View File

@@ -90,7 +90,7 @@ type ISCSICommand struct {
Status byte
SCSIResponse byte
// Data-In
// Data-In/Out
HasStatus bool
DataSN uint32
BufferOffset uint32
@@ -187,6 +187,11 @@ func parseHeader(data []byte) (*ISCSICommand, error) {
m.CDB = data[32:48]
m.ExpStatSN = uint32(ParseUint(data[28:32]))
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:
m.Transit = m.Final
m.Cont = data[1]&0x40 == 0x40

View File

@@ -18,6 +18,7 @@ package iscsit
import (
"net"
"sync"
"github.com/gostor/gotgt/pkg/api"
)
@@ -81,6 +82,8 @@ type iscsiConnection struct {
txTask *iscsiTask
authMethod AuthMethod
readLock *sync.RWMutex
}
type taskState int
@@ -101,6 +104,7 @@ type iscsiTask struct {
func (c *iscsiConnection) init() {
c.state = CONN_STATE_FREE
c.refcount = 1
c.readLock = new(sync.RWMutex)
c.sessionParam = []ISCSISessionParam{}
for _, param := range sessionKeys {
c.sessionParam = append(c.sessionParam, ISCSISessionParam{Value: param.def})

View File

@@ -110,6 +110,8 @@ func (s *ISCSITargetService) rxHandler(conn *iscsiConnection) {
final bool = false
cmd *ISCSICommand
)
conn.readLock.Lock()
defer conn.readLock.Unlock()
if conn.state == CONN_STATE_SCSI {
hdigest = conn.sessionParam[ISCSI_PARAM_HDRDGST_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
}
if length == 0 {
glog.Warningf("set connection to close")
conn.state = CONN_STATE_CLOSE
return
}
@@ -131,6 +134,7 @@ func (s *ISCSITargetService) rxHandler(conn *iscsiConnection) {
cmd, err = parseHeader(buf)
if err != nil {
glog.Error(err)
glog.Warningf("set connection to close")
conn.state = CONN_STATE_CLOSE
return
}
@@ -162,10 +166,12 @@ func (s *ISCSITargetService) rxHandler(conn *iscsiConnection) {
return
}
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
return
}
cmd.RawData = buf[:cmd.DataLen]
cmd.RawData = buf[:length]
conn.rxBuffer = append(conn.rxBuffer, buf...)
final = true
glog.Infof("got command: \n%s", cmd.String())
@@ -189,16 +195,19 @@ func (s *ISCSITargetService) rxHandler(conn *iscsiConnection) {
glog.Infof("OpLoginReq")
if err := s.iscsiExecLogin(conn); err != nil {
glog.Error(err)
glog.Warningf("set connection to close")
conn.state = CONN_STATE_CLOSE
}
case OpLogoutReq:
glog.Infof("OpLogoutReq")
if err := iscsiExecLogout(conn); err != nil {
glog.Warningf("set connection to close")
conn.state = CONN_STATE_CLOSE
}
case OpTextReq:
glog.Infof("OpTextReq")
if err := s.iscsiExecText(conn); err != nil {
glog.Warningf("set connection to close")
conn.state = CONN_STATE_CLOSE
}
default:
@@ -426,8 +435,10 @@ func (s *ISCSITargetService) txHandler(conn *iscsiConnection) {
}
}
glog.Infof("connection state: %d", conn.state)
switch conn.state {
case CONN_STATE_CLOSE, CONN_STATE_EXIT:
glog.Warningf("set connection to close")
conn.state = CONN_STATE_CLOSE
case CONN_STATE_SECURITY_LOGIN:
conn.state = CONN_STATE_LOGIN
@@ -509,6 +520,32 @@ func (s *ISCSITargetService) scsiCommandHandler(conn *iscsiConnection) (err erro
conn.txIOState = IOSTATE_TX_BHS
iscsiExecTMFunction(conn)
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:
conn.txTask = &iscsiTask{conn: conn, cmd: conn.req, tag: conn.req.TaskTag}
conn.txIOState = IOSTATE_TX_BHS
@@ -579,7 +616,7 @@ func (s *ISCSITargetService) iscsiTaskQueueHandler(task *iscsiTask) error {
func (s *ISCSITargetService) iscsiExecTask(task *iscsiTask) error {
cmd := task.cmd
switch cmd.OpCode {
case OpSCSICmd:
case OpSCSICmd, OpSCSIOut:
if cmd.Read {
if cmd.Write {
task.scmd.Direction = api.SCSIDataBidirection