Ensure POR reset is logged

In situations where the last reboot cause is not changed to POR,
specifically after unexpected AC losses, bmc-state-manager fails to
update the property. Therefore after a power cycle the last reboot
cause property is set to unknown. Thankfully, chassis-state-manager
generates a file indicating an AC loss occurred and that can be used
to identify that the last reboot cause was a power-on-cycle. It was
necessary to add an "After xyz.openbmc_project.State.Chassis"
dependency to bmc-state-managers service file to ensure the AC loss
was generated prior to bmc-state-manager executing.

Tested:

- Ensured that when the system was power cycled that the last reboot
  cause was set to "POR" when the chassis lost power file was present.

- Verified that when the file was not present the last reboot
  cause was set accordingly (typically unknown)

Change-Id: Ifa6d5d6f89c221477ee2f2fa1ed15adade359e45
Signed-off-by: NodeMan97 <corey.hardesty@icloud.com>
diff --git a/bmc_state_manager.cpp b/bmc_state_manager.cpp
index e1cbaf2..473329c 100644
--- a/bmc_state_manager.cpp
+++ b/bmc_state_manager.cpp
@@ -313,6 +313,15 @@
             break;
     }
 
+    // If the above code could not detect a reason, check to see
+    // if an AC loss occured.
+    size_t chassisId = 0;
+    if (phosphor::state::manager::utils::checkACLoss(chassisId))
+    {
+        this->lastRebootCause(RebootCause::POR);
+        return;
+    }
+
     // If the above code could not detect a reason, look for a the
     // reset-cause-pinhole gpio to see if it is the reason for the reboot
     auto gpioval =
diff --git a/discover_system_state.cpp b/discover_system_state.cpp
index 837f0d1..c94faaf 100644
--- a/discover_system_state.cpp
+++ b/discover_system_state.cpp
@@ -125,10 +125,7 @@
             info("One time not set, check user setting of power policy");
 
 #ifdef ONLY_RUN_APR_ON_POWER_LOSS
-            std::string chassisLostPowerFileFmt =
-                fmt::sprintf(CHASSIS_LOST_POWER_FILE, hostId);
-            fs::path chassisPowerLossFile{chassisLostPowerFileFmt};
-            if (!fs::exists(chassisPowerLossFile))
+            if (!phosphor::state::manager::utils::checkACLoss(hostId))
             {
                 info(
                     "Chassis power was not on prior to BMC reboot so do not run any power policy");
diff --git a/meson.build b/meson.build
index 17a5a11..046e10f 100644
--- a/meson.build
+++ b/meson.build
@@ -176,6 +176,7 @@
             'chassis_check_power_status.cpp',
             'utils.cpp',
             dependencies: [
+                fmt,
                 libgpiod,
                 phosphordbusinterfaces,
                 phosphorlogging,
@@ -190,6 +191,7 @@
             'bmc_state_manager_main.cpp',
             'utils.cpp',
             dependencies: [
+                fmt,
                 libgpiod,
                 phosphordbusinterfaces,
                 phosphorlogging,
@@ -262,7 +264,8 @@
             'secure_boot_check.cpp',
             'utils.cpp',
             dependencies: [
-            sdbusplus, phosphorlogging, libgpiod
+            fmt, sdbusplus,
+            phosphorlogging, libgpiod
             ],
     implicit_include_directories: true,
     install: true
diff --git a/service_files/xyz.openbmc_project.State.BMC.service b/service_files/xyz.openbmc_project.State.BMC.service
index 5171877..45ba6f0 100644
--- a/service_files/xyz.openbmc_project.State.BMC.service
+++ b/service_files/xyz.openbmc_project.State.BMC.service
@@ -1,6 +1,7 @@
 [Unit]
 Description=Phosphor BMC State Manager
 Before=mapper-wait@-xyz-openbmc_project-state-bmc.service
+After=xyz.openbmc_project.State.Chassis@0.service
 Wants=obmc-mapper.target
 After=obmc-mapper.target
 Wants=xyz.openbmc_project.Logging.service
diff --git a/utils.cpp b/utils.cpp
index ced4e90..9ef652f 100644
--- a/utils.cpp
+++ b/utils.cpp
@@ -1,9 +1,15 @@
+#include "config.h"
+
 #include "utils.hpp"
 
+#include <fmt/format.h>
+#include <fmt/printf.h>
 #include <gpiod.h>
 
 #include <phosphor-logging/lg2.hpp>
 
+#include <filesystem>
+
 namespace phosphor
 {
 namespace state
@@ -182,6 +188,20 @@
     }
 }
 
+bool checkACLoss(size_t& chassisId)
+{
+    std::string chassisLostPowerFileFmt =
+        fmt::sprintf(CHASSIS_LOST_POWER_FILE, chassisId);
+
+    std::filesystem::path chassisPowerLossFile{chassisLostPowerFileFmt};
+    if (std::filesystem::exists(chassisPowerLossFile))
+    {
+        return true;
+    }
+
+    return false;
+}
+
 } // namespace utils
 } // namespace manager
 } // namespace state
diff --git a/utils.hpp b/utils.hpp
index c7f3947..9c1dd18 100644
--- a/utils.hpp
+++ b/utils.hpp
@@ -74,6 +74,13 @@
  */
 void createBmcDump(sdbusplus::bus_t& bus);
 
+/** @brief Attempt to locate the obmc-chassis-lost-power@ file
+ *    to indicate that an AC loss occured.
+ *
+ * @param[in] chassisId  - the chassis instance
+ */
+bool checkACLoss(size_t& chassisId);
+
 } // namespace utils
 } // namespace manager
 } // namespace state