[VOL-3668] Restrict race condition workaround Adopt_device/ONU_IND to onu-setup-procedure
Change-Id: I87eae979aa7b4fcfb36297f71525086c90f596ce
diff --git a/internal/pkg/onuadaptercore/device_handler.go b/internal/pkg/onuadaptercore/device_handler.go
index 7328abd..fbb324e 100644
--- a/internal/pkg/onuadaptercore/device_handler.go
+++ b/internal/pkg/onuadaptercore/device_handler.go
@@ -261,33 +261,6 @@
return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
}
-func (dh *deviceHandler) processInterAdapterONUIndReqMessage(msg *ic.InterAdapterMessage) error {
- msgBody := msg.GetBody()
- onuIndication := &oop.OnuIndication{}
- if err := ptypes.UnmarshalAny(msgBody, onuIndication); err != nil {
- logger.Warnw("onu-ind-request-cannot-unmarshal-msg-body", log.Fields{
- "device-id": dh.deviceID, "error": err})
- return err
- }
-
- onuOperstate := onuIndication.GetOperState()
- logger.Infow("onu-ind-request", log.Fields{"device-id": dh.deviceID,
- "OnuId": onuIndication.GetOnuId(),
- "AdminState": onuIndication.GetAdminState(), "OperState": onuOperstate,
- "SNR": onuIndication.GetSerialNumber()})
-
- //interface related functions might be error checked ....
- if onuOperstate == "up" {
- _ = dh.createInterface(onuIndication)
- } else if (onuOperstate == "down") || (onuOperstate == "unreachable") {
- _ = dh.updateInterface(onuIndication)
- } else {
- logger.Errorw("unknown-onu-indication operState", log.Fields{"OnuId": onuIndication.GetOnuId()})
- return fmt.Errorf("invalidOperState: %s, %s", onuOperstate, dh.deviceID)
- }
- return nil
-}
-
func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
msg *ic.InterAdapterMessage) error {
@@ -506,14 +479,11 @@
"fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
switch msgType {
+ // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
case ic.InterAdapterMessageType_OMCI_REQUEST:
{
return dh.processInterAdapterOMCIReqMessage(msg)
}
- case ic.InterAdapterMessageType_ONU_IND_REQUEST:
- {
- return dh.processInterAdapterONUIndReqMessage(msg)
- }
case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
{
return dh.processInterAdapterTechProfileDownloadReqMessage(msg)
diff --git a/internal/pkg/onuadaptercore/openonu.go b/internal/pkg/onuadaptercore/openonu.go
index d71f80f..f189d51 100644
--- a/internal/pkg/onuadaptercore/openonu.go
+++ b/internal/pkg/onuadaptercore/openonu.go
@@ -24,12 +24,14 @@
"sync"
"time"
+ "github.com/golang/protobuf/ptypes"
"github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
"github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore"
"github.com/opencord/voltha-lib-go/v3/pkg/kafka"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
ic "github.com/opencord/voltha-protos/v3/go/inter_container"
"github.com/opencord/voltha-protos/v3/go/openflow_13"
+ oop "github.com/opencord/voltha-protos/v3/go/openolt"
"github.com/opencord/voltha-protos/v3/go/voltha"
"github.com/opencord/voltha-openonu-adapter-go/internal/pkg/config"
@@ -152,7 +154,8 @@
oo.lockDeviceHandlersMap.Lock()
agent, ok := oo.deviceHandlers[deviceID]
if aWait && !ok {
- logger.Debugw("deviceHandler not present - wait for creation or timeout", log.Fields{"device-id": deviceID})
+ logger.Infow("Race condition: deviceHandler not present - wait for creation or timeout",
+ log.Fields{"device-id": deviceID})
if _, exist := oo.deviceHandlersCreateChan[deviceID]; !exist {
oo.deviceHandlersCreateChan[deviceID] = make(chan bool, 1)
}
@@ -176,6 +179,45 @@
return agent
}
+func (oo *OpenONUAC) processInterAdapterONUIndReqMessage(msg *ic.InterAdapterMessage) error {
+ msgBody := msg.GetBody()
+ onuIndication := &oop.OnuIndication{}
+ if err := ptypes.UnmarshalAny(msgBody, onuIndication); err != nil {
+ logger.Warnw("onu-ind-request-cannot-unmarshal-msg-body", log.Fields{"error": err})
+ return err
+ }
+ //ToDeviceId should address a DeviceHandler instance
+ targetDevice := msg.Header.ToDeviceId
+
+ onuOperstate := onuIndication.GetOperState()
+ waitForDhInstPresent := false
+ if onuOperstate == "up" {
+ //Race condition (relevant in BBSIM-environment only): Due to unsynchronized processing of olt-adapter and rw_core,
+ //ONU_IND_REQUEST msg by olt-adapter could arrive a little bit earlier than rw_core was able to announce the corresponding
+ //ONU by RPC of Adopt_device(). Therefore it could be necessary to wait with processing of ONU_IND_REQUEST until call of
+ //Adopt_device() arrived and DeviceHandler instance was created
+ waitForDhInstPresent = true
+ }
+ if handler := oo.getDeviceHandler(targetDevice, waitForDhInstPresent); handler != nil {
+ logger.Infow("onu-ind-request", log.Fields{"device-id": targetDevice,
+ "OnuId": onuIndication.GetOnuId(),
+ "AdminState": onuIndication.GetAdminState(), "OperState": onuOperstate,
+ "SNR": onuIndication.GetSerialNumber()})
+
+ if onuOperstate == "up" {
+ return handler.createInterface(onuIndication)
+ } else if (onuOperstate == "down") || (onuOperstate == "unreachable") {
+ return handler.updateInterface(onuIndication)
+ } else {
+ logger.Errorw("unknown-onu-ind-request operState", log.Fields{"OnuId": onuIndication.GetOnuId()})
+ return fmt.Errorf("invalidOperState: %s, %s", onuOperstate, targetDevice)
+ }
+ }
+ logger.Warnw("no handler found for received onu-ind-request", log.Fields{
+ "msgToDeviceId": targetDevice})
+ return fmt.Errorf(fmt.Sprintf("handler-not-found-%s", targetDevice))
+}
+
// Adapter interface required methods ############## begin #########
// #################################################################
@@ -216,22 +258,13 @@
logger.Debugw("Process_inter_adapter_message", log.Fields{"msgId": msg.Header.Id,
"msgProxyDeviceId": msg.Header.ProxyDeviceId, "msgToDeviceId": msg.Header.ToDeviceId, "Type": msg.Header.Type})
- var waitForDhInstPresent bool
+ if msg.Header.Type == ic.InterAdapterMessageType_ONU_IND_REQUEST {
+ // we have to handle ONU_IND_REQUEST already here - see comments in processInterAdapterONUIndReqMessage()
+ return oo.processInterAdapterONUIndReqMessage(msg)
+ }
//ToDeviceId should address a DeviceHandler instance
targetDevice := msg.Header.ToDeviceId
- // As a workaround this handling is only required for the OnuIndication with OperState=Up event.
- // But we live without that further check and use this processing also for OperState down/unreachable events to avoid
- // the deeper message processing at this stage. Should do no harm on the other events (except for run time)
- if msg.Header.Type != ic.InterAdapterMessageType_ONU_IND_REQUEST {
- waitForDhInstPresent = false
- } else {
- //Race condition (relevant in BBSIM-environment only): Due to unsynchronized processing of olt-adapter and rw_core,
- //ONU_IND_REQUEST msg by olt-adapter could arrive a little bit earlier than rw_core was able to announce the corresponding
- //ONU by RPC of Adopt_device()
- logger.Debugw("ONU_IND_REQUEST - potentially wait until DeviceHandler instance is created", log.Fields{"device-id": targetDevice})
- waitForDhInstPresent = true
- }
- if handler := oo.getDeviceHandler(targetDevice, waitForDhInstPresent); handler != nil {
+ if handler := oo.getDeviceHandler(targetDevice, false); handler != nil {
/* 200724: modification towards synchronous implementation - possible errors within processing shall be
* in the accordingly delayed response, some timing effect might result in Techprofile processing for multiple UNI's
*/