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:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user