chassis: Switch NMI handling to Control.Host.NMI interface
Nothing in mainline OpenBMC appears to implement a service for the
Chassis.Control.NMISource interface as far as I can tell, so 'ipmitool
chassis power diag' had no way of working. With this change we switch
ipmid to use the same interface that bmcweb uses to handle a POST of
'{"ResetType":"Nmi"}' to the ComputerSystem.Reset endpoint (which
x86-power-control implements and thus actually works).
Tested: 'ipmitool chassis power diag' now successfully triggers an NMI
on the host via x86-power-control instead of simply logging an error on
the BMC.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Change-Id: Ic4c6cb2546cbd3877953fac9dd04ea752810c46c
diff --git a/chassishandler.cpp b/chassishandler.cpp
index c7c1fed..b366b2a 100644
--- a/chassishandler.cpp
+++ b/chassishandler.cpp
@@ -885,35 +885,29 @@
}
//------------------------------------------
-// Set Enabled property to inform NMI source
-// handling to trigger a NMI_OUT BSOD.
+// Trigger an NMI on the host via dbus
//------------------------------------------
-int setNmiProperty(ipmi::Context::ptr& ctx, const bool value)
+static int doNmi(ipmi::Context::ptr& ctx)
{
- constexpr const char* nmiSourceObjPath =
- "/xyz/openbmc_project/Chassis/Control/NMISource";
- constexpr const char* nmiSourceIntf =
- "xyz.openbmc_project.Chassis.Control.NMISource";
- std::string bmcSourceSignal = "xyz.openbmc_project.Chassis.Control."
- "NMISource.BMCSourceSignal.ChassisCmd";
+ constexpr const char* nmiIntfName = "xyz.openbmc_project.Control.Host.NMI";
+ ipmi::DbusObjectInfo nmiObj{};
+ boost::system::error_code ec;
- std::string service;
- boost::system::error_code ec = ipmi::getService(ctx, nmiSourceIntf,
- nmiSourceObjPath, service);
- if (!ec)
- {
- ec = ipmi::setDbusProperty(ctx, service, nmiSourceObjPath,
- nmiSourceIntf, "BMCSource", bmcSourceSignal);
- }
- if (!ec)
- {
- ec = ipmi::setDbusProperty(ctx, service, nmiSourceObjPath,
- nmiSourceIntf, "Enabled", value);
- }
+ ec = ipmi::getDbusObject(ctx, nmiIntfName, nmiObj);
if (ec)
{
- log<level::ERR>("Failed to trigger NMI_OUT",
- entry("EXCEPTION=%s", ec.message().c_str()));
+ log<level::ERR>("Failed to find NMI service",
+ entry("ERROR=%s", ec.message().c_str()));
+ return -1;
+ }
+
+ ctx->bus->yield_method_call<void>(ctx->yield, ec, nmiObj.second,
+ nmiObj.first, nmiIntfName, "NMI");
+ if (ec)
+ {
+ log<level::ERR>("NMI call failed",
+ entry("ERROR=%s", ec.message().c_str()));
+ elog<InternalFailure>();
return -1;
}
@@ -1387,7 +1381,7 @@
rc = initiateHostStateTransition(ctx, State::Host::Transition::Off);
break;
case CMD_PULSE_DIAGNOSTIC_INTR:
- rc = setNmiProperty(ctx, true);
+ rc = doNmi(ctx);
break;
default: