[VOL-4385] ONU Software upgrade download start improvements
Signed-off-by: mpagenko <michael.pagenkopf@adtran.com>
Change-Id: I53ed3406a57d5cc9064e41da57d57aaa4caedc4e
diff --git a/VERSION b/VERSION
index 62a6f53..53c8654 100755
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.0.2-dev234
+2.0.2-dev235
diff --git a/internal/pkg/core/device_handler.go b/internal/pkg/core/device_handler.go
index 216c09d..449d96e 100755
--- a/internal/pkg/core/device_handler.go
+++ b/internal/pkg/core/device_handler.go
@@ -26,8 +26,6 @@
"time"
"github.com/opencord/voltha-openonu-adapter-go/internal/pkg/config"
- "github.com/opencord/voltha-protos/v5/go/openolt"
- "github.com/opencord/voltha-protos/v5/go/tech_profile"
"github.com/gogo/protobuf/proto"
"github.com/looplab/fsm"
@@ -50,7 +48,9 @@
"github.com/opencord/voltha-protos/v5/go/extension"
ic "github.com/opencord/voltha-protos/v5/go/inter_container"
of "github.com/opencord/voltha-protos/v5/go/openflow_13"
+ "github.com/opencord/voltha-protos/v5/go/openolt"
oop "github.com/opencord/voltha-protos/v5/go/openolt"
+ "github.com/opencord/voltha-protos/v5/go/tech_profile"
"github.com/opencord/voltha-protos/v5/go/voltha"
)
@@ -176,6 +176,7 @@
UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
lockUpgradeFsm sync.RWMutex
pOnuUpradeFsm *swupg.OnuUpgradeFsm
+ upgradeCanceled bool
reconciling uint8
mutexReconcilingFlag sync.RWMutex
chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
@@ -1065,9 +1066,11 @@
var inactiveImageID uint16
if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
dh.lockUpgradeFsm.Lock()
- defer dh.lockUpgradeFsm.Unlock()
+ //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
+ // but must be still locked at calling createOnuUpgradeFsm
if dh.pOnuUpradeFsm == nil {
err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
+ dh.lockUpgradeFsm.Unlock()
if err == nil {
if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
@@ -1078,12 +1081,12 @@
"device-id": dh.DeviceID, "error": err})
}
} else { //OnuSw upgrade already running - restart (with possible abort of running)
+ dh.lockUpgradeFsm.Unlock()
logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
- dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
- //no effort spent anymore for the old API to automatically cancel and restart the download
- // like done for the new API
- logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
- dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
+ if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
+ dh.upgradeCanceled = true
+ dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
+ }
//no effort spent anymore for the old API to automatically cancel and restart the download
// like done for the new API
}
@@ -1115,11 +1118,12 @@
logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
"device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
- dh.lockUpgradeFsm.RLock()
- lopOnuUpradeFsm := dh.pOnuUpradeFsm
+ dh.lockUpgradeFsm.Lock()
//lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
- dh.lockUpgradeFsm.RUnlock()
- if lopOnuUpradeFsm != nil {
+ // but must be still locked at calling createOnuUpgradeFsm
+ // (and working with a local pointer copy does not work here if asynchronous request are done to fast
+ // [e.g.leaving the local pointer on nil even though a creation is already on the way])
+ if dh.pOnuUpradeFsm != nil {
//OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
// abort the current processing, running upgrades are always aborted by newer request
logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
@@ -1129,7 +1133,11 @@
logger.Debug(ctx, "flushed-upgrade-fsm-channel")
default:
}
- lopOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
+ dh.lockUpgradeFsm.Unlock()
+ if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
+ dh.upgradeCanceled = true
+ dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
+ }
select {
case <-time.After(cTimeOutRemoveUpgrade * time.Second):
logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
@@ -1138,12 +1146,14 @@
case <-dh.upgradeFsmChan:
logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
}
+ dh.lockUpgradeFsm.Lock() //lock again for following creation
}
//here it can be assumed that no running upgrade processing exists (anymore)
- //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
+ //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
// but none yet defined
err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
+ dh.lockUpgradeFsm.Unlock()
if err == nil {
if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
@@ -1182,6 +1192,10 @@
logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
}
+ if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
+ logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
+ return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
+ }
// use the OnuVendor identification from this device for the internal unique name
imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
// 1.) check a started upgrade process and relay the activation request to it
@@ -1245,6 +1259,10 @@
logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
}
+ if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
+ logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
+ return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
+ }
// use the OnuVendor identification from this device for the internal unique name
imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
// 1.) check a started upgrade process and relay the commitment request to it
@@ -1325,7 +1343,10 @@
pDeviceImageState.ImageState.ImageState = pImageState.ImageState
if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
//so here the imageIdentifier or version equals to what is used in the upgrade FSM
- dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
+ if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
+ dh.upgradeCanceled = true
+ dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
+ }
} //nothing to cancel (upgrade FSM for different image stays alive)
} else {
dh.lockUpgradeFsm.RUnlock()
@@ -2011,7 +2032,12 @@
//lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
dh.lockUpgradeFsm.RUnlock()
if lopOnuUpradeFsm != nil {
- lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
+ if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
+ //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
+ // (even though it may also run into direct cancellation, a bit hard to verify here)
+ // so don't set 'dh.upgradeCanceled = true' here!
+ lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
+ }
}
logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
@@ -2615,8 +2641,8 @@
}
// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
+// precondition: lockUpgradeFsm is already locked from caller of this function
func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
- //in here lockUpgradeFsm is already locked
chUpgradeFsm := make(chan cmn.Message, 2048)
var sFsmName = "OnuSwUpgradeFSM"
logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
@@ -2635,7 +2661,7 @@
// maybe try a FSM reset and then again ... - TODO!!!
return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
}
- /***** LockStateFSM started */
+ /***** Upgrade FSM started */
//reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
(*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
(*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
@@ -2665,7 +2691,8 @@
logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
"device-id": dh.DeviceID})
dh.lockUpgradeFsm.Lock()
- dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
+ dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
+ dh.upgradeCanceled = false //cancelation done
dh.pLastUpgradeImageState = apImageState
dh.lockUpgradeFsm.Unlock()
//signal upgradeFsm removed using non-blocking channel send
@@ -2686,8 +2713,13 @@
}
dh.lockUpgradeFsm.RLock()
- defer dh.lockUpgradeFsm.RUnlock()
+ //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
if dh.pOnuUpradeFsm != nil {
+ if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
+ dh.lockUpgradeFsm.RUnlock()
+ logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
+ return
+ }
pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
if pUpgradeStatemachine != nil {
// commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
@@ -2700,11 +2732,16 @@
if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
if errImg != nil {
+ dh.lockUpgradeFsm.RUnlock()
logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
log.Fields{"device-id": dh.DeviceID})
- dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
+ if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
+ dh.upgradeCanceled = true
+ dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
+ }
return
}
+ dh.lockUpgradeFsm.RUnlock()
if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
// if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
@@ -2726,30 +2763,32 @@
} else {
logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit/on ActivateResponse, but load did not start with expected image Id",
log.Fields{"device-id": dh.DeviceID})
+ dh.upgradeCanceled = true
dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
- return
}
- } else {
- logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
- log.Fields{"device-id": dh.DeviceID})
- dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
return
}
- } else {
- //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
- // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
- if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
- if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
- logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
- "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
- dh.pOnuUpradeFsm.SetImageStateActive(ctx)
- }
+ dh.lockUpgradeFsm.RUnlock()
+ logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
+ log.Fields{"device-id": dh.DeviceID})
+ dh.upgradeCanceled = true
+ dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
+ return
+ }
+ //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
+ // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
+ if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
+ if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
+ logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
+ "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
+ dh.pOnuUpradeFsm.SetImageStateActive(ctx)
}
}
}
} else {
logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
}
+ dh.lockUpgradeFsm.RUnlock()
}
//SetBackend provides a DB backend for the specified path on the existing KV client
diff --git a/internal/pkg/core/openonu.go b/internal/pkg/core/openonu.go
index a7ad35c..c14655e 100755
--- a/internal/pkg/core/openonu.go
+++ b/internal/pkg/core/openonu.go
@@ -416,7 +416,7 @@
return nil, errors.New("invalid image definition")
}
-//ActivateImageUpdate requests downloading some Onu Software image to the INU via OMCI
+//ActivateImageUpdate requests downloading some Onu Software image to the ONU via OMCI
// according to indications as given in request and on success activate the image on the ONU
//The ImageDownload needs to be called `request`due to library reflection requirements
func (oo *OpenONUAC) ActivateImageUpdate(ctx context.Context, imageInfo *ic.ImageDownloadMessage) (*voltha.ImageDownload, error) {
@@ -488,6 +488,8 @@
downloadedToAdapter := false
firstDevice := true
var vendorID string
+ var onuVolthaDevice *voltha.Device
+ var devErr error
for _, pCommonID := range (*request).DeviceId {
vendorIDMatch := true
loDeviceID := (*pCommonID).Id
@@ -497,21 +499,17 @@
loDeviceImageState.ImageState = &loImageState
loDeviceImageState.ImageState.Version = (*request).Image.Version
+ onuVolthaDevice = nil
handler := oo.getDeviceHandler(ctx, loDeviceID, false)
- if handler == nil {
- //cannot start ONU download for requested device
- logger.Warnw(ctx, "no handler found for image activation", log.Fields{"device-id": loDeviceID})
- loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_FAILED
- loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR
- loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
- loResponse.DeviceImageStates = append(loResponse.DeviceImageStates, &loDeviceImageState)
- continue
+ if handler != nil {
+ onuVolthaDevice, devErr = handler.getDeviceFromCore(ctx, loDeviceID)
+ } else {
+ // assumption here is, that the concerned device was already created (automatic start after device creation not supported)
+ devErr = errors.New("no handler found for device-id")
}
-
- onuVolthaDevice, err := handler.getDeviceFromCore(ctx, loDeviceID)
- if err != nil || onuVolthaDevice == nil {
- logger.Warnw(ctx, "Failed to fetch Onu device for image download",
- log.Fields{"device-id": loDeviceID, "err": err})
+ if devErr != nil || onuVolthaDevice == nil {
+ logger.Warnw(ctx, "Failed to fetch ONU device for image download",
+ log.Fields{"device-id": loDeviceID, "err": devErr})
loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_FAILED
loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR //proto restriction, better option: 'INVALID_DEVICE'
loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
@@ -552,24 +550,15 @@
}
if downloadedToAdapter && vendorIDMatch {
// start the ONU download activity for each possible device
- // assumption here is, that the concerned device was already created (automatic start after device creation not supported)
- if handler := oo.getDeviceHandler(ctx, loDeviceID, false); handler != nil {
- logger.Debugw(ctx, "image download on omci requested", log.Fields{
- "image-id": imageIdentifier, "device-id": loDeviceID})
- //onu upgrade handling called in background without immediate error evaluation here
- // as the processing can be done for multiple ONU's and an error on one ONU should not stop processing for others
- // state/progress/success of the request has to be verified using the Get_onu_image_status() API
- go handler.onuSwUpgradeAfterDownload(ctx, request, oo.pFileManager, imageIdentifier)
- loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_STARTED
- loDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
- loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
- } else {
- //cannot start ONU download for requested device
- logger.Warnw(ctx, "no handler found for image activation", log.Fields{"device-id": loDeviceID})
- loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_FAILED
- loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR //proto restriction, better option: 'INVALID_DEVICE'
- loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
- }
+ logger.Debugw(ctx, "image download on omci requested", log.Fields{
+ "image-id": imageIdentifier, "device-id": loDeviceID})
+ //onu upgrade handling called in background without immediate error evaluation here
+ // as the processing can be done for multiple ONU's and an error on one ONU should not stop processing for others
+ // state/progress/success of the request has to be verified using the Get_onu_image_status() API
+ go handler.onuSwUpgradeAfterDownload(ctx, request, oo.pFileManager, imageIdentifier)
+ loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_STARTED
+ loDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
+ loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
} else {
loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_FAILED
if !downloadedToAdapter {
@@ -580,19 +569,8 @@
loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
}
}
-
- // start the ONU download activity for each possible device
- logger.Debugw(ctx, "image download on omci requested", log.Fields{
- "image-id": imageIdentifier, "device-id": loDeviceID})
- //onu upgrade handling called in background without immediate error evaluation here
- // as the processing can be done for multiple ONU's and an error on one ONU should not stop processing for others
- // state/progress/success of the request has to be verified using the Get_onu_image_status() API
- go handler.onuSwUpgradeAfterDownload(ctx, request, oo.pFileManager, imageIdentifier)
- loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_STARTED
- loDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
- loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
loResponse.DeviceImageStates = append(loResponse.DeviceImageStates, &loDeviceImageState)
- }
+ } //for all requested devices
pImageResp := &loResponse
return pImageResp, nil
}
@@ -608,25 +586,23 @@
var vendorIDSet bool
firstDevice := true
var vendorID string
+ var onuVolthaDevice *voltha.Device
+ var devErr error
for _, pCommonID := range (*in).DeviceId {
loDeviceID := (*pCommonID).Id
pDeviceImageState := &voltha.DeviceImageState{DeviceId: loDeviceID}
+ vendorIDSet = false
+ onuVolthaDevice = nil
handler := oo.getDeviceHandler(ctx, loDeviceID, false)
- if handler == nil {
- //cannot get the handler
- logger.Warnw(ctx, "no handler found for image status request ", log.Fields{"device-id": loDeviceID})
- pDeviceImageState.DeviceId = loDeviceID
- pDeviceImageState.ImageState.Version = (*in).Version
- pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_FAILED
- pDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR
- pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
- loResponse.DeviceImageStates = append(loResponse.DeviceImageStates, pDeviceImageState)
- continue
+ if handler != nil {
+ onuVolthaDevice, devErr = handler.getDeviceFromCore(ctx, loDeviceID)
+ } else {
+ // assumption here is, that the concerned device was already created (automatic start after device creation not supported)
+ devErr = errors.New("no handler found for device-id")
}
- onuVolthaDevice, err := handler.getDeviceFromCore(ctx, loDeviceID)
- if err != nil || onuVolthaDevice == nil {
+ if devErr != nil || onuVolthaDevice == nil {
logger.Warnw(ctx, "Failed to fetch Onu device to get image status",
- log.Fields{"device-id": loDeviceID, "err": err})
+ log.Fields{"device-id": loDeviceID, "err": devErr})
pImageState := &voltha.ImageState{
Version: (*in).Version,
DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN, //no statement about last activity possible
@@ -668,7 +644,7 @@
}
}
loResponse.DeviceImageStates = append(loResponse.DeviceImageStates, pDeviceImageState)
- }
+ } //for all requested devices
pImageResp := &loResponse
return pImageResp, nil
}
@@ -682,56 +658,64 @@
imageIdentifier := (*in).Version
firstDevice := true
var vendorID string
+ var vendorIDSet bool
+ var onuVolthaDevice *voltha.Device
+ var devErr error
for _, pCommonID := range (*in).DeviceId {
loDeviceID := (*pCommonID).Id
pDeviceImageState := &voltha.DeviceImageState{}
loImageState := voltha.ImageState{}
pDeviceImageState.ImageState = &loImageState
-
+ vendorIDSet = false
+ onuVolthaDevice = nil
handler := oo.getDeviceHandler(ctx, loDeviceID, false)
- if handler == nil {
- //cannot start ONU download for requested device
- logger.Warnw(ctx, "no handler found for aborting upgrade ", log.Fields{"device-id": loDeviceID})
+ if handler != nil {
+ onuVolthaDevice, devErr = handler.getDeviceFromCore(ctx, loDeviceID)
+ } else {
+ // assumption here is, that the concerned device was already created (automatic start after device creation not supported)
+ devErr = errors.New("no handler found for device-id")
+ }
+ if devErr != nil || onuVolthaDevice == nil {
+ logger.Warnw(ctx, "Failed to fetch Onu device to abort its download",
+ log.Fields{"device-id": loDeviceID, "err": devErr})
pDeviceImageState.DeviceId = loDeviceID
pDeviceImageState.ImageState.Version = (*in).Version
- //nolint:misspell
- pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
- //nolint:misspell
- pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
+ pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
+ pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST //something better could be considered (MissingHandler) - proto
pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
- loResponse.DeviceImageStates = append(loResponse.DeviceImageStates, pDeviceImageState)
- continue
- }
- onuVolthaDevice, err := handler.getDeviceFromCore(ctx, loDeviceID)
- if err != nil || onuVolthaDevice == nil {
- logger.Warnw(ctx, "Failed to fetch Onu device to abort its download",
- log.Fields{"device-id": loDeviceID, "err": err})
- continue //try the work with next deviceId
- }
-
- if firstDevice {
- //start/verify download of the image to the adapter based on first found device only
- // use the OnuVendor identification from first given device
- firstDevice = false
- vendorID = onuVolthaDevice.VendorId
- imageIdentifier = vendorID + imageIdentifier //head on vendor ID of the ONU
- logger.Debugw(ctx, "abort request for file", log.Fields{"image-id": imageIdentifier})
} else {
- //for all following devices verify the matching vendorID
- if onuVolthaDevice.VendorId != vendorID {
- logger.Warnw(ctx, "onu vendor id does not match image vendor id, device ignored",
- log.Fields{"onu-vendor-id": onuVolthaDevice.VendorId, "image-vendor-id": vendorID})
- continue //try the work with next deviceId
+ if firstDevice {
+ //start/verify download of the image to the adapter based on first found device only
+ // use the OnuVendor identification from first given device
+ firstDevice = false
+ vendorID = onuVolthaDevice.VendorId
+ vendorIDSet = true
+ imageIdentifier = vendorID + imageIdentifier //head on vendor ID of the ONU
+ logger.Debugw(ctx, "abort request for file", log.Fields{"image-id": imageIdentifier})
+ } else {
+ //for all following devices verify the matching vendorID
+ if onuVolthaDevice.VendorId != vendorID {
+ logger.Warnw(ctx, "onu vendor id does not match image vendor id, device ignored",
+ log.Fields{"onu-vendor-id": onuVolthaDevice.VendorId, "image-vendor-id": vendorID})
+ pDeviceImageState.DeviceId = loDeviceID
+ pDeviceImageState.ImageState.Version = (*in).Version
+ pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
+ pDeviceImageState.ImageState.Reason = voltha.ImageState_VENDOR_DEVICE_MISMATCH
+ pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
+ } else {
+ vendorIDSet = true
+ }
+ }
+ if vendorIDSet {
+ // cancel the ONU upgrade activity for each possible device
+ logger.Debugw(ctx, "image upgrade abort requested", log.Fields{
+ "image-id": imageIdentifier, "device-id": loDeviceID})
+ //upgrade cancel is called synchronously to collect the imageResponse indications for all concerned devices
+ handler.cancelOnuSwUpgrade(ctx, imageIdentifier, (*in).Version, pDeviceImageState)
}
}
-
- // cancel the ONU upgrade activity for each possible device
- logger.Debugw(ctx, "image upgrade abort requested", log.Fields{
- "image-id": imageIdentifier, "device-id": loDeviceID})
- //upgrade cancel is called synchronously to collect the imageResponse indications for all concerned devices
- handler.cancelOnuSwUpgrade(ctx, imageIdentifier, (*in).Version, pDeviceImageState)
loResponse.DeviceImageStates = append(loResponse.DeviceImageStates, pDeviceImageState)
- }
+ } //for all requested devices
if !firstDevice {
//if at least one valid device was found cancel also a possibly running download to adapter and remove the image
// this is to be done after the upgradeOnu cancel activities in order to not subduct the file for still running processes
diff --git a/internal/pkg/swupg/omci_onu_upgrade.go b/internal/pkg/swupg/omci_onu_upgrade.go
index 43ad621..3a0fe7c 100755
--- a/internal/pkg/swupg/omci_onu_upgrade.go
+++ b/internal/pkg/swupg/omci_onu_upgrade.go
@@ -563,38 +563,36 @@
// in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
// specific here: See definition of state changes: some states are excluded from reset for possible later commit
pAdaptFsm := oFsm.PAdaptFsm
- if pAdaptFsm != nil {
+ if pAdaptFsm != nil && pAdaptFsm.PFsm != nil {
// calling FSM events in background to avoid blocking of the caller
- go func(aPAFsm *cmn.AdapterFsm) {
- if aPAFsm.PFsm != nil {
- if aPAFsm.PFsm.Is(UpgradeStWaitEndDL) {
- oFsm.chReceiveExpectedResponse <- false //which aborts the FSM in WaitEndDL state
- } else if aPAFsm.PFsm.Is(UpgradeStAbortingDL) {
- oFsm.chReceiveAbortEndSwDlResponse <- cEndSwDlResponseAbort //abort waiting on EndDownloadResponse
- }
+ go func(apFsm *fsm.FSM) {
+ if apFsm.Is(UpgradeStWaitEndDL) {
+ oFsm.chReceiveExpectedResponse <- false //which aborts the FSM in WaitEndDL state
+ } else if apFsm.Is(UpgradeStAbortingDL) {
+ oFsm.chReceiveAbortEndSwDlResponse <- cEndSwDlResponseAbort //abort waiting on EndDownloadResponse
+ }
- var err error
- if abCompleteAbort {
- // in case of unconditional abort request the ImageState is set immediately
- oFsm.mutexUpgradeParams.Lock()
- //any previous lingering conditional cancelRequest is superseded by this abortion
- oFsm.conditionalCancelRequested = false
- oFsm.volthaDownloadReason = aReason
- oFsm.mutexUpgradeParams.Unlock()
- err = aPAFsm.PFsm.Event(UpgradeEvAbort) //as unconditional default FSM cancellation
- } else {
- //at conditional abort request the image states are set when reaching the reset state
- oFsm.conditionalCancelRequested = true
- err = aPAFsm.PFsm.Event(UpgradeEvReset) //as state-conditional default FSM cleanup
- }
- if err != nil {
- //error return is expected in case of conditional request and no state transition
- logger.Debugw(ctx, "onu upgrade fsm could not cancel with abort/reset event", log.Fields{
- "device-id": oFsm.deviceID, "error": err})
- }
- } //else the FSM seems already to be in some released state
- }(pAdaptFsm)
- }
+ var err error
+ if abCompleteAbort {
+ // in case of unconditional abort request the ImageState is set immediately
+ oFsm.mutexUpgradeParams.Lock()
+ //any previous lingering conditional cancelRequest is superseded by this abortion
+ oFsm.conditionalCancelRequested = false
+ oFsm.volthaDownloadReason = aReason
+ oFsm.mutexUpgradeParams.Unlock()
+ err = apFsm.Event(UpgradeEvAbort) //as unconditional default FSM cancellation
+ } else {
+ //at conditional abort request the image states are set when reaching the reset state
+ oFsm.conditionalCancelRequested = true
+ err = apFsm.Event(UpgradeEvReset) //as state-conditional default FSM cleanup
+ }
+ if err != nil {
+ //error return is expected in case of conditional request and no state transition
+ logger.Debugw(ctx, "onu upgrade fsm could not cancel with abort/reset event", log.Fields{
+ "device-id": oFsm.deviceID, "error": err})
+ }
+ }(pAdaptFsm.PFsm)
+ } //else the FSM seems already to be in some released state
}
func (oFsm *OnuUpgradeFsm) enterStarting(ctx context.Context, e *fsm.Event) {