VOL-1775 VOL-1779 VOL-1780 : Fix several issues with overall stability
- Apply changes as reported by golang race utility
- Added version attribute in KV object
- Added context object to db/model api
- Carrying timestamp info through context to help in the
decision making when applying a revision change
- Replaced proxy access control mechanism with etcd reservation mechanism
Change-Id: If3d142a73b1da0d64fa6a819530f297dbfada2d3
diff --git a/rw_core/core/logical_device_manager.go b/rw_core/core/logical_device_manager.go
index 96e3541..b871cd4 100644
--- a/rw_core/core/logical_device_manager.go
+++ b/rw_core/core/logical_device_manager.go
@@ -30,27 +30,24 @@
)
type LogicalDeviceManager struct {
- logicalDeviceAgents map[string]*LogicalDeviceAgent
- core *Core
- deviceMgr *DeviceManager
- grpcNbiHdlr *APIHandler
- adapterProxy *AdapterProxy
- kafkaICProxy *kafka.InterContainerProxy
- clusterDataProxy *model.Proxy
- exitChannel chan int
- lockLogicalDeviceAgentsMap sync.RWMutex
- defaultTimeout int64
+ logicalDeviceAgents sync.Map
+ core *Core
+ deviceMgr *DeviceManager
+ grpcNbiHdlr *APIHandler
+ adapterProxy *AdapterProxy
+ kafkaICProxy *kafka.InterContainerProxy
+ clusterDataProxy *model.Proxy
+ exitChannel chan int
+ defaultTimeout int64
}
func newLogicalDeviceManager(core *Core, deviceMgr *DeviceManager, kafkaICProxy *kafka.InterContainerProxy, cdProxy *model.Proxy, timeout int64) *LogicalDeviceManager {
var logicalDeviceMgr LogicalDeviceManager
logicalDeviceMgr.core = core
logicalDeviceMgr.exitChannel = make(chan int, 1)
- logicalDeviceMgr.logicalDeviceAgents = make(map[string]*LogicalDeviceAgent)
logicalDeviceMgr.deviceMgr = deviceMgr
logicalDeviceMgr.kafkaICProxy = kafkaICProxy
logicalDeviceMgr.clusterDataProxy = cdProxy
- logicalDeviceMgr.lockLogicalDeviceAgentsMap = sync.RWMutex{}
logicalDeviceMgr.defaultTimeout = timeout
return &logicalDeviceMgr
}
@@ -83,35 +80,26 @@
}
func (ldMgr *LogicalDeviceManager) addLogicalDeviceAgentToMap(agent *LogicalDeviceAgent) {
- ldMgr.lockLogicalDeviceAgentsMap.Lock()
- defer ldMgr.lockLogicalDeviceAgentsMap.Unlock()
- if _, exist := ldMgr.logicalDeviceAgents[agent.logicalDeviceId]; !exist {
- ldMgr.logicalDeviceAgents[agent.logicalDeviceId] = agent
+ if _, exist := ldMgr.logicalDeviceAgents.Load(agent.logicalDeviceId); !exist {
+ ldMgr.logicalDeviceAgents.Store(agent.logicalDeviceId, agent)
}
}
func (ldMgr *LogicalDeviceManager) isLogicalDeviceInCache(logicalDeviceId string) bool {
- ldMgr.lockLogicalDeviceAgentsMap.RLock()
- defer ldMgr.lockLogicalDeviceAgentsMap.RUnlock()
- _, inCache := ldMgr.logicalDeviceAgents[logicalDeviceId]
+ _, inCache := ldMgr.logicalDeviceAgents.Load(logicalDeviceId)
return inCache
}
// getLogicalDeviceAgent returns the logical device agent. If the device is not in memory then the device will
// be loaded from dB and a logical device agent created to managed it.
func (ldMgr *LogicalDeviceManager) getLogicalDeviceAgent(logicalDeviceId string) *LogicalDeviceAgent {
- ldMgr.lockLogicalDeviceAgentsMap.RLock()
- if agent, ok := ldMgr.logicalDeviceAgents[logicalDeviceId]; ok {
- ldMgr.lockLogicalDeviceAgentsMap.RUnlock()
- return agent
+ if agent, ok := ldMgr.logicalDeviceAgents.Load(logicalDeviceId); ok {
+ return agent.(*LogicalDeviceAgent)
} else {
// Try to load into memory - loading will also create the logical device agent
- ldMgr.lockLogicalDeviceAgentsMap.RUnlock()
if err := ldMgr.load(logicalDeviceId); err == nil {
- ldMgr.lockLogicalDeviceAgentsMap.RLock()
- defer ldMgr.lockLogicalDeviceAgentsMap.RUnlock()
- if agent, ok = ldMgr.logicalDeviceAgents[logicalDeviceId]; ok {
- return agent
+ if agent, ok = ldMgr.logicalDeviceAgents.Load(logicalDeviceId); ok {
+ return agent.(*LogicalDeviceAgent)
}
}
}
@@ -119,9 +107,7 @@
}
func (ldMgr *LogicalDeviceManager) deleteLogicalDeviceAgent(logicalDeviceId string) {
- ldMgr.lockLogicalDeviceAgentsMap.Lock()
- defer ldMgr.lockLogicalDeviceAgentsMap.Unlock()
- delete(ldMgr.logicalDeviceAgents, logicalDeviceId)
+ ldMgr.logicalDeviceAgents.Delete(logicalDeviceId)
}
// GetLogicalDevice provides a cloned most up to date logical device. If device is not in memory
@@ -137,20 +123,21 @@
func (ldMgr *LogicalDeviceManager) listManagedLogicalDevices() (*voltha.LogicalDevices, error) {
log.Debug("listManagedLogicalDevices")
result := &voltha.LogicalDevices{}
- ldMgr.lockLogicalDeviceAgentsMap.RLock()
- defer ldMgr.lockLogicalDeviceAgentsMap.RUnlock()
- for _, agent := range ldMgr.logicalDeviceAgents {
+ ldMgr.logicalDeviceAgents.Range(func(key, value interface{}) bool {
+ agent := value.(*LogicalDeviceAgent)
if ld, _ := agent.GetLogicalDevice(); ld != nil {
result.Items = append(result.Items, ld)
}
- }
+ return true
+ })
+
return result, nil
}
func (ldMgr *LogicalDeviceManager) listLogicalDevices() (*voltha.LogicalDevices, error) {
log.Debug("ListAllLogicalDevices")
result := &voltha.LogicalDevices{}
- if logicalDevices := ldMgr.clusterDataProxy.List("/logical_devices", 0, false, ""); logicalDevices != nil {
+ if logicalDevices := ldMgr.clusterDataProxy.List(context.Background(), "/logical_devices", 0, false, ""); logicalDevices != nil {
for _, logicalDevice := range logicalDevices.([]interface{}) {
if agent := ldMgr.getLogicalDeviceAgent(logicalDevice.(*voltha.LogicalDevice).Id); agent == nil {
agent = newLogicalDeviceAgent(
@@ -203,23 +190,23 @@
func (ldMgr *LogicalDeviceManager) stopManagingLogicalDeviceWithDeviceId(id string) string {
log.Infow("stop-managing-logical-device", log.Fields{"deviceId": id})
// Go over the list of logical device agents to find the one which has rootDeviceId as id
- ldMgr.lockLogicalDeviceAgentsMap.RLock()
- defer ldMgr.lockLogicalDeviceAgentsMap.RUnlock()
- for ldId, ldAgent := range ldMgr.logicalDeviceAgents {
+ var ldId = ""
+ ldMgr.logicalDeviceAgents.Range(func(key, value interface{}) bool {
+ ldAgent := value.(*LogicalDeviceAgent)
if ldAgent.rootDeviceId == id {
- log.Infow("stopping-logical-device-agent", log.Fields{"lDeviceId": ldId})
+ log.Infow("stopping-logical-device-agent", log.Fields{"lDeviceId": key})
ldAgent.stop(nil)
- delete(ldMgr.logicalDeviceAgents, ldId)
- return ldId
+ ldMgr.logicalDeviceAgents.Delete(ldId)
+ ldId = key.(string)
}
- }
- return ""
+ return true
+ })
+ return ldId
}
//getLogicalDeviceFromModel retrieves the logical device data from the model.
func (ldMgr *LogicalDeviceManager) getLogicalDeviceFromModel(lDeviceId string) (*voltha.LogicalDevice, error) {
-
- if logicalDevice := ldMgr.clusterDataProxy.Get("/logical_devices/"+lDeviceId, 0, false, ""); logicalDevice != nil {
+ if logicalDevice := ldMgr.clusterDataProxy.Get(context.Background(), "/logical_devices/"+lDeviceId, 0, false, ""); logicalDevice != nil {
if lDevice, ok := logicalDevice.(*voltha.LogicalDevice); ok {
return lDevice, nil
}
@@ -232,9 +219,7 @@
log.Debugw("loading-logical-device", log.Fields{"lDeviceId": lDeviceId})
// To prevent a race condition, let's hold the logical device agent map lock. This will prevent a loading and
// a create logical device callback from occurring at the same time.
- ldMgr.lockLogicalDeviceAgentsMap.Lock()
- defer ldMgr.lockLogicalDeviceAgentsMap.Unlock()
- if ldAgent, _ := ldMgr.logicalDeviceAgents[lDeviceId]; ldAgent == nil {
+ if ldAgent, _ := ldMgr.logicalDeviceAgents.Load(lDeviceId); ldAgent == nil {
// Proceed with the loading only if the logical device exist in the Model (could have been deleted)
if _, err := ldMgr.getLogicalDeviceFromModel(lDeviceId); err == nil {
// Create a temp logical device Agent and let it load from memory
@@ -243,7 +228,7 @@
agent.stop(nil)
return err
}
- ldMgr.logicalDeviceAgents[agent.logicalDeviceId] = agent
+ ldMgr.logicalDeviceAgents.Store(agent.logicalDeviceId, agent)
}
}
// TODO: load the child device
@@ -430,7 +415,7 @@
}
func (ldMgr *LogicalDeviceManager) setupUNILogicalPorts(ctx context.Context, childDevice *voltha.Device) error {
- log.Debugw("setupUNILogicalPorts", log.Fields{"childDeviceId": childDevice.Id, "parentDeviceId": childDevice.ParentId})
+ log.Debugw("setupUNILogicalPorts", log.Fields{"childDeviceId": childDevice.Id, "parentDeviceId": childDevice.ParentId, "current-data": childDevice})
// Sanity check
if childDevice.Root {
return errors.New("Device-root")
@@ -473,7 +458,7 @@
}
func (ldMgr *LogicalDeviceManager) updatePortsState(device *voltha.Device, state voltha.AdminState_AdminState) error {
- log.Debugw("updatePortsState", log.Fields{"deviceId": device.Id, "state": state})
+ log.Debugw("updatePortsState", log.Fields{"deviceId": device.Id, "state": state, "current-data": device})
var ldId *string
var err error