[VOL-4126] Fixing race condition between vlanConfig FSM and reconcilingFLows flag during reconcile of the flows upon adapter restart
Change-Id: Icf9f4f3f715a7ac95aec95d71fcea6cc2bec486b
diff --git a/internal/pkg/onuadaptercore/device_handler.go b/internal/pkg/onuadaptercore/device_handler.go
index 73a3d48..df3c477 100644
--- a/internal/pkg/onuadaptercore/device_handler.go
+++ b/internal/pkg/onuadaptercore/device_handler.go
@@ -934,16 +934,22 @@
return
}
flowsFound = true
+ lastFlowToReconcile := false
flowsProcessed := 0
dh.setReconcilingFlows(true)
for _, flowData := range uniData.PersFlowParams {
logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
+ // If this is the last flow for the device we need to announce it the waiting
+ // chReconcilingFlowsFinished channel
+ if flowsProcessed == len(uniData.PersFlowParams)-1 {
+ lastFlowToReconcile = true
+ }
//the slice can be passed 'by value' here, - which internally passes its reference copy
dh.lockVlanConfig.RLock()
if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
- uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
+ uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile); err != nil {
logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
}
dh.lockVlanConfig.RUnlock()
@@ -951,7 +957,7 @@
dh.lockVlanConfig.RUnlock()
if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
- uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
+ uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile); err != nil {
logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
}
}
@@ -960,7 +966,10 @@
logger.Debugw(ctx, "reconciling - flows processed", log.Fields{"device-id": dh.deviceID, "flowsProcessed": flowsProcessed,
"numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
"configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
- dh.setReconcilingFlows(false)
+ // this can't be used as global finished reconciling flag because
+ // assumes is getting called before the state machines for the last flow is completed,
+ // while this is not guaranteed.
+ //dh.setReconcilingFlows(false)
}
if !flowsFound {
logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
@@ -2749,13 +2758,13 @@
logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
- loMatchVlan, loSetVlan, loSetPcp)
+ loMatchVlan, loSetVlan, loSetPcp, false)
dh.lockVlanConfig.RUnlock()
return err
}
dh.lockVlanConfig.RUnlock()
return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
- loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
+ loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false)
}
//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
@@ -2805,7 +2814,7 @@
// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
- aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
+ aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool) error {
chVlanFilterFsm := make(chan Message, 2048)
pDevEntry := dh.getOnuDeviceEntry(ctx, true)
@@ -2816,7 +2825,7 @@
pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
- dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
+ dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile)
if pVlanFilterFsm != nil {
dh.lockVlanConfig.Lock()
//ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there