Set RequestedActivation to None in all cases
The Activation D-Bus object represents the activation state for an
associated Version object.
The Activation property of the Activation object indicates the current
activation state. It has possible values like Ready, Activating,
Active, and Failed.
The RequestedActivation property of the Activation object indicates the
desired activation state. It has possible values of Active and None.
When the PSU code update application wants to install firmware on one or
more PSUs, it sets the RequestedActivation property to Active.
If the code update is successful, the Activation property is set to
Active, and the RequestedActivation property is set to None.
However, if the code update fails, the RequestedActivation property is
not changed. It continues to have the value Active.
There are many ways in which a code update can fail, such as:
* Unable to get PSU information from D-Bus
* No compatible PSUs found that need an update (happens during certain
race conditions)
* Unable to find or start PSU code update service file
* PSU code update service fails
Since the RequestedActivation property has the value Active after a
failed code update, it prevents the PSU code update application from
performing another code update in the future.
It is desirable to allow PSU code updates to be attempted in the future.
For example, if a code update fails due to a bad PSU, and the customer
replaces the PSU with a good one that has downlevel code, the new PSU
should be code updated.
Modify the application so that the RequestedActivation property is
always set to None when an activation attempt ends, regardless of
whether it was successful.
Tested:
* Test where update succeeds
* Test where update fails on initial activation attempt
* File path empty
* Could not get list of PSU inventory paths
* PSU queue is empty; no compatible PSUs needed update
* Unable to get update service
* Unable to start service
* Test where update fails after initial activation attempt
* Test where fails to start service on second PSU
* Test where second PSU update service fails
* Test where activation is restarted
* Test where update succeeds
* Test where fails on initial activation attempt
* Test where update service fails
Change-Id: Ie124fdd399b1a9b02d8ad6b50040fa9ae6739ccd
Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
diff --git a/src/activation.cpp b/src/activation.cpp
index 11da384..dfc8fd7 100644
--- a/src/activation.cpp
+++ b/src/activation.cpp
@@ -50,10 +50,10 @@
auto Activation::requestedActivation(RequestedActivations value)
-> RequestedActivations
{
- if (value == SoftwareActivation::RequestedActivations::Active)
+ if (value == RequestedActivations::Active)
{
if (SoftwareActivation::requestedActivation() !=
- SoftwareActivation::RequestedActivations::Active)
+ RequestedActivations::Active)
{
// PSU image could be activated even when it's in active,
// e.g. in case a PSU is replaced and has a older image, it will be
@@ -62,7 +62,11 @@
(activation() == Status::Failed) ||
(activation() == Status::Active))
{
- activation(Status::Activating);
+ if (activation(Status::Activating) != Status::Activating)
+ {
+ // Activation attempt failed
+ value = RequestedActivations::None;
+ }
}
}
else if (activation() == Status::Activating)
@@ -176,6 +180,7 @@
lg2::error("Failed to update PSU {PSU}", "PSU", psuQueue.front());
std::queue<std::string>().swap(psuQueue); // Clear the queue
activation(Status::Failed);
+ requestedActivation(RequestedActivations::None);
shouldActivateAgain = false;
}
@@ -267,7 +272,7 @@
// Reset RequestedActivations to none so that it could be activated in
// future
- requestedActivation(SoftwareActivation::RequestedActivations::None);
+ requestedActivation(RequestedActivations::None);
activation(Status::Active);
// Automatically restart activation if a request occurred while code update
@@ -276,7 +281,7 @@
if (shouldActivateAgain)
{
shouldActivateAgain = false;
- requestedActivation(SoftwareActivation::RequestedActivations::Active);
+ requestedActivation(RequestedActivations::Active);
}
}