diff --git a/pkg/port/iscsit/iscsid.go b/pkg/port/iscsit/iscsid.go index fcfb0fc..6dc518f 100644 --- a/pkg/port/iscsit/iscsid.go +++ b/pkg/port/iscsit/iscsid.go @@ -42,6 +42,9 @@ type ISCSITargetDriver struct { iSCSITargets map[string]*ISCSITarget TSIHPool map[uint16]bool TSIHPoolMutex sync.Mutex + + mu sync.Mutex + l net.Listener } func init() { @@ -103,6 +106,10 @@ func (s *ISCSITargetDriver) NewTarget(tgtName string, configInfo *config.Config) return nil } +func (s *ISCSITargetDriver) RereadTargetLUNMap() { + s.SCSI.RereadTargetLUNMap() +} + func (s *ISCSITargetDriver) AddiSCSIPortal(tgtName string, tpgt uint16, portal string) error { var ( ok bool @@ -156,11 +163,20 @@ func (s *ISCSITargetDriver) Run() error { log.Error(err) os.Exit(1) } + s.mu.Lock() + s.l = l + s.mu.Unlock() for { log.Info("Listening ...") conn, err := l.Accept() if err != nil { + if err, ok := err.(net.Error); ok { + if !err.Temporary() { + log.Info("Closing ...") + break + } + } log.Error(err) continue } @@ -177,7 +193,16 @@ func (s *ISCSITargetDriver) Run() error { // start a new thread to do with this command go s.handler(DATAIN, iscsiConn) } - l.Close() + return nil +} + +func (s *ISCSITargetDriver) Close() error { + s.mu.Lock() + l := s.l + s.mu.Unlock() + if l != nil { + return l.Close() + } return nil } diff --git a/pkg/scsi/drivers.go b/pkg/scsi/drivers.go index 5517ad1..0571f91 100644 --- a/pkg/scsi/drivers.go +++ b/pkg/scsi/drivers.go @@ -26,6 +26,8 @@ import ( type SCSITargetDriver interface { Run() error NewTarget(string, *config.Config) error + RereadTargetLUNMap() + Close() error } type TargetDriverFunc func(*SCSITargetService) (SCSITargetDriver, error) diff --git a/pkg/scsi/scsilumap.go b/pkg/scsi/scsilumap.go index a968eef..b6106cc 100644 --- a/pkg/scsi/scsilumap.go +++ b/pkg/scsi/scsilumap.go @@ -37,15 +37,20 @@ type SCSILUMap struct { var globalSCSILUMap = SCSILUMap{AllDevices: make(api.LUNMap), TargetsLUNMap: make(map[string]api.LUNMap)} -func mappingLUN(deviceID uint64, lun uint64, target string) { +type LUNMapping struct { + TargetName string + LUN uint64 + DeviceID uint64 +} - device := globalSCSILUMap.AllDevices[deviceID] - lunMap := globalSCSILUMap.TargetsLUNMap[target] +func mappingLUN(lm LUNMapping) { + device := globalSCSILUMap.AllDevices[lm.DeviceID] + lunMap := globalSCSILUMap.TargetsLUNMap[lm.TargetName] if lunMap == nil { - globalSCSILUMap.TargetsLUNMap[target] = make(api.LUNMap) - lunMap = globalSCSILUMap.TargetsLUNMap[target] + globalSCSILUMap.TargetsLUNMap[lm.TargetName] = make(api.LUNMap) + lunMap = globalSCSILUMap.TargetsLUNMap[lm.TargetName] } - lunMap[lun] = device + lunMap[lm.LUN] = device } func GetLU(tgtName string, LUN uint64) *api.SCSILu { @@ -66,18 +71,51 @@ func GetTargetLUNMap(tgtName string) api.LUNMap { return lunMap } -func InitSCSILUMap(config *config.Config) error { - var simpleOp *SCSISimpleReservationOperator - var ok bool +func AddBackendStorage(bs config.BackendStorage) error { globalSCSILUMap.mutex.Lock() defer globalSCSILUMap.mutex.Unlock() + _, ok := globalSCSILUMap.AllDevices[bs.DeviceID] + if ok { + return fmt.Errorf("device %q already exists", bs.DeviceID) + } + lu, err := NewSCSILu(&bs) + if err != nil { + return fmt.Errorf("Init SCSI LU map error: %v", err) + } + globalSCSILUMap.AllDevices[bs.DeviceID] = lu + return nil +} + +func DelBackendStorage(deviceID uint64) { + globalSCSILUMap.mutex.Lock() + defer globalSCSILUMap.mutex.Unlock() + delete(globalSCSILUMap.AllDevices, deviceID) +} + +func AddLUNMapping(m LUNMapping) error { + globalSCSILUMap.mutex.Lock() + defer globalSCSILUMap.mutex.Unlock() + mappingLUN(m) + // Init SCSISimpleReservationOperator + op := GetSCSIReservationOperator() + if simpleOp, ok := op.(*SCSISimpleReservationOperator); ok { + simpleOp.InitLUReservation(m.TargetName, m.DeviceID) + } + return nil +} + +func DelLUNMapping(m LUNMapping) { + globalSCSILUMap.mutex.Lock() + defer globalSCSILUMap.mutex.Unlock() + delete(globalSCSILUMap.TargetsLUNMap[m.TargetName], m.LUN) +} + +func InitSCSILUMap(config *config.Config) error { for _, bs := range config.Storages { - lu, err := NewSCSILu(&bs) - if err != nil { - return fmt.Errorf("Init SCSI LU map error: %v", err) + if err := AddBackendStorage(bs); err != nil { + return err } - globalSCSILUMap.AllDevices[bs.DeviceID] = lu } for tgtName, tgt := range config.ISCSITargets { @@ -86,12 +124,8 @@ func InitSCSILUMap(config *config.Config) error { if err != nil { return fmt.Errorf("LU Number must be a number") } - mappingLUN(deviceID, lun, tgtName) - // Init SCSISimpleReservationOperator - op := GetSCSIReservationOperator() - if simpleOp, ok = op.(*SCSISimpleReservationOperator); ok { - simpleOp.InitLUReservation(tgtName, deviceID) - } + m := LUNMapping{DeviceID: deviceID, LUN: lun, TargetName: tgtName} + AddLUNMapping(m) } } return nil diff --git a/pkg/scsi/target.go b/pkg/scsi/target.go index 0fc0a8d..3f12696 100644 --- a/pkg/scsi/target.go +++ b/pkg/scsi/target.go @@ -45,6 +45,15 @@ func (s *SCSITargetService) NewSCSITarget(tid int, driverName, name string) (*ap return target, nil } +func (s *SCSITargetService) RereadTargetLUNMap() { + s.mutex.Lock() + defer s.mutex.Unlock() + + for _, tgt := range s.Targets { + tgt.Devices = GetTargetLUNMap(tgt.Name) + } +} + func FindTargetGroup(target *api.SCSITarget, relPortID uint16) uint16 { for _, tpg := range target.TargetPortGroups { for _, port := range tpg.TargetPortGroup {