[VOL-5464] optimization and err handling of new onu reboot flow

Change-Id: I8cf973ff511f72144d007ffe33c09f34626d158a
Signed-off-by: Akash Reddy Kankanala <akash.kankanala@radisys.com>
diff --git a/internal/pkg/core/device_handler.go b/internal/pkg/core/device_handler.go
index bba3f4a..b185003 100755
--- a/internal/pkg/core/device_handler.go
+++ b/internal/pkg/core/device_handler.go
@@ -883,13 +883,35 @@
 		return
 	}
 	var onuIndication oop.OnuIndication
+	var rebootInProgress bool
+	var persUniUnlockDone bool
 	pDevEntry.MutexPersOnuConfig.RLock()
 	onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
 	onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
 	onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
 	onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
+	rebootInProgress = pDevEntry.SOnuPersistentData.PersRebootInProgress
+	persUniUnlockDone = pDevEntry.SOnuPersistentData.PersUniUnlockDone
 	pDevEntry.MutexPersOnuConfig.RUnlock()
-	_ = dh.createInterface(ctx, &onuIndication)
+	if rebootInProgress {
+		if persUniUnlockDone {
+			logger.Warnw(ctx, "ONU indication shows reboot in progress - cannot proceed with reconciliation", log.Fields{"device-id": dh.DeviceID})
+			dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
+			return
+		}
+	}
+	if onuIndication.OperState == "up" {
+		if err := dh.createInterface(ctx, &onuIndication); err != nil {
+			logger.Errorw(ctx, "failed to handle device up indication", log.Fields{"device-id": dh.DeviceID, "error": err})
+			dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
+			return
+		}
+	} else {
+		logger.Warnw(ctx, "ONU indication does not have 'up' state, cannot proceed with reconciliation", log.Fields{"device-id": dh.DeviceID, "operState": onuIndication.OperState})
+		dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
+		return
+	}
+	logger.Debugw(ctx, "reconciling - simulate onu indication done", log.Fields{"device-id": dh.DeviceID})
 }
 
 func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
@@ -1590,6 +1612,7 @@
 			logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
 			return
 		}
+		dh.UpdateAndStoreRebootState(ctx, true)
 		if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
 			logger.Errorw(ctx, "errror-updating-device-reason-to-core", log.Fields{"device-id": dh.DeviceID, "error": err})
 			return
@@ -2292,6 +2315,7 @@
 			pDevEntry.MutexPersOnuConfig.Lock()
 			pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
 			pDevEntry.SOnuPersistentData.PersRebootInProgress = true
+			pDevEntry.SOnuPersistentData.PersUniUnlockDone = false
 			pDevEntry.MutexPersOnuConfig.Unlock()
 		}
 		// Moving the previous call to write to KV store here, to store the ONU pers data after the update.
@@ -2542,6 +2566,13 @@
 			// abort: system behavior is just unstable ...
 			return err
 		}
+		if dh.GetDeviceTechProfOnReboot() {
+			logger.Debugw(ctx, "Storing OnuPersData during device-down-indication", log.Fields{"device": dh.DeviceID, "onu-pers-data": dh.pOnuOmciDevice.SOnuPersistentData})
+			if err := dh.StorePersistentData(ctx); err != nil {
+				logger.Warnw(ctx, "store persistent data error - Failed to store DownIndication",
+					log.Fields{"device-id": dh.DeviceID, "err": err})
+			}
+		}
 	} else {
 		logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
 	}
@@ -4540,7 +4571,7 @@
 					if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
 						logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
 							log.Fields{"device-id": dh.DeviceID})
-					} else {
+					} else if !onuDevEntry.SOnuPersistentData.PersRebootInProgress {
 						onuDevEntry.MutexPersOnuConfig.RLock()
 						switch onuDevEntry.SOnuPersistentData.PersOperState {
 						case "up":
diff --git a/internal/pkg/core/openonu.go b/internal/pkg/core/openonu.go
index fce08b4..8d3d1a6 100755
--- a/internal/pkg/core/openonu.go
+++ b/internal/pkg/core/openonu.go
@@ -966,6 +966,7 @@
 			}
 			return &empty.Empty{}, nil
 		case "down", "unreachable":
+			handler.pOnuIndication = onuIndication
 			if err := handler.UpdateInterface(ctx); err != nil {
 				return nil, err
 			}