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