mmc: Set updated version to primary

Once the update is successful, mark the version as primary so that
it boots from the updated version upon BMC reboot.

Add a sleep to wait for the service file to complete setting the
primary version. Otherwise, the BMC could mark a Delete or
Priority value change as complete and the service is not done yet,
and if the BMC is rebooted it could try to boot from a non-existent
version.

As backgroung, reference issue openbmc/openbmc#2857 that attempted
to create a 'wait for service' function but was not successful.
This could be investigated further at a later time, which would
benefit other functions like Factory Reset that are also using
sleep as a workaround to wait for systemd service files.

Tested: Verified the version was set to primary during code update
        and delete, and that 3s passed (service file finished in
        about 1s) before the delete/update continued.

Change-Id: I4f9afdb020d8cc7c18cfdafe468dbff2dc8046c1
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/mmc/flash.cpp b/mmc/flash.cpp
index dd12b0d..3bd67fa 100644
--- a/mmc/flash.cpp
+++ b/mmc/flash.cpp
@@ -33,6 +33,7 @@
     msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
 
     auto mmcServiceFile = "obmc-flash-mmc@" + versionId + ".service";
+    auto mmcSetPrimary = "obmc-flash-mmc-setprimary@" + versionId + ".service";
 
     if (newStateUnit == mmcServiceFile && newStateResult == "done")
     {
@@ -40,7 +41,12 @@
         activationProgress->progress(activationProgress->progress() + 1);
     }
 
-    if (newStateUnit == mmcServiceFile)
+    if (newStateUnit == mmcSetPrimary && newStateResult == "done")
+    {
+        ubootEnvVarsUpdated = true;
+    }
+
+    if (newStateUnit == mmcServiceFile || newStateUnit == mmcSetPrimary)
     {
         if (newStateResult == "failed" || newStateResult == "dependency")
         {
@@ -49,7 +55,23 @@
         }
         else if (roVolumeCreated)
         {
-            Activation::onFlashWriteSuccess();
+            if (!ubootEnvVarsUpdated)
+            {
+                activationProgress->progress(90);
+
+                // Set the priority which triggers the service that updates the
+                // environment variables.
+                if (!Activation::redundancyPriority)
+                {
+                    Activation::redundancyPriority =
+                        std::make_unique<RedundancyPriority>(bus, path, *this,
+                                                             0);
+                }
+            }
+            else // Environment variables were updated
+            {
+                Activation::onFlashWriteSuccess();
+            }
         }
     }