[VOL-2174] Race condition when creating NNI port

This commit fixes the race condition where a the NNI logical port
is not created.  The root cause is that at the time an addport
request is received the parent id of the root device was not set
leadint the addport to believe that it does not exist even if it
does.

Change-Id: Ib9de9f4d3fd74fc142c35a75ba5f9a836985715b
diff --git a/rw_core/core/device_agent.go b/rw_core/core/device_agent.go
index fea66d6..d9e8364 100755
--- a/rw_core/core/device_agent.go
+++ b/rw_core/core/device_agent.go
@@ -649,6 +649,24 @@
 	return nil
 }
 
+func (agent *DeviceAgent) setParentId(device *voltha.Device, parentId string) error {
+	agent.lockDevice.Lock()
+	defer agent.lockDevice.Unlock()
+	log.Debugw("setParentId", log.Fields{"deviceId": device.Id, "parentId": parentId})
+	if storeDevice, err := agent.getDeviceWithoutLock(); err != nil {
+		return status.Errorf(codes.NotFound, "%s", agent.deviceId)
+	} else {
+		// clone the device
+		cloned := proto.Clone(storeDevice).(*voltha.Device)
+		cloned.ParentId = parentId
+		// Store the device
+		if err := agent.updateDeviceInStoreWithoutLock(cloned, false, ""); err != nil {
+			return err
+		}
+		return nil
+	}
+}
+
 func (agent *DeviceAgent) updatePmConfigs(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
 	agent.lockDevice.Lock()
 	defer agent.lockDevice.Unlock()
diff --git a/rw_core/core/device_manager.go b/rw_core/core/device_manager.go
index b3c11af..beff7ae 100755
--- a/rw_core/core/device_manager.go
+++ b/rw_core/core/device_manager.go
@@ -1007,6 +1007,14 @@
 	return nil
 }
 
+func (dMgr *DeviceManager) setParentId(device *voltha.Device, parentId string) error {
+	log.Debugw("setParentId", log.Fields{"deviceId": device.Id, "parentId": parentId})
+	if agent := dMgr.getDeviceAgent(device.Id); agent != nil {
+		return agent.setParentId(device, parentId)
+	}
+	return status.Errorf(codes.NotFound, "%s", device.Id)
+}
+
 func (dMgr *DeviceManager) CreateLogicalDevice(cDevice *voltha.Device) error {
 	log.Info("CreateLogicalDevice")
 	// Verify whether the logical device has already been created
@@ -1014,14 +1022,11 @@
 		log.Debugw("Parent device already exist.", log.Fields{"deviceId": cDevice.Id, "logicalDeviceId": cDevice.Id})
 		return nil
 	}
-	var logicalId *string
 	var err error
-	if logicalId, err = dMgr.logicalDeviceMgr.createLogicalDevice(nil, cDevice); err != nil {
+	if _, err = dMgr.logicalDeviceMgr.createLogicalDevice(nil, cDevice); err != nil {
 		log.Warnw("createlogical-device-error", log.Fields{"device": cDevice})
 		return err
 	}
-	// Update the parent device with the logical id
-	dMgr.UpdateDeviceAttribute(cDevice.Id, "ParentId", *logicalId)
 	return nil
 }
 
diff --git a/rw_core/core/logical_device_manager.go b/rw_core/core/logical_device_manager.go
index b957d59..ac4a5e2 100644
--- a/rw_core/core/logical_device_manager.go
+++ b/rw_core/core/logical_device_manager.go
@@ -174,6 +174,13 @@
 
 	agent := newLogicalDeviceAgent(id, device.Id, ldMgr, ldMgr.deviceMgr, ldMgr.clusterDataProxy, ldMgr.defaultTimeout)
 	ldMgr.addLogicalDeviceAgentToMap(agent)
+
+	// Update the root device with the logical device Id reference
+	if err := ldMgr.deviceMgr.setParentId(device, id); err != nil {
+		log.Errorw("failed-setting-parent-id", log.Fields{"logicalDeviceId": id, "deviceId": device.Id})
+		return nil, err
+	}
+
 	go agent.start(ctx, false)
 
 	log.Debug("creating-logical-device-ends")