Implement stats and resize and fix remote backing store apis

- Convert constant to var so that it can be configured from backend
- Add options to disable persistent reservation and ORWrite16 commands

Signed-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
This commit is contained in:
Utkarsh Mani Tripathi
2019-11-20 14:34:35 +05:30
parent d7caf89610
commit d7891b1f68
10 changed files with 190 additions and 50 deletions

View File

@@ -29,7 +29,7 @@ var (
)
func init() {
scsi.RegisterBackingStore("RemBs", newRemBs)
scsi.RegisterBackingStore("RemBs", NewRemoteBackingStore)
}
// RemBackingStore
@@ -40,7 +40,7 @@ type RemBackingStore struct {
RemBs api.RemoteBackingStore
}
func newRemBs() (api.BackingStore, error) {
func NewRemoteBackingStore() (api.BackingStore, error) {
return &RemBackingStore{
BaseBackingStore: scsi.BaseBackingStore{
Name: "RemBs",
@@ -53,9 +53,12 @@ func (bs *RemBackingStore) Open(dev *api.SCSILu, path string) error {
if Size == 0 {
return fmt.Errorf("Size is not initialized")
}
var err error
bs.DataSize = Size
bs.RemBs = scsi.GetTargetBSMap(path)
bs.RemBs, err = scsi.GetTargetBSMap(path)
if err != nil {
return err
}
return nil
}

View File

@@ -228,7 +228,7 @@ const (
NAA_IEEE_REGD_EXTD = byte(0x6)
)
const (
var (
SCSIVendorID = "GOSTOR"
SCSIProductID = "GOTGT"
SCSIID = "iqn.2016-09.com.gotgt.gostor:iscsi-tgt"

View File

@@ -28,6 +28,27 @@ type SCSITargetDriver interface {
NewTarget(string, *config.Config) error
RereadTargetLUNMap()
Close() error
Resize(uint64) error
Stats() Stats
}
type Stats struct {
IsClientConnected bool
RevisionCounter int64
ReplicaCounter int64
SCSIIOCount map[int]int64
ReadIOPS int64
TotalReadTime int64
TotalReadBlockCount int64
WriteIOPS int64
TotalWriteTime int64
TotalWriteBlockCount int64
UsedLogicalBlocks int64
UsedBlocks int64
SectorSize int64
}
type TargetDriverFunc func(*SCSITargetService) (SCSITargetDriver, error)

View File

@@ -37,6 +37,11 @@ const (
PR_EA_FN = (1 << 0)
)
var (
EnableORWrite16 = true
EnablePersistentReservation = true
)
type SBCSCSIDeviceProtocol struct {
BaseSCSIDeviceProtocol
}
@@ -176,26 +181,29 @@ func NewSBCDevice(deviceType api.SCSIDeviceType) api.SCSIDeviceProtocol {
sbc.SCSIDeviceOps[api.MODE_SELECT_10] = NewSCSIDeviceOperation(SBCModeSelect, nil, PR_WE_FA|PR_EA_FA|PR_EA_FN|PR_WE_FN)
sbc.SCSIDeviceOps[api.MODE_SENSE_10] = NewSCSIDeviceOperation(SBCModeSense, nil, PR_WE_FA|PR_WE_FN|PR_EA_FA|PR_EA_FN)
sbc.SCSIDeviceOps[api.PERSISTENT_RESERVE_IN] = NewSCSIDeviceOperation(SPCServiceAction, []*SCSIServiceAction{
{ServiceAction: PR_IN_READ_KEYS, CommandPerformFunc: SPCPRReadKeys},
{ServiceAction: PR_IN_READ_RESERVATION, CommandPerformFunc: SPCPRReadReservation},
{ServiceAction: PR_IN_REPORT_CAPABILITIES, CommandPerformFunc: SPCPRReportCapabilities},
}, 0)
sbc.SCSIDeviceOps[api.PERSISTENT_RESERVE_OUT] = NewSCSIDeviceOperation(SPCServiceAction, []*SCSIServiceAction{
{ServiceAction: PR_OUT_REGISTER, CommandPerformFunc: SPCPRRegister},
{ServiceAction: PR_OUT_RESERVE, CommandPerformFunc: SPCPRReserve},
{ServiceAction: PR_OUT_RELEASE, CommandPerformFunc: SPCPRRelease},
{ServiceAction: PR_OUT_CLEAR, CommandPerformFunc: SPCPRClear},
{ServiceAction: PR_OUT_PREEMPT, CommandPerformFunc: SPCPRPreempt},
// {ServiceAction: PR_OUT_PREEMPT_AND_ABORT, CommandPerformFunc: SPCPRPreempt},
{ServiceAction: PR_OUT_REGISTER_AND_IGNORE_EXISTING_KEY, CommandPerformFunc: SPCPRRegister},
{ServiceAction: PR_OUT_REGISTER_AND_MOVE, CommandPerformFunc: SPCPRRegisterAndMove},
}, 0)
if EnablePersistentReservation {
sbc.SCSIDeviceOps[api.PERSISTENT_RESERVE_IN] = NewSCSIDeviceOperation(SPCServiceAction, []*SCSIServiceAction{
{ServiceAction: PR_IN_READ_KEYS, CommandPerformFunc: SPCPRReadKeys},
{ServiceAction: PR_IN_READ_RESERVATION, CommandPerformFunc: SPCPRReadReservation},
{ServiceAction: PR_IN_REPORT_CAPABILITIES, CommandPerformFunc: SPCPRReportCapabilities},
}, 0)
sbc.SCSIDeviceOps[api.PERSISTENT_RESERVE_OUT] = NewSCSIDeviceOperation(SPCServiceAction, []*SCSIServiceAction{
{ServiceAction: PR_OUT_REGISTER, CommandPerformFunc: SPCPRRegister},
{ServiceAction: PR_OUT_RESERVE, CommandPerformFunc: SPCPRReserve},
{ServiceAction: PR_OUT_RELEASE, CommandPerformFunc: SPCPRRelease},
{ServiceAction: PR_OUT_CLEAR, CommandPerformFunc: SPCPRClear},
{ServiceAction: PR_OUT_PREEMPT, CommandPerformFunc: SPCPRPreempt},
// {ServiceAction: PR_OUT_PREEMPT_AND_ABORT, CommandPerformFunc: SPCPRPreempt},
{ServiceAction: PR_OUT_REGISTER_AND_IGNORE_EXISTING_KEY, CommandPerformFunc: SPCPRRegister},
{ServiceAction: PR_OUT_REGISTER_AND_MOVE, CommandPerformFunc: SPCPRRegisterAndMove},
}, 0)
}
sbc.SCSIDeviceOps[api.READ_16] = NewSCSIDeviceOperation(SBCReadWrite, nil, PR_EA_FA|PR_EA_FN)
sbc.SCSIDeviceOps[api.WRITE_16] = NewSCSIDeviceOperation(SBCReadWrite, nil, PR_EA_FA|PR_EA_FN|PR_WE_FA|PR_WE_FN)
sbc.SCSIDeviceOps[api.ORWRITE_16] = NewSCSIDeviceOperation(SBCReadWrite, nil, PR_EA_FA|PR_EA_FN)
if EnableORWrite16 {
sbc.SCSIDeviceOps[api.ORWRITE_16] = NewSCSIDeviceOperation(SBCReadWrite, nil, PR_EA_FA|PR_EA_FN)
}
sbc.SCSIDeviceOps[api.WRITE_VERIFY_16] = NewSCSIDeviceOperation(SBCReadWrite, nil, PR_EA_FA|PR_EA_FN)
sbc.SCSIDeviceOps[api.VERIFY_16] = NewSCSIDeviceOperation(SBCVerify, nil, PR_EA_FA|PR_EA_FN)

View File

@@ -53,6 +53,20 @@ func (s *SCSITargetService) GetTargetList() ([]api.SCSITarget, error) {
return result, nil
}
func (s *SCSITargetService) Resize(size uint64) error {
s.mutex.Lock()
//TODO for multiple LUNs
for _, t := range s.Targets {
if t.Devices != nil {
for i := range t.Devices {
t.Devices[i].Size = size
}
}
}
s.mutex.Unlock()
return nil
}
func (s *SCSITargetService) AddCommandQueue(tid int, scmd *api.SCSICommand) error {
var (
target *api.SCSITarget
@@ -128,9 +142,18 @@ func NewSCSIDeviceOperation(fn api.CommandFunc, sa []*SCSIServiceAction, pr uint
func BuildSenseData(cmd *api.SCSICommand, key byte, asc SCSISubError) {
senseBuffer := &bytes.Buffer{}
inBufLen, ok := SCSICDBBufXLength(cmd.SCB)
var length uint32 = 0xa
var (
length uint32 = 0xa
fixedFormat bool = true
)
if cmd.Device.Attrs.SenseFormat {
if cmd.Device != nil {
if cmd.Device.Attrs.SenseFormat {
fixedFormat = false
}
}
if !fixedFormat {
// descriptor format
// current, not deferred
senseBuffer.WriteByte(0x72)

View File

@@ -78,13 +78,16 @@ func GetTargetLUNMap(tgtName string) api.LUNMap {
return lunMap
}
func GetTargetBSMap(tgtName string) api.RemoteBackingStore {
/* TODO check for lock held by caller
func GetTargetBSMap(tgtName string) (api.RemoteBackingStore, error) {
globalSCSILUMap.mutex.RLock()
defer globalSCSILUMap.mutex.RUnlock()*/
defer globalSCSILUMap.mutex.RUnlock()
lunMap := globalSCSILUMap.TargetsBSMap[tgtName]
return lunMap
bs, ok := globalSCSILUMap.TargetsBSMap[tgtName]
if !ok {
return nil, errors.New("Remote backing store is not found in globalSCSILUMap")
}
return bs, nil
}
func AddBackendStorage(bs config.BackendStorage) error {
@@ -148,19 +151,22 @@ func InitSCSILUMap(config *config.Config) error {
}
func InitSCSILUMapEx(config *config.BackendStorage, tgtName string, lun uint64, bs api.RemoteBackingStore) error {
globalSCSILUMap.mutex.Lock()
defer globalSCSILUMap.mutex.Unlock()
if bs == nil {
return errors.New("Remote backing store is nil")
}
globalSCSILUMap.mutex.Lock()
globalSCSILUMap.TargetsBSMap[tgtName] = bs
globalSCSILUMap.mutex.Unlock()
lu, err := NewSCSILu(config)
if err != nil {
return errors.New("Init SCSI LU map error.")
return fmt.Errorf("Init SCSI LU map error, err: %v", err)
}
globalSCSILUMap.mutex.Lock()
globalSCSILUMap.AllDevices[config.DeviceID] = lu
globalSCSILUMap.mutex.Unlock()
mappingLUN(LUNMapping{
DeviceID: config.DeviceID,