add initial implementation of remote backing store
This commit implement the BackingStore Interface for remote backing store. Signed-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
This commit is contained in:
@@ -17,6 +17,7 @@ package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
uuid "github.com/satori/go.uuid"
|
||||
@@ -406,3 +407,14 @@ type UnmapBlockDescriptor struct {
|
||||
Offset uint64
|
||||
TL uint32
|
||||
}
|
||||
|
||||
type ReaderWriterAt interface {
|
||||
io.ReaderAt
|
||||
io.WriterAt
|
||||
}
|
||||
|
||||
type RemoteBackingStore interface {
|
||||
ReaderWriterAt
|
||||
Sync() (int, error)
|
||||
Unmap(int64, int64) (int, error)
|
||||
}
|
||||
|
||||
107
pkg/scsi/backingstore/remote/remote.go
Normal file
107
pkg/scsi/backingstore/remote/remote.go
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
Copyright 2016 openebs authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package remote
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gostor/gotgt/pkg/api"
|
||||
"github.com/gostor/gotgt/pkg/scsi"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
scsi.RegisterBackingStore("RemBs", newRemBs)
|
||||
}
|
||||
|
||||
// RemBackingStore
|
||||
type RemBackingStore struct {
|
||||
scsi.BaseBackingStore
|
||||
// Remote backing store, remote server exposing
|
||||
// read and write methods.
|
||||
RemBs api.RemBackingStore
|
||||
}
|
||||
|
||||
func newRemBs() (api.BackingStore, error) {
|
||||
return &RemBackingStore{
|
||||
BaseBackingStore: scsi.BaseBackingStore{
|
||||
Name: "RemBs",
|
||||
OflagsSupported: 0,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (bs *RemBackingStore) Open(dev *api.SCSILu, path string) error {
|
||||
bs.DataSize = uint64(dev.Size)
|
||||
bs.RemBs = scsi.GetTargetBSMap(path)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bs *RemBackingStore) Close(dev *api.SCSILu) error {
|
||||
/* TODO return bs.File.Close()*/
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bs *RemBackingStore) Init(dev *api.SCSILu, Opts string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bs *RemBackingStore) Exit(dev *api.SCSILu) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bs *RemBackingStore) Size(dev *api.SCSILu) uint64 {
|
||||
return bs.DataSize
|
||||
}
|
||||
|
||||
func (bs *RemBackingStore) Read(offset, tl int64) ([]byte, error) {
|
||||
tmpbuf := make([]byte, tl)
|
||||
length, err := bs.RemBs.ReadAt(tmpbuf, offset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if length != len(tmpbuf) {
|
||||
return nil, fmt.Errorf("Incomplete read expected:%d actual:%d", tl, length)
|
||||
}
|
||||
return tmpbuf, nil
|
||||
}
|
||||
|
||||
func (bs *RemBackingStore) Write(wbuf []byte, offset int64) error {
|
||||
length, err := bs.RemBs.WriteAt(wbuf, offset)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
if length != len(wbuf) {
|
||||
return fmt.Errorf("Incomplete write expected:%d actual:%d", len(wbuf), length)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bs *RemBackingStore) DataAdvise(offset, length int64, advise uint32) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bs *RemBackingStore) DataSync(offset, length int64) (err error) {
|
||||
_, err = bs.RemBs.Sync()
|
||||
return
|
||||
}
|
||||
|
||||
func (bs *RemBackingStore) Unmap(bd []api.UnmapBlockDescriptor) (err error) {
|
||||
_, err = bs.RemBs.Unmap()
|
||||
return
|
||||
}
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package scsi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"sync"
|
||||
@@ -33,9 +34,15 @@ type SCSILUMap struct {
|
||||
AllDevices api.LUNMap
|
||||
// use target name as the key for target's LUN map
|
||||
TargetsLUNMap map[string]api.LUNMap
|
||||
|
||||
TargetsBSMap map[string]api.RemoteBackingStore /* use target name as the key for target's Backing Store (temp) */
|
||||
}
|
||||
|
||||
var globalSCSILUMap = SCSILUMap{AllDevices: make(api.LUNMap), TargetsLUNMap: make(map[string]api.LUNMap)}
|
||||
var globalSCSILUMap = SCSILUMap{
|
||||
AllDevices: make(api.LUNMap),
|
||||
TargetsLUNMap: make(map[string]api.LUNMap),
|
||||
TargetsBSMap: make(map[string]api.RemoteBackingStore),
|
||||
}
|
||||
|
||||
type LUNMapping struct {
|
||||
TargetName string
|
||||
@@ -71,6 +78,15 @@ func GetTargetLUNMap(tgtName string) api.LUNMap {
|
||||
return lunMap
|
||||
}
|
||||
|
||||
func GetTargetBSMap(tgtName string) api.RemoteBackingStore {
|
||||
/* TODO check for lock held by caller
|
||||
globalSCSILUMap.mutex.RLock()
|
||||
defer globalSCSILUMap.mutex.RUnlock()*/
|
||||
|
||||
lunMap := globalSCSILUMap.TargetsBSMap[tgtName]
|
||||
return lunMap
|
||||
}
|
||||
|
||||
func AddBackendStorage(bs config.BackendStorage) error {
|
||||
globalSCSILUMap.mutex.Lock()
|
||||
defer globalSCSILUMap.mutex.Unlock()
|
||||
@@ -130,3 +146,33 @@ func InitSCSILUMap(config *config.Config) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func InitSCSILUMapEx(tgtName, devpath string, deviceID, lun, size, sectorSize uint64, bs api.RemoteBackingStore) error {
|
||||
globalSCSILUMap.mutex.Lock()
|
||||
defer globalSCSILUMap.mutex.Unlock()
|
||||
|
||||
if bs == nil {
|
||||
return errors.New("Remote backing store is nil")
|
||||
}
|
||||
|
||||
globalSCSILUMap.TargetsBSMap[tgtName] = bs
|
||||
|
||||
lu, err := NewSCSILu(&config.BackendStorage{
|
||||
DeviceID: deviceID,
|
||||
Path: "RemBs:" + devpath,
|
||||
Online: true,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return errors.New("Init SCSI LU map error.")
|
||||
}
|
||||
globalSCSILUMap.AllDevices[deviceID] = lu
|
||||
|
||||
mappingLUN(LUNMapping{
|
||||
DeviceID: deviceID,
|
||||
LUN: lun,
|
||||
TargetName: tgtName,
|
||||
},
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user