perf2
This commit is contained in:
@@ -278,7 +278,7 @@ func parseHeader(data []byte) (*ISCSICommand, error) {
|
||||
|
||||
func (m *ISCSICommand) scsiCmdRespBytes() []byte {
|
||||
// rfc7143 11.4
|
||||
buf := &bytes.Buffer{}
|
||||
buf := bytes.Buffer{}
|
||||
buf.WriteByte(byte(OpSCSIResp))
|
||||
var flag byte = 0x80
|
||||
if m.Resid > 0 {
|
||||
@@ -321,8 +321,12 @@ func (m *ISCSICommand) scsiCmdRespBytes() []byte {
|
||||
|
||||
func (m *ISCSICommand) dataInBytes() []byte {
|
||||
// rfc7143 11.7
|
||||
buf := &bytes.Buffer{}
|
||||
buf.WriteByte(byte(OpSCSIIn))
|
||||
dl := m.DataLen
|
||||
for dl%4 > 0 {
|
||||
dl++
|
||||
}
|
||||
var buf = make([]byte, (48 + dl))
|
||||
buf[0] = byte(OpSCSIIn)
|
||||
var flag byte
|
||||
if m.FinalInSeq || m.Final == true {
|
||||
flag |= 0x80
|
||||
@@ -338,44 +342,29 @@ func (m *ISCSICommand) dataInBytes() []byte {
|
||||
flag |= 0x02
|
||||
}
|
||||
}
|
||||
buf.WriteByte(flag)
|
||||
buf.WriteByte(0x00)
|
||||
buf[1] = flag
|
||||
//buf.WriteByte(0x00)
|
||||
if m.HasStatus && m.Final == true {
|
||||
flag = byte(m.Status)
|
||||
}
|
||||
buf.WriteByte(flag)
|
||||
|
||||
buf.WriteByte(0x00) // 4
|
||||
|
||||
buf.Write(util.MarshalUint64(uint64(m.DataLen))[5:]) // 5-8
|
||||
//buf.WriteByte(flag)
|
||||
buf[3] = flag
|
||||
copy(buf[5:], util.MarshalUint64(uint64(m.DataLen))[5:])
|
||||
// Skip through to byte 16 Since A bit is not set 11.7.4
|
||||
for i := 0; i < 8; i++ {
|
||||
buf.WriteByte(0x00)
|
||||
}
|
||||
buf.Write(util.MarshalUint64(uint64(m.TaskTag))[4:])
|
||||
for i := 0; i < 4; i++ {
|
||||
// 11.7.4
|
||||
buf.WriteByte(0xff)
|
||||
}
|
||||
buf.Write(util.MarshalUint64(uint64(m.StatSN))[4:])
|
||||
buf.Write(util.MarshalUint64(uint64(m.ExpCmdSN))[4:])
|
||||
buf.Write(util.MarshalUint64(uint64(m.MaxCmdSN))[4:])
|
||||
buf.Write(util.MarshalUint64(uint64(m.DataSN))[4:])
|
||||
buf.Write(util.MarshalUint64(uint64(m.BufferOffset))[4:])
|
||||
buf.Write(util.MarshalUint64(uint64(m.Resid))[4:])
|
||||
buf.Write(m.RawData[m.BufferOffset : m.BufferOffset+uint32(m.DataLen)])
|
||||
dl := m.DataLen
|
||||
for dl%4 > 0 {
|
||||
dl++
|
||||
buf.WriteByte(0x00)
|
||||
}
|
||||
copy(buf[16:], util.MarshalUint32(m.TaskTag))
|
||||
copy(buf[24:], util.MarshalUint32(m.StatSN))
|
||||
copy(buf[28:], util.MarshalUint32(m.ExpCmdSN))
|
||||
copy(buf[32:], util.MarshalUint32(m.MaxCmdSN))
|
||||
copy(buf[36:], util.MarshalUint32(m.DataSN))
|
||||
copy(buf[40:], util.MarshalUint32(m.BufferOffset))
|
||||
copy(buf[44:], util.MarshalUint32(m.Resid))
|
||||
copy(buf[48:], m.RawData[m.BufferOffset:m.BufferOffset+uint32(m.DataLen)])
|
||||
|
||||
return buf.Bytes()
|
||||
return buf
|
||||
}
|
||||
|
||||
func (m *ISCSICommand) textRespBytes() []byte {
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
buf := bytes.Buffer{}
|
||||
buf.WriteByte(byte(OpTextResp))
|
||||
var b byte
|
||||
if m.Final {
|
||||
@@ -415,8 +404,7 @@ func (m *ISCSICommand) textRespBytes() []byte {
|
||||
}
|
||||
|
||||
func (m *ISCSICommand) noopInBytes() []byte {
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
buf := bytes.Buffer{}
|
||||
buf.WriteByte(byte(OpNoopIn))
|
||||
var b byte
|
||||
b |= 0x80
|
||||
@@ -452,7 +440,7 @@ func (m *ISCSICommand) noopInBytes() []byte {
|
||||
|
||||
func (m *ISCSICommand) scsiTMFRespBytes() []byte {
|
||||
// rfc7143 11.6
|
||||
buf := &bytes.Buffer{}
|
||||
buf := bytes.Buffer{}
|
||||
buf.WriteByte(byte(OpSCSITaskResp))
|
||||
buf.WriteByte(0x80)
|
||||
buf.WriteByte(m.Result)
|
||||
@@ -477,9 +465,8 @@ func (m *ISCSICommand) scsiTMFRespBytes() []byte {
|
||||
}
|
||||
|
||||
func (m *ISCSICommand) r2tRespBytes() []byte {
|
||||
|
||||
// rfc7143 11.8
|
||||
buf := &bytes.Buffer{}
|
||||
buf := bytes.Buffer{}
|
||||
buf.WriteByte(byte(OpReady))
|
||||
var b byte
|
||||
if m.Final {
|
||||
|
||||
@@ -155,7 +155,7 @@ func (conn *iscsiConnection) buildRespPackage(oc OpCode, task *iscsiTask) error
|
||||
if task == nil {
|
||||
task = conn.rxTask
|
||||
}
|
||||
resp := &ISCSICommand{
|
||||
conn.resp = &ISCSICommand{
|
||||
StatSN: conn.req.ExpStatSN,
|
||||
TaskTag: conn.req.TaskTag,
|
||||
ExpCmdSN: conn.session.ExpCmdSN,
|
||||
@@ -164,55 +164,55 @@ func (conn *iscsiConnection) buildRespPackage(oc OpCode, task *iscsiTask) error
|
||||
}
|
||||
switch oc {
|
||||
case OpReady:
|
||||
resp.OpCode = OpReady
|
||||
resp.R2TSN = task.r2tSN
|
||||
resp.BufferOffset = uint32(task.offset)
|
||||
resp.DesiredLength = uint32(task.r2tCount)
|
||||
conn.resp.OpCode = OpReady
|
||||
conn.resp.R2TSN = task.r2tSN
|
||||
conn.resp.BufferOffset = uint32(task.offset)
|
||||
conn.resp.DesiredLength = uint32(task.r2tCount)
|
||||
if val := conn.loginParam.sessionParam[ISCSI_PARAM_MAX_BURST].Value; task.r2tCount > int(val) {
|
||||
resp.DesiredLength = uint32(val)
|
||||
conn.resp.DesiredLength = uint32(val)
|
||||
}
|
||||
case OpSCSIIn, OpSCSIResp:
|
||||
resp.OpCode = oc
|
||||
resp.Immediate = true
|
||||
resp.Final = true
|
||||
resp.SCSIResponse = 0x00
|
||||
resp.HasStatus = true
|
||||
conn.resp.OpCode = oc
|
||||
conn.resp.Immediate = true
|
||||
conn.resp.Final = true
|
||||
conn.resp.SCSIResponse = 0x00
|
||||
conn.resp.HasStatus = true
|
||||
scmd := task.scmd
|
||||
resp.Status = scmd.Result
|
||||
conn.resp.Status = scmd.Result
|
||||
if scmd.Result != 0 && scmd.SenseBuffer != nil {
|
||||
length := util.MarshalUint32(scmd.SenseBuffer.Length)
|
||||
resp.RawData = append(length[2:4], scmd.SenseBuffer.Buffer...)
|
||||
conn.resp.RawData = append(length[2:4], scmd.SenseBuffer.Buffer...)
|
||||
} else if scmd.Direction == api.SCSIDataRead || scmd.Direction == api.SCSIDataWrite {
|
||||
if scmd.InSDBBuffer != nil {
|
||||
resp.Resid = scmd.InSDBBuffer.Resid
|
||||
if resp.Resid != 0 && resp.Resid < scmd.InSDBBuffer.Length {
|
||||
resp.RawData = scmd.InSDBBuffer.Buffer[:resp.Resid]
|
||||
conn.resp.Resid = scmd.InSDBBuffer.Resid
|
||||
if conn.resp.Resid != 0 && conn.resp.Resid < scmd.InSDBBuffer.Length {
|
||||
conn.resp.RawData = scmd.InSDBBuffer.Buffer[:conn.resp.Resid]
|
||||
} else {
|
||||
resp.RawData = scmd.InSDBBuffer.Buffer
|
||||
conn.resp.RawData = scmd.InSDBBuffer.Buffer
|
||||
}
|
||||
} else {
|
||||
resp.RawData = []byte{}
|
||||
conn.resp.RawData = []byte{}
|
||||
}
|
||||
}
|
||||
|
||||
case OpNoopIn, OpReject:
|
||||
resp.OpCode = oc
|
||||
resp.Final = true
|
||||
resp.NSG = FullFeaturePhase
|
||||
resp.ExpCmdSN = conn.req.CmdSN + 1
|
||||
conn.resp.OpCode = oc
|
||||
conn.resp.Final = true
|
||||
conn.resp.NSG = FullFeaturePhase
|
||||
conn.resp.ExpCmdSN = conn.req.CmdSN + 1
|
||||
case OpSCSITaskResp:
|
||||
resp.OpCode = oc
|
||||
resp.Final = true
|
||||
resp.NSG = FullFeaturePhase
|
||||
resp.ExpCmdSN = conn.req.CmdSN + 1
|
||||
resp.Result = task.result
|
||||
conn.resp.OpCode = oc
|
||||
conn.resp.Final = true
|
||||
conn.resp.NSG = FullFeaturePhase
|
||||
conn.resp.ExpCmdSN = conn.req.CmdSN + 1
|
||||
conn.resp.Result = task.result
|
||||
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
|
||||
conn.resp.OpCode = OpLoginResp
|
||||
conn.resp.Transit = conn.loginParam.tgtTrans
|
||||
conn.resp.CSG = conn.req.CSG
|
||||
conn.resp.NSG = conn.loginParam.tgtNSG
|
||||
conn.resp.ExpCmdSN = conn.req.CmdSN
|
||||
conn.resp.MaxCmdSN = conn.req.CmdSN
|
||||
negoKeys, err := conn.processLoginData()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -221,11 +221,10 @@ func (conn *iscsiConnection) buildRespPackage(oc OpCode, task *iscsiTask) error
|
||||
negoKeys = loginKVDeclare(conn, negoKeys)
|
||||
conn.loginParam.keyDeclared = true
|
||||
}
|
||||
resp.RawData = util.MarshalKVText(negoKeys)
|
||||
conn.resp.RawData = util.MarshalKVText(negoKeys)
|
||||
conn.txTask = nil
|
||||
}
|
||||
|
||||
conn.resp = resp
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -156,7 +156,6 @@ func (s *ISCSITargetDriver) Run() error {
|
||||
log.Error(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer l.Close()
|
||||
|
||||
for {
|
||||
log.Info("Listening ...")
|
||||
@@ -178,6 +177,7 @@ func (s *ISCSITargetDriver) Run() error {
|
||||
// start a new thread to do with this command
|
||||
go s.handler(DATAIN, iscsiConn)
|
||||
}
|
||||
l.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -476,10 +476,12 @@ SendRemainingData:
|
||||
for {
|
||||
switch conn.txIOState {
|
||||
case IOSTATE_TX_BHS:
|
||||
log.Debug("ready to write response")
|
||||
log.Debugf("response is %s", resp.String())
|
||||
if log.GetLevel() == log.DebugLevel {
|
||||
log.Debug("ready to write response")
|
||||
log.Debugf("response is %s", resp.String())
|
||||
}
|
||||
if l, err := conn.write(resp.Bytes()); err != nil {
|
||||
log.Error(err)
|
||||
log.Errorf("failed to write data to client: %v", err)
|
||||
return
|
||||
} else {
|
||||
conn.txIOState = IOSTATE_TX_INIT_AHS
|
||||
@@ -538,7 +540,7 @@ SendRemainingData:
|
||||
case CONN_STATE_SCSI:
|
||||
conn.txTask = nil
|
||||
default:
|
||||
log.Warnf("unexpected connection state: %d", conn.state)
|
||||
log.Warnf("unexpected connection state: %v", conn.State())
|
||||
conn.rxIOState = IOSTATE_RX_BHS
|
||||
s.handler(DATAIN, conn)
|
||||
}
|
||||
|
||||
@@ -54,16 +54,15 @@ func NewBackingStore(name string) (api.BackingStore, error) {
|
||||
|
||||
func bsPerformCommand(bs api.BackingStore, cmd *api.SCSICommand) (err error, key byte, asc SCSISubError) {
|
||||
var (
|
||||
scb = cmd.SCB
|
||||
offset = cmd.Offset
|
||||
opcode = api.SCSICommandType(scb[0])
|
||||
lu = cmd.Device
|
||||
length int
|
||||
doVerify bool = false
|
||||
doWrite bool = false
|
||||
wbuf []byte
|
||||
tl int64 = int64(cmd.TL)
|
||||
rbuf []byte = pool.NewBuffer(int(tl))
|
||||
scb = cmd.SCB
|
||||
offset = cmd.Offset
|
||||
opcode = api.SCSICommandType(scb[0])
|
||||
lu = cmd.Device
|
||||
length int
|
||||
doVerify bool = false
|
||||
doWrite bool = false
|
||||
rbuf, wbuf []byte
|
||||
tl int64 = int64(cmd.TL)
|
||||
)
|
||||
key = HARDWARE_ERROR
|
||||
asc = ASC_INTERNAL_TGT_FAILURE
|
||||
@@ -105,6 +104,7 @@ func bsPerformCommand(bs api.BackingStore, cmd *api.SCSICommand) (err error, key
|
||||
// TODO
|
||||
break
|
||||
case api.READ_6, api.READ_10, api.READ_12, api.READ_16:
|
||||
rbuf = pool.NewBuffer(int(tl))
|
||||
rbuf, err = bs.Read(int64(offset), tl)
|
||||
if err != nil && err != io.EOF {
|
||||
key = MEDIUM_ERROR
|
||||
@@ -141,7 +141,6 @@ func bsPerformCommand(bs api.BackingStore, cmd *api.SCSICommand) (err error, key
|
||||
}
|
||||
write:
|
||||
if doWrite {
|
||||
// hack: wbuf = []byte("hello world!")
|
||||
err = bs.Write(wbuf, int64(offset))
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
@@ -176,6 +175,7 @@ write:
|
||||
}
|
||||
verify:
|
||||
if doVerify {
|
||||
rbuf = pool.NewBuffer(int(tl))
|
||||
rbuf, err = bs.Read(int64(offset), tl)
|
||||
if err != nil {
|
||||
key = MEDIUM_ERROR
|
||||
@@ -187,9 +187,6 @@ verify:
|
||||
key = MISCOMPARE
|
||||
asc = ASC_MISCOMPARE_DURING_VERIFY_OPERATION
|
||||
goto sense
|
||||
} else {
|
||||
log.Warnf("%v", wbuf)
|
||||
log.Warnf("%v", rbuf)
|
||||
}
|
||||
if scb[1]&0x10 != 0 {
|
||||
bs.DataAdvise(int64(offset), int64(length), util.POSIX_FADV_WILLNEED)
|
||||
|
||||
@@ -19,12 +19,16 @@ package pool
|
||||
|
||||
import "sync"
|
||||
|
||||
var bytePool sync.Pool = sync.Pool{}
|
||||
|
||||
func NewBuffer(size int) []byte {
|
||||
var bytePool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return make([]byte, size)
|
||||
},
|
||||
bytePool.New = func() interface{} {
|
||||
return make([]byte, size)
|
||||
}
|
||||
|
||||
return bytePool.Get().([]byte)
|
||||
}
|
||||
|
||||
func ReleaseBuffer(b []byte) {
|
||||
bytePool.Put(b)
|
||||
}
|
||||
|
||||
@@ -91,13 +91,14 @@ func MarshalUint32(i uint32) []byte {
|
||||
return data
|
||||
}
|
||||
|
||||
func MarshalUint64(i uint64) []byte {
|
||||
var data []byte
|
||||
func MarshalUint64(v uint64) []byte {
|
||||
var data = [8]byte{}
|
||||
var i = 0
|
||||
for j := 56; j >= 0; j -= 8 {
|
||||
b := byte(i >> uint32(j))
|
||||
data = append(data, b)
|
||||
data[i] = byte(v >> uint32(j))
|
||||
i++
|
||||
}
|
||||
return data
|
||||
return data[0:8]
|
||||
}
|
||||
|
||||
func StringToByte(str string, align int, maxlength int) []byte {
|
||||
|
||||
Reference in New Issue
Block a user