fix bugs and make it run basically

This commit is contained in:
Lei Xue
2016-08-27 20:07:51 +08:00
parent f97ab027de
commit aedc09021f
22 changed files with 1997 additions and 431 deletions

View File

@@ -16,17 +16,82 @@ limitations under the License.
package scsi
import "github.com/gostor/gotgt/pkg/api"
import (
"bytes"
"encoding/binary"
"fmt"
"sync"
type CommandFunc func(host int, cmd *api.SCSICommand) api.SAMStat
"github.com/golang/glog"
"github.com/gostor/gotgt/pkg/api"
)
type SCSITargetService struct {
mutex sync.RWMutex
Targets []*api.SCSITarget
}
var _instance *SCSITargetService
func NewSCSITargetService() *SCSITargetService {
if _instance == nil {
_instance = &SCSITargetService{Targets: []*api.SCSITarget{}}
}
return _instance
}
func (s *SCSITargetService) GetTargetList() ([]api.SCSITarget, error) {
result := []api.SCSITarget{}
s.mutex.RLock()
for _, t := range s.Targets {
result = append(result, *t)
}
s.mutex.RUnlock()
return result, nil
}
func (s *SCSITargetService) AddCommandQueue(tid int, scmd *api.SCSICommand) error {
var (
target *api.SCSITarget
itn *api.ITNexus
)
s.mutex.RLock()
for _, t := range s.Targets {
if t.TID == tid {
target = t
break
}
}
s.mutex.RUnlock()
if target == nil {
return fmt.Errorf("Cannot find the target with ID(%d)", tid)
}
scmd.Target = target
for _, it := range target.ITNexus {
if it.ID == scmd.CommandITNID {
itn = it
break
}
}
scmd.ITNexus = itn
scmd.Device = target.Devices[0]
result := scmd.Device.PerformCommand(tid, scmd)
scmd.Result = result.Stat
if result.Err != nil {
glog.Error(result.Err)
return result.Err
}
return nil
}
type SCSIServiceAction struct {
ServiceAction uint32
CommandPerformFunc CommandFunc
CommandPerformFunc api.CommandFunc
}
type SCSIDeviceOperation struct {
CommandPerformFunc CommandFunc
CommandPerformFunc api.CommandFunc
ServiceAction *SCSIServiceAction
PRConflictBits uint8
}
@@ -36,15 +101,7 @@ type BaseSCSIDeviceProtocol struct {
SCSIDeviceOps []SCSIDeviceOperation
}
type SCSIDeviceProtocol interface {
InitLu(lu *api.SCSILu) error
ExitLu(lu *api.SCSILu) error
ConfigLu(lu *api.SCSILu) error
OnlineLu(lu *api.SCSILu) error
OfflineLu(lu *api.SCSILu) error
}
func NewSCSIDeviceOperation(fn CommandFunc, sa *SCSIServiceAction, pr uint8) SCSIDeviceOperation {
func NewSCSIDeviceOperation(fn api.CommandFunc, sa *SCSIServiceAction, pr uint8) SCSIDeviceOperation {
return SCSIDeviceOperation{
CommandPerformFunc: fn,
ServiceAction: sa,
@@ -54,6 +111,9 @@ func NewSCSIDeviceOperation(fn CommandFunc, sa *SCSIServiceAction, pr uint8) SCS
func BuildSenseData(cmd *api.SCSICommand, key byte, asc SCSISubError) {
senseBuffer := cmd.SenseBuffer
if senseBuffer == nil {
senseBuffer = &bytes.Buffer{}
}
if cmd.Device.Attrs.SenseFormat {
// descriptor format
// current, not deferred
@@ -81,3 +141,44 @@ func BuildSenseData(cmd *api.SCSICommand, key byte, asc SCSISubError) {
cmd.SenseLength = length + 8
}
}
func getSCSIReadWriteOffset(scb []byte) uint64 {
var off uint64
var opcode = api.SCSICommandType(scb[0])
switch opcode {
case api.READ_6, api.WRITE_6:
off = uint64((scb[1]&0x1f))<<16 + uint64(scb[2])<<8 + uint64(scb[3])
case api.READ_10, api.PRE_FETCH_10, api.WRITE_10, api.VERIFY_10, api.WRITE_VERIFY, api.WRITE_SAME, api.SYNCHRONIZE_CACHE, api.READ_12, api.WRITE_12, api.VERIFY_12, api.WRITE_VERIFY_12:
off = uint64(binary.BigEndian.Uint32(scb[2:]))
case api.READ_16, api.PRE_FETCH_16, api.WRITE_16, api.ORWRITE_16, api.VERIFY_16, api.WRITE_VERIFY_16, api.WRITE_SAME_16, api.SYNCHRONIZE_CACHE_16, api.COMPARE_AND_WRITE:
off = binary.BigEndian.Uint64(scb[2:])
default:
}
return off
}
func getSCSIReadWriteCount(scb []byte) uint32 {
var cnt uint32
var opcode = api.SCSICommandType(scb[0])
switch opcode {
case api.READ_6, api.WRITE_6:
cnt = uint32(scb[4])
if cnt == 0 {
cnt = 256
}
case api.READ_10, api.PRE_FETCH_10, api.WRITE_10, api.VERIFY_10, api.WRITE_VERIFY, api.WRITE_SAME, api.SYNCHRONIZE_CACHE:
cnt = uint32(scb[7])<<8 | uint32(scb[8])
case api.READ_12, api.WRITE_12, api.VERIFY_12, api.WRITE_VERIFY_12:
cnt = binary.BigEndian.Uint32(scb[6:])
case api.READ_16, api.PRE_FETCH_16, api.WRITE_16, api.ORWRITE_16, api.VERIFY_16, api.WRITE_VERIFY_16, api.WRITE_SAME_16, api.SYNCHRONIZE_CACHE_16:
cnt = binary.BigEndian.Uint32(scb[10:])
case api.COMPARE_AND_WRITE:
cnt = uint32(scb[13])
default:
}
return cnt
}