Initial commit
This commit is contained in:
+48
@@ -0,0 +1,48 @@
|
||||
From dcfe25ff7fe8874933107ff5dcfaa447722de5d1 Mon Sep 17 00:00:00 2001
|
||||
From: wangjue <jue.wang2@luxshare-ict.com>
|
||||
Date: Thu, 26 Dec 2024 10:38:18 +0800
|
||||
Subject: [PATCH] Add multiplierM offsetB bExp rExp items in
|
||||
sensor_data_record.json
|
||||
|
||||
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
|
||||
---
|
||||
scripts/sensor_data_record_gen.py | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/scripts/sensor_data_record_gen.py b/scripts/sensor_data_record_gen.py
|
||||
index 2ef58b7..fdcf691 100755
|
||||
--- a/scripts/sensor_data_record_gen.py
|
||||
+++ b/scripts/sensor_data_record_gen.py
|
||||
@@ -12,10 +12,18 @@ def getSensorParams(sensor, sensor_params):
|
||||
sensorName = sensor.get("sensorName", path[path.rfind("/") + 1 :])
|
||||
sensorReadingType = sensor.get("sensorReadingType", 0)
|
||||
sensorType = sensor.get("sensorType", 0)
|
||||
+ multiplierM = sensor.get("multiplierM", 0)
|
||||
+ offsetB = sensor.get("offsetB", 0)
|
||||
+ bExp = sensor.get("bExp", 0)
|
||||
+ rExp = sensor.get("rExp", 0)
|
||||
sensor_params[path] = {
|
||||
"sensorName": sensorName,
|
||||
"sensorReadingType": sensorReadingType,
|
||||
"sensorType": sensorType,
|
||||
+ "multiplierM": multiplierM,
|
||||
+ "offsetB": offsetB,
|
||||
+ "bExp": bExp,
|
||||
+ "rExp": rExp,
|
||||
}
|
||||
|
||||
overridePaths = sensor.get("overridePaths", [])
|
||||
@@ -25,6 +33,10 @@ def getSensorParams(sensor, sensor_params):
|
||||
"sensorName": sensorName,
|
||||
"sensorReadingType": sensorReadingType,
|
||||
"sensorType": sensorType,
|
||||
+ "multiplierM": multiplierM,
|
||||
+ "offsetB": offsetB,
|
||||
+ "bExp": bExp,
|
||||
+ "rExp": rExp,
|
||||
}
|
||||
return sensor_params
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
||||
+263
@@ -0,0 +1,263 @@
|
||||
From 57dc7fbdd1dceb8c82512dae754bf4a8370a4010 Mon Sep 17 00:00:00 2001
|
||||
From: roly <Rolyli.Li@luxshare-ict.com>
|
||||
Date: Fri, 7 Feb 2025 14:42:30 +0800
|
||||
Subject: [PATCH] Add power cycle trigger async firmware update
|
||||
|
||||
---
|
||||
chassishandler.cpp | 216 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 216 insertions(+)
|
||||
|
||||
diff --git a/chassishandler.cpp b/chassishandler.cpp
|
||||
index 89d3e00..8e68ac5 100644
|
||||
--- a/chassishandler.cpp
|
||||
+++ b/chassishandler.cpp
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <mapper.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
+#include <boost/asio.hpp>
|
||||
#include <ipmid/api.hpp>
|
||||
#include <ipmid/types.hpp>
|
||||
#include <ipmid/utils.hpp>
|
||||
@@ -813,6 +814,196 @@ ipmi::RspType<> ipmiSetChassisCap(bool intrusion, bool fpLockout,
|
||||
return ipmi::responseSuccess();
|
||||
}
|
||||
|
||||
+//------------------------------------------------
|
||||
+// Is power on (check power state before async update)
|
||||
+//------------------------------------------------
|
||||
+bool isPowerOn()
|
||||
+{
|
||||
+ std::variant<std::string> msg;
|
||||
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
|
||||
+ try
|
||||
+ {
|
||||
+ auto method = bus.new_method_call("xyz.openbmc_project.State.Chassis",
|
||||
+ "/xyz/openbmc_project/state/chassis0",
|
||||
+ "org.freedesktop.DBus.Properties",
|
||||
+ "Get");
|
||||
+ method.append("xyz.openbmc_project.State.Chassis");
|
||||
+ method.append("CurrentPowerState");
|
||||
+ auto reply = bus.call(method);
|
||||
+ reply.read(msg);
|
||||
+ return std::get<std::string>(msg).find("Off") != std::string::npos
|
||||
+ ? false
|
||||
+ : true;
|
||||
+ }
|
||||
+ catch (const std::exception& /*ex*/)
|
||||
+ {
|
||||
+ log<level::ERR>("Can not get power status");
|
||||
+ return true;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+//------------------------------------------------
|
||||
+// Async update start (return status or no value))
|
||||
+//------------------------------------------------
|
||||
+std::string asyncUpdateStart()
|
||||
+{
|
||||
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
|
||||
+ std::string asyncStatus{};
|
||||
+ auto method = bus.new_method_call(
|
||||
+ "xyz.openbmc_project.Software.AsyncUpdate",
|
||||
+ "/xyz/openbmc_project/Software/AsyncUpdate",
|
||||
+ "xyz.openbmc_project.Software.AsyncUpdate", "Start");
|
||||
+ try
|
||||
+ {
|
||||
+ auto reply = bus.call(method);
|
||||
+ reply.read(asyncStatus);
|
||||
+ return asyncStatus;
|
||||
+ }
|
||||
+ catch (const sdbusplus::exception::SdBusError& /*ex*/)
|
||||
+ {
|
||||
+ log<level::ERR>("Error in starting async update");
|
||||
+ return "";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+//------------------------------------------------
|
||||
+// Get async update status (return status or no value)
|
||||
+//------------------------------------------------
|
||||
+std::string asyncUpdateStatus()
|
||||
+{
|
||||
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
|
||||
+ try
|
||||
+ {
|
||||
+ auto status = ipmi::getDbusProperty(
|
||||
+ bus, "xyz.openbmc_project.Software.AsyncUpdate",
|
||||
+ "/xyz/openbmc_project/Software/AsyncUpdate",
|
||||
+ "xyz.openbmc_project.Software.AsyncUpdate", "AsyncUpdateStatus");
|
||||
+ return std::get<std::string>(status);
|
||||
+ }
|
||||
+ catch (const sdbusplus::exception::SdBusError& /*ex*/)
|
||||
+ {
|
||||
+ log<level::ERR>("Can not get async update status");
|
||||
+ return "";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int initiateHostStateTransition(ipmi::Context::ptr& ctx,
|
||||
+ State::Host::Transition transition);
|
||||
+int initiateChassisStateTransition(ipmi::Context::ptr& ctx,
|
||||
+ State::Chassis::Transition transition);
|
||||
+//---------------------------------------------------------------------------
|
||||
+// if power cycle wait for power on
|
||||
+//---------------------------------------------------------------------------
|
||||
+void waitForUpdateDone()
|
||||
+{
|
||||
+ static boost::asio::steady_timer timer(*getIoContext());
|
||||
+ timer.expires_after(boost::asio::chrono::seconds(15));
|
||||
+ timer.async_wait([&](const boost::system::error_code& ec) {
|
||||
+ if (ec)
|
||||
+ {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (asyncUpdateStatus() != "Idle")
|
||||
+ {
|
||||
+ waitForUpdateDone();
|
||||
+ return;
|
||||
+ }
|
||||
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
|
||||
+ try
|
||||
+ {
|
||||
+ auto method =
|
||||
+ bus.new_method_call("xyz.openbmc_project.State.Host",
|
||||
+ "/xyz/openbmc_project/state/host0",
|
||||
+ "org.freedesktop.DBus.Properties", "Set");
|
||||
+
|
||||
+ method.append("xyz.openbmc_project.State.Host");
|
||||
+ method.append("RequestedHostTransition");
|
||||
+ method.append(std::variant<std::string>{
|
||||
+ "xyz.openbmc_project.State.Host.Transition.On"});
|
||||
+ bus.call_noreply(method);
|
||||
+ }
|
||||
+ catch (const sdbusplus::exception::SdBusError& /*ex*/)
|
||||
+ {
|
||||
+ log<level::ERR>("Can not power On after async update");
|
||||
+ }
|
||||
+ });
|
||||
+}
|
||||
+//---------------------------------------------------------------------------
|
||||
+// wait for power off to start update
|
||||
+//---------------------------------------------------------------------------
|
||||
+void waitForStartUpdate(bool doPowerOn)
|
||||
+{
|
||||
+ static boost::asio::steady_timer timer(*getIoContext());
|
||||
+ timer.expires_after(boost::asio::chrono::seconds(15));
|
||||
+ timer.async_wait(
|
||||
+ [doPowerOn](const boost::system::error_code& ec) {
|
||||
+ if (ec)
|
||||
+ {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (isPowerOn()) // power status is not "off"
|
||||
+ {
|
||||
+ waitForStartUpdate(doPowerOn);
|
||||
+ return;
|
||||
+ }
|
||||
+ try
|
||||
+ {
|
||||
+ asyncUpdateStart();
|
||||
+ if (doPowerOn)
|
||||
+ {
|
||||
+ waitForUpdateDone();
|
||||
+ }
|
||||
+ }
|
||||
+ catch (const sdbusplus::exception::SdBusError& /*ex*/)
|
||||
+ {
|
||||
+ log<level::ERR>("Can not start update");
|
||||
+ }
|
||||
+ });
|
||||
+}
|
||||
+
|
||||
+enum class PowerControlAsyncStatus
|
||||
+{
|
||||
+ active,
|
||||
+ running,
|
||||
+ idle
|
||||
+};
|
||||
+
|
||||
+//---------------------------------------------------------------------------
|
||||
+// hook host power control to trigger async update
|
||||
+// return true if async-update is not in progress
|
||||
+//---------------------------------------------------------------------------
|
||||
+PowerControlAsyncStatus
|
||||
+ processPowerControlHost(ipmi::Context::ptr& ctx,
|
||||
+ State::Host::Transition transition)
|
||||
+{
|
||||
+ std::string asyncStatus = asyncUpdateStatus();
|
||||
+ auto doPowerOn = isPowerOn();
|
||||
+ switch (transition)
|
||||
+ {
|
||||
+ case State::Host::Transition::Reboot:
|
||||
+ if (asyncStatus == "Waiting")
|
||||
+ {
|
||||
+ initiateChassisStateTransition(ctx,
|
||||
+ State::Chassis::Transition::Off);
|
||||
+ waitForStartUpdate(doPowerOn);
|
||||
+ return PowerControlAsyncStatus::active;
|
||||
+ }
|
||||
+ else if (asyncStatus == "Running")
|
||||
+ {
|
||||
+ return PowerControlAsyncStatus::running;
|
||||
+ }
|
||||
+ break;
|
||||
+ case State::Host::Transition::On:
|
||||
+ if (asyncStatus == "Running")
|
||||
+ {
|
||||
+ return PowerControlAsyncStatus::running;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ return PowerControlAsyncStatus::idle;
|
||||
+}
|
||||
//------------------------------------------
|
||||
// Calls into Host State Manager Dbus object
|
||||
//------------------------------------------
|
||||
@@ -1363,9 +1554,18 @@ ipmi::RspType<> ipmiChassisControl(ipmi::Context::ptr& ctx,
|
||||
uint8_t chassisControl)
|
||||
{
|
||||
int rc = 0;
|
||||
+ PowerControlAsyncStatus asyncUpdateStatus = PowerControlAsyncStatus::idle;
|
||||
switch (chassisControl)
|
||||
{
|
||||
case CMD_POWER_ON:
|
||||
+ asyncUpdateStatus =
|
||||
+ processPowerControlHost(ctx, State::Host::Transition::On);
|
||||
+ if (asyncUpdateStatus != PowerControlAsyncStatus::idle)
|
||||
+ {
|
||||
+ log<level::ERR>(
|
||||
+ "Power-on opertion is not allowed during the upgrade process");
|
||||
+ return ipmi::responseCommandNotAvailable();
|
||||
+ }
|
||||
rc = initiateHostStateTransition(ctx, State::Host::Transition::On);
|
||||
break;
|
||||
case CMD_POWER_OFF:
|
||||
@@ -1377,6 +1577,22 @@ ipmi::RspType<> ipmiChassisControl(ipmi::Context::ptr& ctx,
|
||||
ctx, State::Host::Transition::ForceWarmReboot);
|
||||
break;
|
||||
case CMD_POWER_CYCLE:
|
||||
+ asyncUpdateStatus =
|
||||
+ processPowerControlHost(ctx, State::Host::Transition::Reboot);
|
||||
+ if (asyncUpdateStatus == PowerControlAsyncStatus::active)
|
||||
+ {
|
||||
+ log<level::INFO>(
|
||||
+ "Power-cycle operation will activate the async-update, let the async-update flow to do the power-cycle");
|
||||
+ rc = ipmi::ccSuccess;
|
||||
+ break;
|
||||
+ }
|
||||
+ else if (asyncUpdateStatus == PowerControlAsyncStatus::running)
|
||||
+ {
|
||||
+ log<level::INFO>(
|
||||
+ "Power-cycle operation is not allowed during the upgrade");
|
||||
+ rc = ipmi::ccCommandNotAvailable;
|
||||
+ break;
|
||||
+ }
|
||||
rc = initiateHostStateTransition(ctx,
|
||||
State::Host::Transition::Reboot);
|
||||
break;
|
||||
--
|
||||
2.25.1
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
From a16e5220657aeca72ad01c2408fefed38fa3c256 Mon Sep 17 00:00:00 2001
|
||||
From: wangjue <jue.wang2@luxshare-ict.com>
|
||||
Date: Fri, 13 Dec 2024 11:07:55 +0800
|
||||
Subject: [PATCH] Fix incorrect thresholdLevelsStates response for Get Sensor
|
||||
Reading command
|
||||
|
||||
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
|
||||
---
|
||||
sensordatahandler.hpp | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/sensordatahandler.hpp b/sensordatahandler.hpp
|
||||
index 6c3a8e5..2867cd5 100644
|
||||
--- a/sensordatahandler.hpp
|
||||
+++ b/sensordatahandler.hpp
|
||||
@@ -327,9 +327,9 @@ GetSensorResponse readingData(const Info& sensorInfo)
|
||||
warningAlarmLow = false;
|
||||
}
|
||||
response.thresholdLevelsStates =
|
||||
- (static_cast<uint8_t>(critAlarmHigh) << 3) |
|
||||
- (static_cast<uint8_t>(critAlarmLow) << 2) |
|
||||
- (static_cast<uint8_t>(warningAlarmHigh) << 1) |
|
||||
+ (static_cast<uint8_t>(critAlarmHigh) << 4) |
|
||||
+ (static_cast<uint8_t>(warningAlarmHigh) << 3) |
|
||||
+ (static_cast<uint8_t>(critAlarmLow) << 1) |
|
||||
(static_cast<uint8_t>(warningAlarmLow));
|
||||
|
||||
return response;
|
||||
--
|
||||
2.34.1
|
||||
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
From 3079d7621187cb966f19726f2f31fb03f0080eed Mon Sep 17 00:00:00 2001
|
||||
From: roly <Rolyli.Li@luxshare-ict.com>
|
||||
Date: Wed, 11 Dec 2024 17:08:44 +0800
|
||||
Subject: [PATCH] add sensor config file
|
||||
|
||||
---
|
||||
scripts/meson.build | 19 +++++-
|
||||
scripts/sensor_data_record_gen.py | 104 ++++++++++++++++++++++++++++++
|
||||
2 files changed, 120 insertions(+), 3 deletions(-)
|
||||
create mode 100755 scripts/sensor_data_record_gen.py
|
||||
|
||||
diff --git a/scripts/meson.build b/scripts/meson.build
|
||||
index b739e6f..ae5358c 100644
|
||||
--- a/scripts/meson.build
|
||||
+++ b/scripts/meson.build
|
||||
@@ -3,11 +3,11 @@ python_exe = find_program('python3', 'python')
|
||||
|
||||
sensor_gen = custom_target('sensor-gen',
|
||||
output: 'sensor-gen.cpp',
|
||||
- input: [ 'sensor_gen.py', get_option('sensor-yaml-gen')],
|
||||
+ input: files(get_option('sensor-yaml-gen')),
|
||||
command: [
|
||||
python_exe,
|
||||
- '@INPUT0@',
|
||||
- '-i', '@INPUT1@',
|
||||
+ files('sensor_gen.py'),
|
||||
+ '-i', '@INPUT@',
|
||||
'-o', meson.current_build_dir(),
|
||||
'generate-cpp',
|
||||
],
|
||||
@@ -39,3 +39,16 @@ fru_gen = custom_target('fru-gen',
|
||||
],
|
||||
)
|
||||
generated_src += fru_gen
|
||||
+
|
||||
+sensor_data_gen = custom_target('sensor-json-gen',
|
||||
+ output: 'sensor-data-record.json',
|
||||
+ input: files(get_option('sensor-yaml-gen')),
|
||||
+ command: [
|
||||
+ files('sensor_data_record_gen.py'),
|
||||
+ '-i', '@INPUT@',
|
||||
+ '-o', meson.current_build_dir(),
|
||||
+ ],
|
||||
+ install: true,
|
||||
+ install_dir: get_option('datadir') / 'ipmi-providers',
|
||||
+)
|
||||
+generated_src += sensor_data_gen
|
||||
diff --git a/scripts/sensor_data_record_gen.py b/scripts/sensor_data_record_gen.py
|
||||
new file mode 100755
|
||||
index 0000000..2ef58b7
|
||||
--- /dev/null
|
||||
+++ b/scripts/sensor_data_record_gen.py
|
||||
@@ -0,0 +1,104 @@
|
||||
+#!/usr/bin/env python3
|
||||
+
|
||||
+import argparse
|
||||
+import json
|
||||
+import os
|
||||
+
|
||||
+import yaml
|
||||
+
|
||||
+
|
||||
+def getSensorParams(sensor, sensor_params):
|
||||
+ path = sensor["path"]
|
||||
+ sensorName = sensor.get("sensorName", path[path.rfind("/") + 1 :])
|
||||
+ sensorReadingType = sensor.get("sensorReadingType", 0)
|
||||
+ sensorType = sensor.get("sensorType", 0)
|
||||
+ sensor_params[path] = {
|
||||
+ "sensorName": sensorName,
|
||||
+ "sensorReadingType": sensorReadingType,
|
||||
+ "sensorType": sensorType,
|
||||
+ }
|
||||
+
|
||||
+ overridePaths = sensor.get("overridePaths", [])
|
||||
+ for item in overridePaths:
|
||||
+ sensorName = item[item.rfind("/") + 1 :]
|
||||
+ sensor_params[item] = {
|
||||
+ "sensorName": sensorName,
|
||||
+ "sensorReadingType": sensorReadingType,
|
||||
+ "sensorType": sensorType,
|
||||
+ }
|
||||
+ return sensor_params
|
||||
+
|
||||
+
|
||||
+def main():
|
||||
+ app_description = "Convert sensor yaml to json."
|
||||
+
|
||||
+ parser = argparse.ArgumentParser(
|
||||
+ description=app_description,
|
||||
+ formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
+ )
|
||||
+ parser.add_argument(
|
||||
+ "-i",
|
||||
+ "--sensor_yaml",
|
||||
+ dest="sensor_yaml",
|
||||
+ nargs="*",
|
||||
+ type=str,
|
||||
+ default=[],
|
||||
+ help="input sensor yaml file list to parse",
|
||||
+ )
|
||||
+ parser.add_argument(
|
||||
+ "-o",
|
||||
+ "--output-dir",
|
||||
+ dest="outputdir",
|
||||
+ help="The directory of json file",
|
||||
+ )
|
||||
+ parser.add_argument(
|
||||
+ "-f",
|
||||
+ "--override-flag",
|
||||
+ dest="override",
|
||||
+ default="",
|
||||
+ help="override flag",
|
||||
+ )
|
||||
+ args = parser.parse_args()
|
||||
+
|
||||
+ if not args.override and len(args.sensor_yaml) > 1:
|
||||
+ raise RuntimeError(
|
||||
+ "Not support multi machine, but there are multi sensor yamls"
|
||||
+ )
|
||||
+ total_sensor_params = {}
|
||||
+
|
||||
+ for yaml_file in args.sensor_yaml:
|
||||
+ with open(yaml_file, "r") as y:
|
||||
+ sensors = yaml.safe_load(y)
|
||||
+ sensors = [i for i in sensors.values()]
|
||||
+ sensor_params = {}
|
||||
+ for s in sensors:
|
||||
+ sensor_params = getSensorParams(s, sensor_params)
|
||||
+ for sensor_param in sensor_params:
|
||||
+ # if the sensor is already in the total_sensor_params, check the value is must same
|
||||
+ if sensor_param in total_sensor_params:
|
||||
+ if (
|
||||
+ total_sensor_params[sensor_param]
|
||||
+ != sensor_params[sensor_param]
|
||||
+ ):
|
||||
+ raise RuntimeError(
|
||||
+ "The sensor is already in the total_sensor_params, but the value is different"
|
||||
+ )
|
||||
+ else:
|
||||
+ total_sensor_params[sensor_param] = sensor_params[
|
||||
+ sensor_param
|
||||
+ ]
|
||||
+ output_json = os.path.join(args.outputdir, "sensor-data-record.json")
|
||||
+ with open(output_json, "w") as j:
|
||||
+ j.write(
|
||||
+ json.dumps(
|
||||
+ total_sensor_params,
|
||||
+ indent=4,
|
||||
+ sort_keys=True,
|
||||
+ separators=(",", ": "),
|
||||
+ )
|
||||
+ )
|
||||
+ j.write("\n")
|
||||
+
|
||||
+
|
||||
+if __name__ == "__main__":
|
||||
+ main()
|
||||
--
|
||||
2.25.1
|
||||
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
From fdcfa9e7ff6eb31fe77cd4032d202bb8f1a50f37 Mon Sep 17 00:00:00 2001
|
||||
From: roly <Rolyli.Li@luxshare-ict.com>
|
||||
Date: Thu, 21 Nov 2024 18:23:00 +0800
|
||||
Subject: [PATCH] ipmi cmd support set sel time utc offset
|
||||
|
||||
---
|
||||
storagehandler.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 63 insertions(+)
|
||||
|
||||
diff --git a/storagehandler.cpp b/storagehandler.cpp
|
||||
index 4fef019..67d76ea 100644
|
||||
--- a/storagehandler.cpp
|
||||
+++ b/storagehandler.cpp
|
||||
@@ -696,6 +696,63 @@ ipmi::RspType<int16_t> ipmiStorageGetSelTimeUtcOffset()
|
||||
return ipmi::responseSuccess(timeEquation);
|
||||
}
|
||||
|
||||
+/** @brief implements the Set SEL timezone command
|
||||
+ * @returns IPMI completion code plus response data
|
||||
+ * -current timezone
|
||||
+ */
|
||||
+ipmi::RspType<> ipmiStorageSetSelTimeUtcOffset(int16_t UTCOffset)
|
||||
+{
|
||||
+ int hrs = 0;
|
||||
+ char ZoneInfoFile[128] = {0}, file[32] = {0};
|
||||
+ static constexpr int16_t SEL_UTC_MAX_RANGE = 1440;
|
||||
+ static constexpr int16_t SEL_UTC_MIN_RANGE = -1440;
|
||||
+ static constexpr int16_t UNSPECIFIED_UTC_OFFSET = 0x7ff;
|
||||
+ constexpr auto LOCALTIME = "/etc/localtime";
|
||||
+
|
||||
+ if (((UTCOffset > SEL_UTC_MAX_RANGE ) || (UTCOffset < SEL_UTC_MIN_RANGE) || (UTCOffset % 60 != 0)) && UTCOffset != UNSPECIFIED_UTC_OFFSET)
|
||||
+ {
|
||||
+ return ipmi::responseParmOutOfRange();
|
||||
+ }
|
||||
+
|
||||
+ hrs = UTCOffset / 60;
|
||||
+ if(UTCOffset == UNSPECIFIED_UTC_OFFSET)
|
||||
+ {
|
||||
+ hrs = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (0 > UTCOffset)
|
||||
+ {
|
||||
+ if (snprintf(file,sizeof(file), "GMT+%d", -hrs) >= (long int)sizeof(file))
|
||||
+ {
|
||||
+ return ipmi::responseUnspecifiedError();
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (snprintf(file,sizeof(file), "GMT-%d", hrs) >= (long int)sizeof(file))
|
||||
+ {
|
||||
+ return ipmi::responseUnspecifiedError();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (snprintf (ZoneInfoFile, sizeof(ZoneInfoFile), "%s/%s", "/usr/share/zoneinfo/Etc", file) >= (long int)sizeof(ZoneInfoFile))
|
||||
+ {
|
||||
+ return ipmi::responseUnspecifiedError();
|
||||
+ }
|
||||
+
|
||||
+ if((0 > unlink(LOCALTIME)) && errno != ENOENT)
|
||||
+ {
|
||||
+ return ipmi::responseUnspecifiedError();
|
||||
+ }
|
||||
+
|
||||
+ if(symlink(ZoneInfoFile, LOCALTIME) < 0)
|
||||
+ {
|
||||
+ return ipmi::responseUnspecifiedError();
|
||||
+ }
|
||||
+
|
||||
+ return ipmi::responseSuccess();
|
||||
+}
|
||||
+
|
||||
/** @brief implements the reserve SEL command
|
||||
* @returns IPMI completion code plus response data
|
||||
* - SEL reservation ID.
|
||||
@@ -952,6 +1009,12 @@ void register_netfn_storage_functions()
|
||||
ipmi::Privilege::User,
|
||||
ipmiStorageGetSelTimeUtcOffset);
|
||||
|
||||
+ // <Set SEL Timezone>
|
||||
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
|
||||
+ ipmi::storage::cmdSetSelTimeUtcOffset,
|
||||
+ ipmi::Privilege::Operator,
|
||||
+ ipmiStorageSetSelTimeUtcOffset);
|
||||
+
|
||||
// <Get SEL Entry>
|
||||
ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_GET_SEL_ENTRY, NULL,
|
||||
getSELEntry, PRIVILEGE_USER);
|
||||
--
|
||||
2.25.1
|
||||
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
From cfb5e13388531e1317eeb3ccf0f8eef0c6eeca60 Mon Sep 17 00:00:00 2001
|
||||
From: Ren Yu <yux.ren@intel.com>
|
||||
Date: Tue, 28 May 2019 17:11:17 +0800
|
||||
Subject: [PATCH] Save the pre-timeout interrupt in dbus property
|
||||
|
||||
Get the watchdog pre-timeout interrupt value from ipmi watchdog set command,
|
||||
and store it into dbus property.
|
||||
|
||||
Tested:
|
||||
Config IPMI watchdog: BIOS FRB2 Power Cycle after 1 seconds:
|
||||
ipmitool raw 0x06 0x24 0x01 0x13 0x0 0x2 0xa 0x00
|
||||
Start watchdog:
|
||||
Ipmitool mc watchdog reset
|
||||
Check the watchdog pre-timeout interrupt in below:
|
||||
https://BMCIP/redfish/v1/Systems/system/LogServices/EventLog/Entries
|
||||
|
||||
Signed-off-by: Ren Yu <yux.ren@intel.com>
|
||||
Upstream-Status: Pending
|
||||
---
|
||||
app/watchdog.cpp | 47 ++++++++++++++++++++++++++++++++++++++++
|
||||
app/watchdog_service.cpp | 6 +++++
|
||||
app/watchdog_service.hpp | 9 ++++++++
|
||||
3 files changed, 62 insertions(+)
|
||||
|
||||
diff --git a/app/watchdog.cpp b/app/watchdog.cpp
|
||||
index 03c373e..cb0b1fd 100644
|
||||
--- a/app/watchdog.cpp
|
||||
+++ b/app/watchdog.cpp
|
||||
@@ -80,6 +80,7 @@ ipmi::RspType<> ipmiAppResetWatchdogTimer()
|
||||
|
||||
static constexpr uint8_t wd_dont_stop = 0x1 << 6;
|
||||
static constexpr uint8_t wd_timeout_action_mask = 0x3;
|
||||
+static constexpr uint8_t wdPreTimeoutInterruptMask = 0x3;
|
||||
|
||||
static constexpr uint8_t wdTimerUseResTimer1 = 0x0;
|
||||
static constexpr uint8_t wdTimerUseResTimer2 = 0x6;
|
||||
@@ -127,6 +128,45 @@ WatchdogService::Action ipmiActionToWdAction(IpmiAction ipmi_action)
|
||||
}
|
||||
}
|
||||
|
||||
+enum class IpmiPreTimeoutInterrupt : uint8_t
|
||||
+{
|
||||
+ None = 0x0,
|
||||
+ SMI = 0x1,
|
||||
+ NMI = 0x2,
|
||||
+ MI = 0x3,
|
||||
+};
|
||||
+/** @brief Converts an IPMI Watchdog PreTimeoutInterrupt to DBUS defined action
|
||||
+ * @param[in] ipmi_action The IPMI Watchdog PreTimeoutInterrupt
|
||||
+ * @return The Watchdog PreTimeoutInterrupt that the ipmi_action maps to
|
||||
+ */
|
||||
+WatchdogService::PreTimeoutInterruptAction ipmiPreTimeoutInterruptToWdAction(
|
||||
+ IpmiPreTimeoutInterrupt ipmiPreTimeOutInterrupt)
|
||||
+{
|
||||
+ switch (ipmiPreTimeOutInterrupt)
|
||||
+ {
|
||||
+ case IpmiPreTimeoutInterrupt::None:
|
||||
+ {
|
||||
+ return WatchdogService::PreTimeoutInterruptAction::None;
|
||||
+ }
|
||||
+ case IpmiPreTimeoutInterrupt::SMI:
|
||||
+ {
|
||||
+ return WatchdogService::PreTimeoutInterruptAction::SMI;
|
||||
+ }
|
||||
+ case IpmiPreTimeoutInterrupt::NMI:
|
||||
+ {
|
||||
+ return WatchdogService::PreTimeoutInterruptAction::NMI;
|
||||
+ }
|
||||
+ case IpmiPreTimeoutInterrupt::MI:
|
||||
+ {
|
||||
+ return WatchdogService::PreTimeoutInterruptAction::MI;
|
||||
+ }
|
||||
+ default:
|
||||
+ {
|
||||
+ throw std::domain_error("IPMI PreTimeoutInterrupt is invalid");
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
enum class IpmiTimerUse : uint8_t
|
||||
{
|
||||
Reserved = 0x0,
|
||||
@@ -250,6 +290,13 @@ ipmi::RspType<>
|
||||
// Mark as initialized so that future resets behave correctly
|
||||
wd_service.setInitialized(true);
|
||||
|
||||
+ // pretimeOutAction
|
||||
+ const auto ipmiPreTimeoutInterrupt =
|
||||
+ static_cast<IpmiPreTimeoutInterrupt>(wdPreTimeoutInterruptMask &
|
||||
+ (static_cast<uint8_t>(preTimeoutInterrupt)));
|
||||
+ wd_service.setPreTimeoutInterrupt(
|
||||
+ ipmiPreTimeoutInterruptToWdAction(ipmiPreTimeoutInterrupt));
|
||||
+
|
||||
lastCallSuccessful = true;
|
||||
return ipmi::responseSuccess();
|
||||
}
|
||||
diff --git a/app/watchdog_service.cpp b/app/watchdog_service.cpp
|
||||
index 3534e89..4df1ab6 100644
|
||||
--- a/app/watchdog_service.cpp
|
||||
+++ b/app/watchdog_service.cpp
|
||||
@@ -198,3 +198,9 @@ void WatchdogService::setInterval(uint64_t interval)
|
||||
{
|
||||
setProperty("Interval", interval);
|
||||
}
|
||||
+
|
||||
+void WatchdogService::setPreTimeoutInterrupt(
|
||||
+ PreTimeoutInterruptAction preTimeoutInterrupt)
|
||||
+{
|
||||
+ setProperty("PreTimeoutInterrupt", convertForMessage(preTimeoutInterrupt));
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/app/watchdog_service.hpp b/app/watchdog_service.hpp
|
||||
index 141bdb7..32b7461 100644
|
||||
--- a/app/watchdog_service.hpp
|
||||
+++ b/app/watchdog_service.hpp
|
||||
@@ -15,6 +15,8 @@ class WatchdogService
|
||||
|
||||
using Action =
|
||||
sdbusplus::xyz::openbmc_project::State::server::Watchdog::Action;
|
||||
+ using PreTimeoutInterruptAction = sdbusplus::xyz::openbmc_project::State::
|
||||
+ server::Watchdog::PreTimeoutInterruptAction;
|
||||
using TimerUse =
|
||||
sdbusplus::xyz::openbmc_project::State::server::Watchdog::TimerUse;
|
||||
|
||||
@@ -92,6 +94,13 @@ class WatchdogService
|
||||
*/
|
||||
void setInterval(uint64_t interval);
|
||||
|
||||
+ /** @brief Sets the value of the PreTimeoutInterrupt property on the host
|
||||
+ * watchdog
|
||||
+ *
|
||||
+ * @param[in] PreTimeoutInterrupt - The new PreTimeoutInterrupt value
|
||||
+ */
|
||||
+ void setPreTimeoutInterrupt(PreTimeoutInterruptAction preTimeoutInterrupt);
|
||||
+
|
||||
private:
|
||||
/** @brief sdbusplus handle */
|
||||
sdbusplus::bus_t bus;
|
||||
--
|
||||
2.17.1
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
[Unit]
|
||||
Description=Phosphor Inband IPMI
|
||||
Wants=clear-once.service
|
||||
Wants=xyz.openbmc_project.Settings.service
|
||||
After=xyz.openbmc_project.Settings.service
|
||||
After=clear-once.service
|
||||
After=org.openbmc.HostIpmi.service
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
ExecStart=/usr/bin/env ipmid
|
||||
SyslogIdentifier=ipmid
|
||||
RuntimeDirectory = ipmi
|
||||
RuntimeDirectoryPreserve = yes
|
||||
StateDirectory = ipmi
|
||||
Type=dbus
|
||||
BusName=xyz.openbmc_project.Control.Host
|
||||
|
||||
[Install]
|
||||
WantedBy=basic.target
|
||||
Alias=xyz.openbmc_project.Control.Host.service
|
||||
@@ -0,0 +1,3 @@
|
||||
[Unit]
|
||||
Wants=mapper-wait@-xyz-openbmc_project-inventory-system-board-Lux_Baseboard-BMC_Boot.service
|
||||
After=mapper-wait@-xyz-openbmc_project-inventory-system-board-Lux_Baseboard-BMC_Boot.service
|
||||
Reference in New Issue
Block a user