[VOL-1645] Fix for device agents creation
Change-Id: I1a17bd689e458088b42963d395abf6b96180f5b8
diff --git a/rw_core/core/device_ownership.go b/rw_core/core/device_ownership.go
index 5deb1cb..ed0fd08 100644
--- a/rw_core/core/device_ownership.go
+++ b/rw_core/core/device_ownership.go
@@ -174,21 +174,33 @@
// Retrieve the ownership key based on the id
var ownershipKey string
var err error
- if ownershipKey, err = da.getOwnershipKey(id); err != nil {
+ var idStr string
+ var cache bool
+ if ownershipKey, idStr, cache, err = da.getOwnershipKey(id); err != nil {
log.Warnw("no-ownershipkey", log.Fields{"error": err})
return false
}
+ // Update the deviceToKey map, if not from cache
+ if !cache {
+ da.deviceToKeyMapLock.Lock()
+ da.deviceToKeyMap[idStr] = ownershipKey
+ da.deviceToKeyMapLock.Unlock()
+ }
+
deviceOwned, ownedByMe := da.getOwnership(ownershipKey)
if deviceOwned {
return ownedByMe
}
- // Not owned by me or maybe anybody else. Try to reserve it
+ // Not owned by me or maybe nobody else. Try to reserve it
reservedByMe := da.tryToReserveKey(ownershipKey)
myChnl := make(chan int)
da.deviceMapLock.Lock()
- da.deviceMap[ownershipKey] = &ownership{id: ownershipKey, owned: reservedByMe, chnl: myChnl}
+ da.deviceMap[ownershipKey] = &ownership{
+ id: ownershipKey,
+ owned: reservedByMe,
+ chnl: myChnl}
da.deviceMapLock.Unlock()
log.Debugw("set-new-ownership", log.Fields{"Id": ownershipKey, "owned": reservedByMe})
@@ -198,6 +210,9 @@
//AbandonDevice must be invoked whenever a device is deleted from the Core
func (da *DeviceOwnership) AbandonDevice(id string) error {
+ if id == "" {
+ return status.Error(codes.FailedPrecondition, "id-nil")
+ }
da.deviceMapLock.Lock()
defer da.deviceMapLock.Unlock()
if o, exist := da.deviceMap[id]; exist { // id is ownership key
@@ -209,7 +224,7 @@
delete(da.deviceToKeyMap, k)
}
}
- // Remove the device reference from the devicMap
+ // Remove the device reference from the deviceMap
delete(da.deviceMap, id)
// Stop the Go routine monitoring the device
@@ -218,9 +233,7 @@
log.Debugw("abandoning-device", log.Fields{"Id": id})
return nil
} else { // id is not ownership key
- if err := da.deleteDeviceKey(id); err != nil {
- log.Errorw("failed-deleting-key", log.Fields{"id": id})
- }
+ da.deleteDeviceKey(id)
}
return nil
}
@@ -258,50 +271,48 @@
return nil
}
-func (da *DeviceOwnership) deleteDeviceKey(id string) error {
+func (da *DeviceOwnership) deleteDeviceKey(id string) {
da.deviceToKeyMapLock.Lock()
defer da.deviceToKeyMapLock.Unlock()
if _, exist := da.deviceToKeyMap[id]; exist {
delete(da.deviceToKeyMap, id)
- return nil
}
- log.Warnw("device-not-owned", log.Fields{"deviceId": id})
- return nil
}
-func (da *DeviceOwnership) getOwnershipKey(id interface{}) (string, error) {
+// getOwnershipKey returns the ownership key that the id param uses. Ownership key is the parent
+// device Id of a child device or the rootdevice of a logical device. This function also returns the
+// id in string format of the id param via the ref output as well as if the data was retrieved from cache
+func (da *DeviceOwnership) getOwnershipKey(id interface{}) (ownershipKey string, ref string, cached bool, err error) {
if id == nil {
- return "", status.Error(codes.InvalidArgument, "nil-id")
+ return "", "", false, status.Error(codes.InvalidArgument, "nil-id")
}
- da.deviceToKeyMapLock.Lock()
- defer da.deviceToKeyMapLock.Unlock()
+ da.deviceToKeyMapLock.RLock()
+ defer da.deviceToKeyMapLock.RUnlock()
var device *voltha.Device
var lDevice *voltha.LogicalDevice
// The id can either be a device Id or a logical device id.
if dId, ok := id.(*utils.DeviceID); ok {
// Use cache if present
if val, exist := da.deviceToKeyMap[dId.Id]; exist {
- return val, nil
+ return val, dId.Id, true, nil
}
if device, _ = da.deviceMgr.GetDevice(dId.Id); device == nil {
- return "", status.Error(codes.NotFound, fmt.Sprintf("id-absent-%s", dId))
+ return "", dId.Id, false, status.Errorf(codes.NotFound, "id-absent-%s", dId)
}
if device.Root {
- da.deviceToKeyMap[dId.Id] = device.Id
+ return device.Id, dId.Id, false, nil
} else {
- da.deviceToKeyMap[dId.Id] = device.ParentId
+ return device.ParentId, dId.Id, false, nil
}
- return da.deviceToKeyMap[dId.Id], nil
} else if ldId, ok := id.(*utils.LogicalDeviceID); ok {
// Use cache if present
if val, exist := da.deviceToKeyMap[ldId.Id]; exist {
- return val, nil
+ return val, ldId.Id, true, nil
}
if lDevice, _ = da.logicalDeviceMgr.getLogicalDevice(ldId.Id); lDevice == nil {
- return "", status.Error(codes.NotFound, fmt.Sprintf("id-absent-%s", ldId))
+ return "", ldId.Id, false, status.Errorf(codes.NotFound, "id-absent-%s", dId)
}
- da.deviceToKeyMap[ldId.Id] = lDevice.RootDeviceId
- return lDevice.RootDeviceId, nil
+ return lDevice.RootDeviceId, ldId.Id, false, nil
}
- return "", status.Error(codes.NotFound, fmt.Sprintf("id-%s", id))
+ return "", "", false, status.Error(codes.NotFound, fmt.Sprintf("id-%v", id))
}