[VOL-3930] Using a shared lock for Resource acquisition and release
Change-Id: Ic93588ab944ef912d417e9334d56b833b46a3f26
diff --git a/VERSION b/VERSION
index ee74734..627a3f4 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-4.1.0
+4.1.1
diff --git a/pkg/ponresourcemanager/ponresourcemanager.go b/pkg/ponresourcemanager/ponresourcemanager.go
index 415ce21..70ed8e6 100755
--- a/pkg/ponresourcemanager/ponresourcemanager.go
+++ b/pkg/ponresourcemanager/ponresourcemanager.go
@@ -703,6 +703,13 @@
:return list/uint32/None: list, uint32 or None if resource type is
alloc_id/gemport_id, onu_id or invalid type respectively
*/
+
+ logger.Debugw(ctx, "getting-resource-id", log.Fields{
+ "intf-id": IntfID,
+ "resource-type": ResourceType,
+ "num": NumIDs,
+ })
+
if NumIDs < 1 {
logger.Error(ctx, "Invalid number of resources requested")
return nil, fmt.Errorf("Invalid number of resources requested %d", NumIDs)
@@ -771,21 +778,30 @@
return false
}
-func (PONRMgr *PONResourceManager) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) bool {
+func (PONRMgr *PONResourceManager) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) error {
/*
- Release alloc/gemport/onu/flow id for given OLT PON interface.
- :param pon_intf_id: OLT PON interface id
- :param resource_type: String to identify type of resource
- :param release_content: required number of ids
- :return boolean: True if all IDs in given release_content release else False
+ Release alloc/gemport/onu/flow id for given OLT PON interface.
+ :param pon_intf_id: OLT PON interface id
+ :param resource_type: String to identify type of resource
+ :param release_content: required number of ids
+ :return boolean: True if all IDs in given release_content release else False
*/
+
+ logger.Debugw(ctx, "freeing-resource-id", log.Fields{
+ "intf-id": IntfID,
+ "resource-type": ResourceType,
+ "release-content": ReleaseContent,
+ })
+
if !checkValidResourceType(ResourceType) {
- logger.Error(ctx, "Invalid resource type")
- return false
+ err := fmt.Errorf("Invalid resource type: %s", ResourceType)
+ logger.Error(ctx, err.Error())
+ return err
}
if ReleaseContent == nil {
- logger.Debug(ctx, "Nothing to release")
- return true
+ err := fmt.Errorf("Nothing to release")
+ logger.Debug(ctx, err.Error())
+ return err
}
// delegate to the master instance if sharing enabled across instances
SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
@@ -794,22 +810,24 @@
}
Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
if Path == "" {
- logger.Error(ctx, "Failed to get path")
- return false
+ err := fmt.Errorf("Failed to get path for IntfId %d and ResourceType %s", IntfID, ResourceType)
+ logger.Error(ctx, err.Error())
+ return err
}
Resource, err := PONRMgr.GetResource(ctx, Path)
if err != nil {
- logger.Error(ctx, "Failed to get resource")
- return false
+ logger.Error(ctx, err.Error())
+ return err
}
for _, Val := range ReleaseContent {
PONRMgr.ReleaseID(ctx, Resource, Val)
}
if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
- logger.Errorf(ctx, "Free resource for %s failed", Path)
- return false
+ err := fmt.Errorf("Free resource for %s failed", Path)
+ logger.Errorf(ctx, err.Error())
+ return err
}
- return true
+ return nil
}
func (PONRMgr *PONResourceManager) UpdateResource(ctx context.Context, Path string, Resource map[string]interface{}) error {
@@ -1258,6 +1276,10 @@
return GEMPORT_ID
}
+func (PONRMgr *PONResourceManager) GetResourceTypeOnuID() string {
+ return ONU_ID
+}
+
// ToByte converts an interface value to a []byte. The interface should either be of
// a string type or []byte. Otherwise, an error is returned.
func ToByte(value interface{}) ([]byte, error) {
diff --git a/pkg/techprofile/tech_profile.go b/pkg/techprofile/tech_profile.go
index 5cb5a2e..0f2741f 100644
--- a/pkg/techprofile/tech_profile.go
+++ b/pkg/techprofile/tech_profile.go
@@ -36,8 +36,10 @@
// Interface to pon resource manager APIs
type iPonResourceMgr interface {
GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error)
+ FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) error
GetResourceTypeAllocID() string
GetResourceTypeGemPortID() string
+ GetResourceTypeOnuID() string
GetTechnology() string
}
@@ -221,6 +223,7 @@
type TechProfileMgr struct {
config *TechProfileFlags
resourceMgr iPonResourceMgr
+ OnuIDMgmtLock sync.RWMutex
GemPortIDMgmtLock sync.RWMutex
AllocIDMgmtLock sync.RWMutex
}
@@ -659,9 +662,7 @@
logger.Infow(ctx, "Allocating TechProfileMgr instance from techprofile template", log.Fields{"uniPortName": uniPortName, "intfId": intfId, "numGem": tp.NumGemPorts})
if tp.InstanceCtrl.Onu == "multi-instance" {
- t.AllocIDMgmtLock.Lock()
- tcontIDs, err = t.resourceMgr.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1)
- t.AllocIDMgmtLock.Unlock()
+ tcontIDs, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1)
if err != nil {
logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
return nil
@@ -673,9 +674,7 @@
} else if tpInst == nil {
// No "single-instance" tp found on one any uni port for the given TP ID
// Allocate a new TcontID or AllocID
- t.AllocIDMgmtLock.Lock()
- tcontIDs, err = t.resourceMgr.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1)
- t.AllocIDMgmtLock.Unlock()
+ tcontIDs, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1)
if err != nil {
logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
return nil
@@ -686,9 +685,7 @@
}
}
logger.Debugw(ctx, "Num GEM ports in TP:", log.Fields{"NumGemPorts": tp.NumGemPorts})
- t.GemPortIDMgmtLock.Lock()
- gemPorts, err = t.resourceMgr.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeGemPortID(), tp.NumGemPorts)
- t.GemPortIDMgmtLock.Unlock()
+ gemPorts, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeGemPortID(), tp.NumGemPorts)
if err != nil {
logger.Errorw(ctx, "Error getting gemport ids from rsrcrMgr", log.Fields{"intfId": intfId, "numGemports": tp.NumGemPorts})
return nil
@@ -793,7 +790,7 @@
logger.Infow(ctx, "Allocating TechProfileMgr instance from techprofile template", log.Fields{"uniPortName": uniPortName, "intfId": intfId, "numGem": tp.NumGemPorts})
if tp.InstanceCtrl.Onu == "multi-instance" {
- if tcontIDs, err = t.resourceMgr.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1); err != nil {
+ if tcontIDs, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1); err != nil {
logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
return nil
}
@@ -804,7 +801,7 @@
} else if tpInst == nil {
// No "single-instance" tp found on one any uni port for the given TP ID
// Allocate a new TcontID or AllocID
- if tcontIDs, err = t.resourceMgr.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1); err != nil {
+ if tcontIDs, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1); err != nil {
logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
return nil
}
@@ -814,7 +811,7 @@
}
}
logger.Debugw(ctx, "Num GEM ports in TP:", log.Fields{"NumGemPorts": tp.NumGemPorts})
- if gemPorts, err = t.resourceMgr.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeGemPortID(), tp.NumGemPorts); err != nil {
+ if gemPorts, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeGemPortID(), tp.NumGemPorts); err != nil {
logger.Errorw(ctx, "Error getting gemport ids from rsrcrMgr", log.Fields{"intfId": intfId, "numGemports": tp.NumGemPorts})
return nil
}
@@ -1397,3 +1394,62 @@
}
return nil
}
+
+func (t *TechProfileMgr) GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error) {
+ logger.Debugw(ctx, "getting-resource-id", log.Fields{
+ "intf-id": IntfID,
+ "resource-type": ResourceType,
+ "num": NumIDs,
+ })
+ var err error
+ var ids []uint32
+ switch ResourceType {
+ case t.resourceMgr.GetResourceTypeAllocID():
+ t.AllocIDMgmtLock.Lock()
+ ids, err = t.resourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
+ t.AllocIDMgmtLock.Unlock()
+ case t.resourceMgr.GetResourceTypeGemPortID():
+ t.GemPortIDMgmtLock.Lock()
+ ids, err = t.resourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
+ t.GemPortIDMgmtLock.Unlock()
+ case t.resourceMgr.GetResourceTypeOnuID():
+ t.OnuIDMgmtLock.Lock()
+ ids, err = t.resourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
+ t.OnuIDMgmtLock.Unlock()
+ default:
+ return nil, fmt.Errorf("ResourceType %s not supported", ResourceType)
+ }
+ if err != nil {
+ return nil, err
+ }
+ return ids, nil
+}
+
+func (t *TechProfileMgr) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) error {
+ logger.Debugw(ctx, "freeing-resource-id", log.Fields{
+ "intf-id": IntfID,
+ "resource-type": ResourceType,
+ "release-content": ReleaseContent,
+ })
+ var err error
+ switch ResourceType {
+ case t.resourceMgr.GetResourceTypeAllocID():
+ t.AllocIDMgmtLock.Lock()
+ err = t.resourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
+ t.AllocIDMgmtLock.Unlock()
+ case t.resourceMgr.GetResourceTypeGemPortID():
+ t.GemPortIDMgmtLock.Lock()
+ err = t.resourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
+ t.GemPortIDMgmtLock.Unlock()
+ case t.resourceMgr.GetResourceTypeOnuID():
+ t.OnuIDMgmtLock.Lock()
+ err = t.resourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
+ t.OnuIDMgmtLock.Unlock()
+ default:
+ return fmt.Errorf("ResourceType %s not supported", ResourceType)
+ }
+ if err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/pkg/techprofile/tech_profile_if.go b/pkg/techprofile/tech_profile_if.go
index d3a79ce..84d84ee 100644
--- a/pkg/techprofile/tech_profile_if.go
+++ b/pkg/techprofile/tech_profile_if.go
@@ -38,4 +38,6 @@
GetMulticastTrafficQueues(ctx context.Context, tp *TechProfile) []*tp_pb.TrafficQueue
GetGemportForPbit(ctx context.Context, tp interface{}, Dir tp_pb.Direction, pbit uint32) interface{}
FindAllTpInstances(ctx context.Context, techProfiletblID uint32, ponIntf uint32, onuID uint32) interface{}
+ GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error)
+ FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) error
}