Activation: Point active image to requested image

Once an image has been updated, point the current image to it.

Closes openbmc/openbmc#1278

Change-Id: If21938283913d4b40cadf44952b2a530c9266812
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index 01dd6b8..cf9197d 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,7 +19,8 @@
 	$(SYSTEMD_LIBS) \
 	$(PHOSPHOR_DBUS_INTERFACES_LIBS) \
 	$(SDBUSPLUS_LIBS) \
-	$(PHOSPHOR_LOGGING_LIBS)
+	$(PHOSPHOR_LOGGING_LIBS) \
+	-lstdc++fs
 
 openpower_update_manager_CXXFLAGS = $(generic_cxxflags)
 openpower_update_manager_LDFLAGS = $(generic_ldflags)
diff --git a/activation.cpp b/activation.cpp
index 935382a..4344c7f 100755
--- a/activation.cpp
+++ b/activation.cpp
@@ -1,3 +1,4 @@
+#include <experimental/filesystem>
 #include "activation.hpp"
 #include "config.h"
 
@@ -8,6 +9,7 @@
 namespace updater
 {
 
+namespace fs = std::experimental::filesystem;
 namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server;
 
 auto Activation::activation(Activations value) ->
@@ -62,6 +64,52 @@
         method.append(ubimountServiceFile,
                       "replace");
         bus.call_noreply(method);
+
+        // The ubimount service files attemps to create the RW and Preserved
+        // UBI volumes. If the service fails, the mount directories PNOR_PRSV
+        // and PNOR_RW_PREFIX_<versionid> won't be present. Check for the
+        // existence of those directories to validate the service file was
+        // successful, also for the existence of the RO directory where the
+        // image is supposed to reside.
+        if ((fs::exists(PNOR_PRSV)) &&
+            (fs::exists(PNOR_RW_PREFIX + versionId)) &&
+            (fs::exists(PNOR_RO_PREFIX + versionId)))
+        {
+            if (!fs::exists(PNOR_ACTIVE_PATH))
+            {
+                fs::create_directories(PNOR_ACTIVE_PATH);
+            }
+
+            // If the RW or RO active links exist, remove them and create new
+            // ones pointing to the active version.
+            if (fs::exists(PNOR_RO_ACTIVE_PATH))
+            {
+                fs::remove(PNOR_RO_ACTIVE_PATH);
+            }
+            fs::create_directory_symlink(PNOR_RO_PREFIX + versionId,
+                    PNOR_RO_ACTIVE_PATH);
+            if (fs::exists(PNOR_RW_ACTIVE_PATH))
+            {
+                fs::remove(PNOR_RW_ACTIVE_PATH);
+            }
+            fs::create_directory_symlink(PNOR_RW_PREFIX + versionId,
+                    PNOR_RW_ACTIVE_PATH);
+
+            // There is only one preserved directory as it is not tied to a
+            // version, so just create the link if it doesn't exist already.
+            if (!fs::exists(PNOR_PRSV_ACTIVE_PATH))
+            {
+                fs::create_directory_symlink(PNOR_PRSV, PNOR_PRSV_ACTIVE_PATH);
+            }
+
+            Activation::activation(
+                    softwareServer::Activation::Activations::Active);
+        }
+        else
+        {
+            Activation::activation(
+                    softwareServer::Activation::Activations::Failed);
+        }
     }
     return softwareServer::Activation::requestedActivation(value);
 }
diff --git a/configure.ac b/configure.ac
index cbbebef..7c9278c 100755
--- a/configure.ac
+++ b/configure.ac
@@ -80,6 +80,23 @@
 AC_DEFINE(SYSTEMD_INTERFACE, "org.freedesktop.systemd1.Manager",
     [systemd interface.])
 
+AC_DEFINE(PNOR_TOC_FILE, "pnor.toc",
+    [The name of the PNOR table of contents file])
+AC_DEFINE(PNOR_RO_PREFIX, "/media/pnor-ro-",
+    [The prefix path for the versioned read-only pnor partitions])
+AC_DEFINE(PNOR_RW_PREFIX, "/media/pnor-rw-",
+    [The prefix path for the versioned read-write pnor partitions])
+AC_DEFINE(PNOR_PRSV, "/media/pnor-prsv",
+    [The path for the preserved pnor partitions])
+AC_DEFINE(PNOR_ACTIVE_PATH, "/var/lib/phosphor-software-manager/pnor/",
+    [Path to the active pnor partitions])
+AC_DEFINE(PNOR_RO_ACTIVE_PATH, "/var/lib/phosphor-software-manager/pnor/ro",
+    [Path to the active read-only pnor partitions])
+AC_DEFINE(PNOR_RW_ACTIVE_PATH, "/var/lib/phosphor-software-manager/pnor/rw",
+    [Path to the active read-write pnor partitions])
+AC_DEFINE(PNOR_PRSV_ACTIVE_PATH, "/var/lib/phosphor-software-manager/pnor/prsv",
+    [Path to the active preserved pnor partitions])
+
 AC_CONFIG_FILES([Makefile test/Makefile])
 AC_OUTPUT