date: 2016-08-30/17:00
This commit is contained in:
@@ -110,6 +110,8 @@ func (cmd *ISCSICommand) Bytes() []byte {
|
||||
return cmd.textRespBytes()
|
||||
case OpNoopIn:
|
||||
return cmd.noopInBytes()
|
||||
case OpSCSITaskResp:
|
||||
return cmd.scsiTMFRespBytes()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -176,7 +178,7 @@ func parseHeader(data []byte) (*ISCSICommand, error) {
|
||||
m.DataLen = int(ParseUint(data[5:8]))
|
||||
m.TaskTag = uint32(ParseUint(data[16:20]))
|
||||
switch m.OpCode {
|
||||
case OpSCSICmd:
|
||||
case OpSCSICmd, OpSCSITaskReq:
|
||||
m.LUN = [8]uint8{data[9]}
|
||||
m.ExpectedDataLen = uint32(ParseUint(data[20:24]))
|
||||
m.CmdSN = uint32(ParseUint(data[24:28]))
|
||||
@@ -364,3 +366,29 @@ func (m *ISCSICommand) noopInBytes() []byte {
|
||||
buf.Write(rd)
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func (m *ISCSICommand) scsiTMFRespBytes() []byte {
|
||||
// rfc7143 11.6
|
||||
buf := &bytes.Buffer{}
|
||||
buf.WriteByte(byte(OpSCSITaskResp))
|
||||
buf.WriteByte(0x80)
|
||||
buf.WriteByte(0x00)
|
||||
buf.WriteByte(0x00)
|
||||
|
||||
// Skip through to byte 16
|
||||
for i := 0; i < 3*4; i++ {
|
||||
buf.WriteByte(0x00)
|
||||
}
|
||||
buf.Write(util.MarshalUint64(uint64(m.TaskTag))[4:])
|
||||
for i := 0; i < 4; i++ {
|
||||
buf.WriteByte(0x00)
|
||||
}
|
||||
buf.Write(util.MarshalUint64(uint64(m.StatSN))[4:])
|
||||
buf.Write(util.MarshalUint64(uint64(m.ExpCmdSN))[4:])
|
||||
buf.Write(util.MarshalUint64(uint64(m.MaxCmdSN))[4:])
|
||||
for i := 0; i < 3*4; i++ {
|
||||
buf.WriteByte(0x00)
|
||||
}
|
||||
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
@@ -139,8 +139,8 @@ func (s *ISCSITargetService) rxHandler(conn *iscsiConnection) {
|
||||
conn.rxIOState = IOSTATE_RX_INIT_AHS
|
||||
break
|
||||
}
|
||||
glog.Infof("got command: \n%s", cmd.String())
|
||||
glog.Infof("got buffer: %v", buf)
|
||||
glog.V(2).Infof("got command: \n%s", cmd.String())
|
||||
glog.V(2).Infof("got buffer: %v", buf)
|
||||
final = true
|
||||
case IOSTATE_RX_INIT_AHS:
|
||||
conn.rxIOState = IOSTATE_RX_DATA
|
||||
@@ -204,6 +204,7 @@ func (s *ISCSITargetService) rxHandler(conn *iscsiConnection) {
|
||||
default:
|
||||
iscsiExecReject(conn)
|
||||
}
|
||||
glog.V(1).Infof("connection state is %v", conn.state)
|
||||
glog.Infof("%#v", conn.resp.String())
|
||||
s.handler(DATAOUT, conn)
|
||||
}
|
||||
@@ -347,6 +348,20 @@ func iscsiExecNoopOut(conn *iscsiConnection) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func iscsiExecReject(conn *iscsiConnection) error {
|
||||
conn.resp = &ISCSICommand{
|
||||
OpCode: OpReject,
|
||||
@@ -432,6 +447,7 @@ func (s *ISCSITargetService) txHandler(conn *iscsiConnection) {
|
||||
case CONN_STATE_SCSI:
|
||||
conn.txTask = nil
|
||||
default:
|
||||
glog.Infof("unexpected connection state: %d", conn.state)
|
||||
conn.rxIOState = IOSTATE_RX_BHS
|
||||
s.handler(DATAIN, conn)
|
||||
}
|
||||
@@ -487,6 +503,11 @@ func (s *ISCSITargetService) scsiCommandHandler(conn *iscsiConnection) (err erro
|
||||
}
|
||||
conn.resp = resp
|
||||
}
|
||||
case OpSCSITaskReq:
|
||||
// task management function
|
||||
conn.txTask = &iscsiTask{conn: conn, cmd: conn.req, tag: conn.req.TaskTag}
|
||||
conn.txIOState = IOSTATE_TX_BHS
|
||||
iscsiExecTMFunction(conn)
|
||||
case OpSCSIOut:
|
||||
case OpNoopOut:
|
||||
conn.txTask = &iscsiTask{conn: conn, cmd: conn.req, tag: conn.req.TaskTag}
|
||||
|
||||
@@ -19,6 +19,7 @@ package backingstore
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/golang/glog"
|
||||
@@ -74,7 +75,7 @@ func (bs *FileBackingStore) CommandSubmit(cmd *api.SCSICommand) (err error) {
|
||||
key = scsi.ILLEGAL_REQUEST
|
||||
asc = scsi.ASC_INVALID_FIELD_IN_CDB
|
||||
wbuf []byte = []byte{}
|
||||
rbuf []byte = []byte{}
|
||||
rbuf = make([]byte, cmd.TL)
|
||||
length int
|
||||
doVerify bool = false
|
||||
doWrite bool = false
|
||||
@@ -98,6 +99,9 @@ func (bs *FileBackingStore) CommandSubmit(cmd *api.SCSICommand) (err error) {
|
||||
doWrite = true
|
||||
goto write
|
||||
case api.SYNCHRONIZE_CACHE, api.SYNCHRONIZE_CACHE_16:
|
||||
if err = util.Fdatasync(lu.File); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
break
|
||||
case api.WRITE_VERIFY, api.WRITE_VERIFY_12, api.WRITE_VERIFY_16:
|
||||
doVerify = true
|
||||
@@ -110,7 +114,7 @@ func (bs *FileBackingStore) CommandSubmit(cmd *api.SCSICommand) (err error) {
|
||||
break
|
||||
case api.READ_6, api.READ_10, api.READ_12, api.READ_16:
|
||||
length, err = lu.File.ReadAt(rbuf, int64(offset))
|
||||
if err != nil {
|
||||
if err != nil && err != io.EOF {
|
||||
key = scsi.MEDIUM_ERROR
|
||||
asc = scsi.ASC_READ_ERROR
|
||||
break
|
||||
|
||||
@@ -35,13 +35,13 @@ func NewSCSILu(lun uint64, target *api.SCSITarget) (*api.SCSILu, error) {
|
||||
DeviceProtocol: sbc,
|
||||
Storage: backing,
|
||||
BlockShift: 0,
|
||||
Size: 1024 * 1024 * 1024,
|
||||
Size: 1024 * 1024 * 10,
|
||||
}
|
||||
// hack this
|
||||
if _, err = os.Stat("/tmp/data.txt"); err != nil && os.IsExist(err) {
|
||||
os.Create("/tmp/data.txt")
|
||||
if _, err = os.Stat("/var/tmp/disk.img"); err != nil && os.IsExist(err) {
|
||||
panic(err)
|
||||
}
|
||||
f, err := backing.Open(lu, "/tmp/data.txt")
|
||||
f, err := backing.Open(lu, "/var/tmp/disk.img")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user