[VOL-4429] openonuAdapterGo - omci config error and crash during flow removal after adapter restart
Change-Id: Ifa3c62071fe59e270dd070ed8ccbae9018d582f5
diff --git a/VERSION b/VERSION
index 13097ab..4e7057f 100755
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.0.3-dev240
+2.0.3-dev241
diff --git a/internal/pkg/avcfg/omci_ani_config.go b/internal/pkg/avcfg/omci_ani_config.go
index 6ade746..d4c8082 100755
--- a/internal/pkg/avcfg/omci_ani_config.go
+++ b/internal/pkg/avcfg/omci_ani_config.go
@@ -784,7 +784,7 @@
uniVlanConfigFsm := oFsm.pDeviceHandler.GetUniVlanConfigFsm(oFsm.pOnuUniPort.UniID)
if uniVlanConfigFsm != nil {
// ensure mutexTPState not locked before calling some VlanConfigFsm activity (that might already be pending on it)
- if uniVlanConfigFsm.IsFlowRemovePending(oFsm.waitFlowDeleteChannel) {
+ if uniVlanConfigFsm.IsFlowRemovePending(ctx, oFsm.waitFlowDeleteChannel) {
logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID, "techProfile-id": oFsm.techProfileID})
// if flow remove is pending then wait for flow remove to finish first before proceeding with gem port delete
diff --git a/internal/pkg/avcfg/omci_vlan_config.go b/internal/pkg/avcfg/omci_vlan_config.go
index 03cacf9..7d6dcfe 100755
--- a/internal/pkg/avcfg/omci_vlan_config.go
+++ b/internal/pkg/avcfg/omci_vlan_config.go
@@ -213,7 +213,7 @@
logger.Errorw(ctx, "UniVlanConfigFsm's cmn.AdapterFsm could not be instantiated!!", log.Fields{
"device-id": instFsm.deviceID})
// Push response on the response channel
- instFsm.PushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-fsm-could-not-be-instantiated"))
+ instFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-fsm-could-not-be-instantiated"))
return nil
}
instFsm.PAdaptFsm.PFsm = fsm.NewFSM(
@@ -271,7 +271,7 @@
logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
"device-id": instFsm.deviceID})
// Push response on the response channel
- instFsm.PushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-base-fsm-could-not-be-instantiated"))
+ instFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-base-fsm-could-not-be-instantiated"))
return nil
}
@@ -339,6 +339,8 @@
if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
}
+ //cmp also usage in EVTOCDE create in omci_cc
+ oFsm.evtocdID = cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo)
oFsm.NumUniFlows = 1
oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
@@ -354,6 +356,10 @@
//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
+ if oFsm == nil {
+ logger.Error(ctx, "no valid UniVlanConfigFsm!")
+ return
+ }
//mutex protection is required for possible concurrent access to FSM members
oFsm.mutexIsAwaitingResponse.Lock()
oFsm.isCanceled = true
@@ -378,7 +384,11 @@
}
//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
-func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
+func (oFsm *UniVlanConfigFsm) GetWaitingTpID(ctx context.Context) uint8 {
+ if oFsm == nil {
+ logger.Error(ctx, "no valid UniVlanConfigFsm!")
+ return 0
+ }
//mutex protection is required for possible concurrent access to FSM members
oFsm.mutexFlowParams.RLock()
defer oFsm.mutexFlowParams.RUnlock()
@@ -386,7 +396,11 @@
}
//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
-func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
+func (oFsm *UniVlanConfigFsm) RequestClearPersistency(ctx context.Context, aClear bool) {
+ if oFsm == nil {
+ logger.Error(ctx, "no valid UniVlanConfigFsm!")
+ return
+ }
//mutex protection is required for possible concurrent access to FSM members
oFsm.mutexFlowParams.Lock()
defer oFsm.mutexFlowParams.Unlock()
@@ -400,6 +414,10 @@
// nolint: gocyclo
func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig, respChan *chan error) error {
+ if oFsm == nil {
+ logger.Error(ctx, "no valid UniVlanConfigFsm!")
+ return fmt.Errorf("no-valid-UniVlanConfigFsm")
+ }
loRuleParams := cmn.UniVlanRuleParams{
TpID: aTpID,
MatchVid: uint32(aMatchVlan),
@@ -449,7 +467,7 @@
"device-id": oFsm.deviceID, "slice length": len(oFsm.uniRemoveFlowsSlice)})
oFsm.mutexFlowParams.RUnlock()
err = fmt.Errorf("abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice %s", oFsm.deviceID)
- oFsm.PushReponseOnFlowResponseChannel(ctx, respChan, err)
+ oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
return err
}
@@ -459,7 +477,7 @@
logger.Errorw(ctx, "UniVlanConfigFsm suspension on add aborted - abort complete add-request", log.Fields{
"device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
err = fmt.Errorf("abort UniVlanConfigFsm suspension on add %s", oFsm.deviceID)
- oFsm.PushReponseOnFlowResponseChannel(ctx, respChan, err)
+ oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
return err
}
oFsm.mutexFlowParams.RLock()
@@ -506,7 +524,7 @@
logger.Errorw(ctx, "UniVlanConfigFsm suspended add-cookie-to-rule aborted", log.Fields{
"device-id": oFsm.deviceID, "cookie": delayedCookie})
err = fmt.Errorf(" UniVlanConfigFsm suspended add-cookie-to-rule aborted %s", oFsm.deviceID)
- oFsm.PushReponseOnFlowResponseChannel(ctx, respChan, err)
+ oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
return err
}
flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
@@ -532,7 +550,7 @@
logger.Errorw(ctx, "UniVlanConfigFsm suspended add-new-rule aborted", log.Fields{
"device-id": oFsm.deviceID, "cookie": delayedCookie})
err = fmt.Errorf(" UniVlanConfigFsm suspended add-new-rule aborted %s", oFsm.deviceID)
- oFsm.PushReponseOnFlowResponseChannel(ctx, respChan, err)
+ oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
return err
}
requestAppendRule = true //default assumption here is that rule is to be appended
@@ -576,7 +594,7 @@
logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
err = fsmErr
- oFsm.PushReponseOnFlowResponseChannel(ctx, respChan, err)
+ oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
return err
}
}
@@ -609,7 +627,7 @@
"sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
oFsm.mutexFlowParams.Unlock()
err = fmt.Errorf("abort UniVlanConfigFsm on add due to internal counter mismatch %s", oFsm.deviceID)
- oFsm.PushReponseOnFlowResponseChannel(ctx, respChan, err)
+ oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
return err
}
@@ -639,7 +657,7 @@
if fsmErr != nil {
logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
- oFsm.PushReponseOnFlowResponseChannel(ctx, respChan, fsmErr)
+ oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fsmErr)
return fsmErr
}
}
@@ -653,14 +671,14 @@
"device-id": oFsm.deviceID, "flow-number": oFsm.NumUniFlows})
oFsm.mutexFlowParams.Unlock()
err = fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
- oFsm.PushReponseOnFlowResponseChannel(ctx, respChan, err)
+ oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
return err
}
} else {
// no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
// push response on response channel as there is nothing to be done for this flow
- oFsm.PushReponseOnFlowResponseChannel(ctx, respChan, nil)
+ oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
oFsm.mutexFlowParams.RLock()
if oFsm.NumUniFlows == oFsm.ConfiguredUniFlow {
@@ -820,6 +838,10 @@
// if found removes cookie from flow cookie list and if this is empty
// initiates removal of the flow related configuration from the ONU (via OMCI)
func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64, respChan *chan error) error {
+ if oFsm == nil {
+ logger.Error(ctx, "no valid UniVlanConfigFsm!")
+ return fmt.Errorf("no-valid-UniVlanConfigFsm")
+ }
var deletedCookie uint64
flowCookieMatch := false
//mutex protection is required for possible concurrent access to FSM members
@@ -860,7 +882,7 @@
"device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
}
// Push response on the response channel
- oFsm.PushReponseOnFlowResponseChannel(ctx, respChan, nil)
+ oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
//permanently store the modified flow config for reconcile case and immediately write to KvStore
if oFsm.pDeviceHandler != nil {
if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
@@ -885,7 +907,7 @@
go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
}
// Push response on the response channel
- oFsm.PushReponseOnFlowResponseChannel(ctx, respChan, nil)
+ oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
return nil
} //unknown cookie
@@ -1037,7 +1059,7 @@
if !aWasConfigured {
// We did not actually process this flow but was removed before that.
// Indicate success response for the flow to caller who is blocking on a response
- oFsm.PushReponseOnFlowResponseChannel(ctx, storedUniFlowParams.RespChan, nil)
+ oFsm.pushReponseOnFlowResponseChannel(ctx, storedUniFlowParams.RespChan, nil)
}
//cut off the requested flow by slicing out this element
@@ -1145,8 +1167,6 @@
oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[0]
tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
oFsm.TpIDWaitingFor = tpID
- //cmp also usage in EVTOCDE create in omci_cc
- oFsm.evtocdID = cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo)
loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
//attention: take care to release the mutexFlowParams when calling the FSM directly -
// synchronous FSM 'event/state' functions may rely on this mutex
@@ -1297,7 +1317,7 @@
"device-id": oFsm.deviceID,
"overall-uni-rules": oFsm.NumUniFlows, "configured-uni-rules": oFsm.ConfiguredUniFlow})
if len(oFsm.uniVlanFlowParamsSlice) > 0 {
- oFsm.PushReponseOnFlowResponseChannel(ctx, oFsm.actualUniFlowParam.RespChan, nil)
+ oFsm.pushReponseOnFlowResponseChannel(ctx, oFsm.actualUniFlowParam.RespChan, nil)
}
pConfigVlanStateAFsm := oFsm.PAdaptFsm
@@ -1812,7 +1832,7 @@
oFsm.mutexFlowParams.Unlock()
// send response on the response channel for the removed flow.
- oFsm.PushReponseOnFlowResponseChannel(ctx, flowRespChan, nil)
+ oFsm.pushReponseOnFlowResponseChannel(ctx, flowRespChan, nil)
}
func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
@@ -1863,7 +1883,7 @@
oFsm.mutexFlowParams.RLock()
}
// Send response on response channel if the caller is waiting on it.
- oFsm.PushReponseOnFlowResponseChannel(ctx, removeUniFlowParams.respChan, fmt.Errorf("internal-error"))
+ oFsm.pushReponseOnFlowResponseChannel(ctx, removeUniFlowParams.respChan, fmt.Errorf("internal-error"))
}
}
@@ -1877,7 +1897,7 @@
if len(oFsm.uniVlanFlowParamsSlice) > 0 {
for _, vlanRule := range oFsm.uniVlanFlowParamsSlice {
// Send response on response channel if the caller is waiting on it.
- oFsm.PushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("internal-error"))
+ oFsm.pushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("internal-error"))
}
var emptySlice = make([]cmn.UniVlanFlowParams, 0)
_ = oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID, &emptySlice, true) //ignore errors
@@ -3146,7 +3166,11 @@
}
// IsFlowRemovePending returns true if there are pending flows to remove, else false.
-func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(aFlowDeleteChannel chan<- bool) bool {
+func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(ctx context.Context, aFlowDeleteChannel chan<- bool) bool {
+ if oFsm == nil {
+ logger.Error(ctx, "no valid UniVlanConfigFsm!")
+ return false
+ }
oFsm.mutexFlowParams.Lock()
defer oFsm.mutexFlowParams.Unlock()
if len(oFsm.uniRemoveFlowsSlice) > 0 {
@@ -3173,8 +3197,8 @@
}
}
-// PushReponseOnFlowResponseChannel pushes response on the response channel if available
-func (oFsm *UniVlanConfigFsm) PushReponseOnFlowResponseChannel(ctx context.Context, respChan *chan error, err error) {
+// pushReponseOnFlowResponseChannel pushes response on the response channel if available
+func (oFsm *UniVlanConfigFsm) pushReponseOnFlowResponseChannel(ctx context.Context, respChan *chan error, err error) {
if respChan != nil {
// Do it in a non blocking fashion, so that in case the flow handler routine has shutdown for any reason, we do not block here
select {
diff --git a/internal/pkg/common/interfaces.go b/internal/pkg/common/interfaces.go
index ef5e004..1f7d457 100755
--- a/internal/pkg/common/interfaces.go
+++ b/internal/pkg/common/interfaces.go
@@ -178,5 +178,5 @@
// IuniVlanConfigFsm interface to uniVlanConfigFsm
type IuniVlanConfigFsm interface {
- IsFlowRemovePending(chan<- bool) bool
+ IsFlowRemovePending(context.Context, chan<- bool) bool
}
diff --git a/internal/pkg/core/device_handler.go b/internal/pkg/core/device_handler.go
index 41a8771..f2cd542 100755
--- a/internal/pkg/core/device_handler.go
+++ b/internal/pkg/core/device_handler.go
@@ -2076,7 +2076,7 @@
dh.lockVlanConfig.RUnlock()
//reset of all Fsm is always accompanied by global persistency data removal
// no need to remove specific data
- pVlanFilterFsm.RequestClearPersistency(false)
+ pVlanFilterFsm.RequestClearPersistency(ctx, false)
//ensure the FSM processing is stopped in case waiting for some response
pVlanFilterFsm.CancelProcessing(ctx)
} else {
@@ -3268,7 +3268,7 @@
pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
if pVlanFilterStatemachine != nil {
//if this was an event of the TP processing that was waited for in the VlanFilterFsm
- if pVlanFilterFsm.GetWaitingTpID() == aTpID {
+ if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
@@ -4147,7 +4147,10 @@
// GetUniVlanConfigFsm - TODO: add comment
func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
- return dh.UniVlanConfigFsmMap[uniID]
+ dh.lockVlanConfig.RLock()
+ value := dh.UniVlanConfigFsmMap[uniID]
+ dh.lockVlanConfig.RUnlock()
+ return value
}
// GetOnuAlarmManager - TODO: add comment