fix bugs and make it run basically
This commit is contained in:
127
pkg/scsi/scsi.go
127
pkg/scsi/scsi.go
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user