Add IPMI OEM command LinuxBootDone

Add a new OEM command for LinuxBoot to notify the BMC when it is about
to kexec into the OS. This is intended to give the BMC a chance to
prepare for an untrusted OS, e.g. disable any interfaces it doesn't want
the OS to have access to.

Tested:
Exercised the new OEM command using ipmitool
$ ipmitool raw 0x2e 0x32 0x79 0x2b 0x00 0x11
  79 2b 00 11

Change-Id: Ica76d77cdde48cebfbced32d8e7e860b559074e8
Signed-off-by: John Wedig <johnwedig@google.com>
diff --git a/handler.cpp b/handler.cpp
index 4046871..9032055 100644
--- a/handler.cpp
+++ b/handler.cpp
@@ -670,5 +670,36 @@
         std::vector<uint8_t>{});
 }
 
+static constexpr auto BARE_METAL_TARGET = "gbmc-bare-metal-active.target";
+
+void Handler::linuxBootDone() const
+{
+    if (isBmcInBareMetalMode() != static_cast<uint8_t>(BmcMode::BM_MODE))
+    {
+        return;
+    }
+
+    log<level::INFO>("LinuxBootDone: Disabling IPMI");
+
+    // Start the bare metal active systemd target.
+    auto bus = sdbusplus::bus::new_default();
+    auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT,
+                                      SYSTEMD_INTERFACE, "StartUnit");
+
+    method.append(BARE_METAL_TARGET);
+    method.append("replace");
+
+    try
+    {
+        bus.call_noreply(method);
+    }
+    catch (const sdbusplus::exception::SdBusError& ex)
+    {
+        log<level::ERR>("Failed to start bare metal active systemd target",
+                        entry("WHAT=%s", ex.what()));
+        throw IpmiException(::ipmi::ccUnspecifiedError);
+    }
+}
+
 } // namespace ipmi
 } // namespace google