202 lines
4.1 KiB
Go
202 lines
4.1 KiB
Go
package mock
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/sirupsen/logrus"
|
|
|
|
"github.com/gostor/gotgt/pkg/api"
|
|
"github.com/gostor/gotgt/pkg/config" /* init lib */
|
|
"github.com/gostor/gotgt/pkg/port/iscsit"
|
|
"github.com/gostor/gotgt/pkg/scsi"
|
|
_ "github.com/gostor/gotgt/pkg/scsi/backingstore" /* init lib */
|
|
"github.com/gostor/gotgt/pkg/scsi/backingstore/remote"
|
|
)
|
|
|
|
type remoteBs struct {
|
|
Volume string
|
|
Size int64
|
|
SectorSize int
|
|
|
|
isUp bool
|
|
rw api.RemoteBackingStore
|
|
|
|
tgtName string
|
|
lhbsName string
|
|
clusterIP string
|
|
cfg *config.Config
|
|
targetDriver scsi.SCSITargetDriver
|
|
stats scsi.Stats
|
|
}
|
|
|
|
func (r *remoteBs) ReadAt(data []byte, size int64) (int, error) {
|
|
return 0, nil
|
|
}
|
|
|
|
func (r *remoteBs) WriteAt(data []byte, size int64) (int, error) {
|
|
return 0, nil
|
|
}
|
|
|
|
func (r *remoteBs) Sync() (int, error) {
|
|
return 0, nil
|
|
}
|
|
|
|
func (r *remoteBs) Unmap(bs int64, size int64) (int, error) {
|
|
return 0, nil
|
|
}
|
|
|
|
func initializeSCSITarget(size int64) {
|
|
iscsit.EnableStats = true
|
|
scsi.EnableORWrite16 = false
|
|
scsi.EnablePersistentReservation = false
|
|
scsi.EnableMultipath = false
|
|
remote.Size = uint64(size)
|
|
}
|
|
|
|
// Startup starts iscsi target server
|
|
func (r *remoteBs) Startup(name string, frontendIP string, clusterIP string, size, sectorSize int64) error {
|
|
initializeSCSITarget(size)
|
|
|
|
if frontendIP == "" {
|
|
host, _ := os.Hostname()
|
|
addrs, _ := net.LookupIP(host)
|
|
for _, addr := range addrs {
|
|
if ipv4 := addr.To4(); ipv4 != nil {
|
|
frontendIP = ipv4.String()
|
|
if frontendIP == "127.0.0.1" {
|
|
continue
|
|
}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
r.tgtName = "iqn.2016-09.com.gotgt.gostor:" + name
|
|
r.lhbsName = "RemBs:" + name
|
|
r.cfg = &config.Config{
|
|
Storages: []config.BackendStorage{
|
|
{
|
|
DeviceID: 1000,
|
|
Path: r.lhbsName,
|
|
Online: true,
|
|
},
|
|
},
|
|
ISCSIPortals: []config.ISCSIPortalInfo{
|
|
{
|
|
ID: 0,
|
|
Portal: frontendIP + ":3260",
|
|
},
|
|
},
|
|
ISCSITargets: map[string]config.ISCSITarget{
|
|
r.tgtName: {
|
|
TPGTs: map[string][]uint64{
|
|
"1": {0},
|
|
},
|
|
LUNs: map[string]uint64{
|
|
"1": uint64(1000),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
r.Volume = name
|
|
r.Size = size
|
|
r.SectorSize = int(sectorSize)
|
|
r.rw = r
|
|
r.clusterIP = clusterIP
|
|
logrus.Info("Start SCSI target")
|
|
if err := r.startScsiTarget(r.cfg); err != nil {
|
|
return err
|
|
}
|
|
|
|
r.isUp = true
|
|
|
|
return nil
|
|
}
|
|
|
|
// Shutdown stop scsi target
|
|
func (r *remoteBs) Shutdown() error {
|
|
if r.Volume != "" {
|
|
r.Volume = ""
|
|
}
|
|
|
|
if err := r.stopScsiTarget(); err != nil {
|
|
return fmt.Errorf("Failed to stop scsi target, err: %v", err)
|
|
}
|
|
r.isUp = false
|
|
|
|
return nil
|
|
}
|
|
|
|
// State provides info whether scsi target is up or down
|
|
func (r *remoteBs) State() string {
|
|
if r.isUp {
|
|
return "Up"
|
|
}
|
|
return "Down"
|
|
}
|
|
|
|
// Stats get target stats from the scsi target
|
|
func (r *remoteBs) Stats() scsi.Stats {
|
|
if !r.isUp {
|
|
return scsi.Stats{}
|
|
}
|
|
return r.targetDriver.Stats()
|
|
}
|
|
|
|
// Resize is called to resize the volume
|
|
func (r *remoteBs) Resize(size uint64) error {
|
|
if !r.isUp {
|
|
return fmt.Errorf("Volume is not up")
|
|
}
|
|
return r.targetDriver.Resize(size)
|
|
}
|
|
|
|
func (r *remoteBs) startScsiTarget(cfg *config.Config) error {
|
|
var err error
|
|
id := uuid.New()
|
|
uid := binary.BigEndian.Uint64(id[:8])
|
|
err = scsi.InitSCSILUMapEx(&config.BackendStorage{
|
|
DeviceID: uid,
|
|
Path: "RemBs:" + r.tgtName,
|
|
Online: true,
|
|
BlockShift: 9,
|
|
ThinProvisioning: true,
|
|
},
|
|
r.tgtName, uint64(0), r.rw)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
scsiTarget := scsi.NewSCSITargetService()
|
|
r.targetDriver, err = scsi.NewTargetDriver("iscsi", scsiTarget)
|
|
if err != nil {
|
|
logrus.Errorf("iscsi target driver error")
|
|
return err
|
|
}
|
|
r.targetDriver.NewTarget(r.tgtName, cfg)
|
|
//r.targetDriver.SetClusterIP(r.clusterIP)
|
|
go r.targetDriver.Run(3260)
|
|
// Wait here so that listener get started
|
|
time.Sleep(1 * time.Second)
|
|
|
|
logrus.Infof("SCSI device created")
|
|
return nil
|
|
}
|
|
|
|
func (r *remoteBs) stopScsiTarget() error {
|
|
if r.targetDriver == nil {
|
|
return nil
|
|
}
|
|
logrus.Infof("Stopping target %v ...", r.tgtName)
|
|
if err := r.targetDriver.Close(); err != nil {
|
|
return err
|
|
}
|
|
logrus.Infof("Target %v stopped", r.tgtName)
|
|
return nil
|
|
}
|