blob: bfadf5f9d138f1694b9b3adee8b10ede5ff2ee8a [file] [log] [blame]
/*
* Copyright 2019-present Open Networking Foundation
* 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 resourcemanager provides the utility for managing resources
package core
import (
"github.com/opencord/voltha-lib-go/v7/pkg/log"
ponrmgr "github.com/opencord/voltha-lib-go/v7/pkg/ponresourcemanager"
"github.com/opencord/voltha-lib-go/v7/pkg/techprofile"
"github.com/opencord/voltha-protos/v5/go/openolt"
"golang.org/x/net/context"
"sync"
)
const (
basePathKvStore = "service/voltha"
)
// OpenOltResourceMgr holds resource related information as provided below for each field
type OpenOltResourceMgr struct {
deviceInfo *openolt.DeviceInfo
intfID uint32 // pon interface id
// array of pon resource managers per interface technology
PonRsrMgr *ponrmgr.PONResourceManager
TechprofileRef techprofile.TechProfileIf
FlowIDMgmtLock sync.RWMutex
flow_id uint64
}
// NewResourceMgr init a New resource manager instance which in turn instantiates pon resource manager
// instances according to technology. Initializes the default resource ranges for all
// the resources.
func NewResourceMgr(deviceID string, KVStoreHostPort string, kvStoreType string, deviceType string, ponID uint32, devInfo *openolt.DeviceInfo) *OpenOltResourceMgr {
var ResourceMgr OpenOltResourceMgr
logger.Debugf(nil, "Init new resource manager")
ResourceMgr.deviceInfo = devInfo
ResourceMgr.intfID = ponID
ctx := context.Background()
newCtx := context.WithValue(ctx, "ponIf", ponID)
// Create a separate Resource Manager instance for each range. This assumes that
// each technology is represented by only a single range
for _, TechRange := range devInfo.Ranges {
for _, intfID := range TechRange.IntfIds {
if intfID == ponID {
technology := TechRange.Technology
logger.Debugf(context.Background(), "Device info technology %s, intf-id %v", technology, ponID)
rsrMgr, err := ponrmgr.NewPONResourceManager(newCtx, technology, deviceType, deviceID,
kvStoreType, KVStoreHostPort, basePathKvStore)
if err != nil {
logger.Errorf(context.Background(), "Failed to create pon resource manager instance for technology %s", technology)
return nil
}
ResourceMgr.PonRsrMgr = rsrMgr
// self.initialize_device_resource_range_and_pool(resource_mgr, global_resource_mgr, arange)
InitializeDeviceResourceRangeAndPool(rsrMgr, TechRange, devInfo)
if err := ResourceMgr.PonRsrMgr.InitDeviceResourcePoolForIntf(context.Background(), intfID); err != nil {
logger.Fatal(context.Background(), "failed-to-initialize-device-resource-pool-intf-id-%v-device-id", ResourceMgr.intfID)
return nil
}
}
}
}
var err error
ResourceMgr.TechprofileRef, err = techprofile.NewTechProfile(newCtx, ResourceMgr.PonRsrMgr, ResourceMgr.PonRsrMgr.Backend,
ResourceMgr.PonRsrMgr.Address, basePathKvStore)
if err != nil || ResourceMgr.TechprofileRef == nil {
logger.Errorw(nil, "failed-to-allocate-to-techprofile-for-pon-port", log.Fields{"intfID": ponID, "err": err})
return nil
}
logger.Info(nil, "Initialization of resource manager success!")
return &ResourceMgr
}
// InitializeDeviceResourceRangeAndPool initializes the resource range pool according to the sharing type, then apply
// device specific information. If KV doesn't exist
// or is broader than the device, the device's information will
// dictate the range limits
func InitializeDeviceResourceRangeAndPool(ponRMgr *ponrmgr.PONResourceManager,
techRange *openolt.DeviceInfo_DeviceResourceRanges, devInfo *openolt.DeviceInfo) {
// var ONUIDShared, AllocIDShared, GEMPortIDShared openolt.DeviceInfo_DeviceResourceRanges_Pool_SharingType
var ONUIDStart, ONUIDEnd, AllocIDStart, AllocIDEnd, GEMPortIDStart, GEMPortIDEnd uint32
var ONUIDShared, AllocIDShared, GEMPortIDShared, FlowIDShared uint32
// The below variables are just dummy and needed to pass as arguments to InitDefaultPONResourceRanges function.
// The openolt adapter does not need flowIDs to be managed as it is managed on the OLT device
// The UNI IDs are dynamically generated by openonu adapter for every discovered UNI.
var flowIDDummyStart, flowIDDummyEnd uint32 = 1, 2
var uniIDDummyStart, uniIDDummyEnd uint32 = 0, 1
// init the resource range pool according to the sharing type
logger.Debugw(nil, "Device info init", log.Fields{"technology": techRange.Technology,
"onu_id_start": ONUIDStart, "onu_id_end": ONUIDEnd,
"alloc_id_start": AllocIDStart, "alloc_id_end": AllocIDEnd,
"gemport_id_start": GEMPortIDStart, "gemport_id_end": GEMPortIDEnd,
"intf_ids": techRange.IntfIds,
})
for _, RangePool := range techRange.Pools {
// FIXME: Remove hardcoding
if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ONU_ID {
ONUIDStart = RangePool.Start
ONUIDEnd = RangePool.End
ONUIDShared = uint32(RangePool.Sharing)
} else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ALLOC_ID {
AllocIDStart = RangePool.Start
AllocIDEnd = RangePool.End
AllocIDShared = uint32(RangePool.Sharing)
} else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_GEMPORT_ID {
GEMPortIDStart = RangePool.Start
GEMPortIDEnd = RangePool.End
GEMPortIDShared = uint32(RangePool.Sharing)
}
}
ponRMgr.InitDefaultPONResourceRanges(nil, ONUIDStart, ONUIDEnd, ONUIDShared,
AllocIDStart, AllocIDEnd, AllocIDShared,
GEMPortIDStart, GEMPortIDEnd, GEMPortIDShared,
flowIDDummyStart, flowIDDummyEnd, FlowIDShared, uniIDDummyStart, uniIDDummyEnd,
devInfo.PonPorts, techRange.IntfIds)
}
// Delete clears used resources for the particular olt device being deleted
func (RsrcMgr *OpenOltResourceMgr) Delete() error {
if err := RsrcMgr.PonRsrMgr.ClearDeviceResourcePool(context.Background()); err != nil {
logger.Debug(nil, "Failed to clear device resource pool")
return err
}
logger.Debug(nil, "Cleared device resource pool")
return nil
}
// GetONUID returns the available OnuID for the given pon-port
func (RsrcMgr *OpenOltResourceMgr) GetONUID(ponIntfID uint32) (uint32, error) {
ctx := context.Background()
newCtx := context.WithValue(ctx, "ponIf", ponIntfID)
// Get ONU id for a provided pon interface ID.
onuID, err := RsrcMgr.TechprofileRef.GetResourceID(newCtx, ponIntfID,
ponrmgr.ONU_ID, 1)
if err != nil {
logger.Errorf(nil, "Failed to get resource for interface %d for type %s",
ponIntfID, ponrmgr.ONU_ID)
return 0, err
}
if len(onuID) > 0 {
return onuID[0], err
}
return 0, err // return onuID 0 on error
}
// GetFlowID return flow ID for a given pon interface id, onu id and uni id
func (RsrcMgr *OpenOltResourceMgr) GetFlowID(ctx context.Context, ponIntfID uint32) (uint64, error) {
RsrcMgr.FlowIDMgmtLock.Lock()
defer RsrcMgr.FlowIDMgmtLock.Unlock()
RsrcMgr.flow_id++
return RsrcMgr.flow_id, nil
}