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 (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"io"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
uuid "github.com/satori/go.uuid"
|
uuid "github.com/satori/go.uuid"
|
||||||
@@ -406,3 +407,14 @@ type UnmapBlockDescriptor struct {
|
|||||||
Offset uint64
|
Offset uint64
|
||||||
TL uint32
|
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
|
package scsi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -33,9 +34,15 @@ type SCSILUMap struct {
|
|||||||
AllDevices api.LUNMap
|
AllDevices api.LUNMap
|
||||||
// use target name as the key for target's LUN map
|
// use target name as the key for target's LUN map
|
||||||
TargetsLUNMap map[string]api.LUNMap
|
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 {
|
type LUNMapping struct {
|
||||||
TargetName string
|
TargetName string
|
||||||
@@ -71,6 +78,15 @@ func GetTargetLUNMap(tgtName string) api.LUNMap {
|
|||||||
return 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 {
|
func AddBackendStorage(bs config.BackendStorage) error {
|
||||||
globalSCSILUMap.mutex.Lock()
|
globalSCSILUMap.mutex.Lock()
|
||||||
defer globalSCSILUMap.mutex.Unlock()
|
defer globalSCSILUMap.mutex.Unlock()
|
||||||
@@ -130,3 +146,33 @@ func InitSCSILUMap(config *config.Config) error {
|
|||||||
}
|
}
|
||||||
return nil
|
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