1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
From f49794106c6993b0a53b3b6634b44ae3d2f5cd82 Mon Sep 17 00:00:00 2001
From: Nikita Kosenkov <NKosenkov@IBS.RU>
Date: Thu, 9 Jun 2022 14:26:30 +0300
Subject: [PATCH] x86-power-control: added check BMC restart cause for AlwaysOn
policy
---
src/power_control.cpp | 80 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 78 insertions(+), 2 deletions(-)
diff --git a/src/power_control.cpp b/src/power_control.cpp
index 05aa45c..380ba7e 100644
--- a/src/power_control.cpp
+++ b/src/power_control.cpp
@@ -31,6 +31,7 @@
#include <filesystem>
#include <fstream>
#include <string_view>
+#include <regex>
namespace power_control
{
@@ -857,6 +858,74 @@ void PersistentState::saveState()
appStateStream << stateData.dump(indentationSize);
}
+enum class BMCRestartCause
+{
+ power = 1, // After cold BMC boot
+ watchdog, // After warm BMC reboot
+ unknown // Unknown reboot cause
+};
+
+BMCRestartCause getBmcRestartCause()
+{
+ // U-boot write restart cause to bootargs
+ std::string cmdlineFilePath{"/proc/cmdline"};
+ std::ifstream cmdlineFile{cmdlineFilePath};
+ if(!cmdlineFile.is_open())
+ {
+ lg2::error("BMCRestartCause: cannot open {FILE}", "FILE",
+ cmdlineFilePath);
+
+ return BMCRestartCause::unknown;
+ }
+
+ // Read cmd line from file
+ std::stringstream cmdlineBuffer;
+ cmdlineBuffer << cmdlineFile.rdbuf();
+ cmdlineFile.close();
+
+ std::string cmdline{cmdlineBuffer.str()};
+ if(cmdline.size() == 0)
+ {
+ lg2::error("BMCRestartCause: file {FILE} is empty", "FILE",
+ cmdlineFilePath);
+
+ return BMCRestartCause::unknown;
+ }
+
+ // Parse cmdline with regex
+ std::smatch regexResult;
+ std::regex regexExpr("resetreason=((?:power|watchdog))");
+ if (!std::regex_search(cmdline, regexResult, regexExpr))
+ {
+ lg2::error("BMCRestartCause: error parse file {FILE}", "FILE",
+ cmdlineFilePath);
+
+ return BMCRestartCause::unknown;
+ }
+
+ // Initialize restart cause
+ BMCRestartCause bmcRestartCause = BMCRestartCause::unknown;
+
+ if(regexResult.ready())
+ {
+ // The second element is needed
+ // as it contains the result of the second capturing group
+ if(regexResult.str(1) == "power")
+ {
+ bmcRestartCause = BMCRestartCause::power;
+ }
+ else if (regexResult.str(1) == "watchdog")
+ {
+ bmcRestartCause = BMCRestartCause::watchdog;
+ }
+
+ lg2::info("BmcRestartCause: current BMC restart cause={CAUSE}", "CAUSE",
+ regexResult.str(1));
+ }
+
+ return bmcRestartCause;
+}
+
static constexpr char const* setingsService = "xyz.openbmc_project.Settings";
static constexpr char const* powerRestorePolicyObject =
"/xyz/openbmc_project/control/host0/power_restore_policy";
@@ -1083,8 +1152,15 @@ void PowerRestoreController::invoke()
if (powerRestorePolicy ==
"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
{
- sendPowerControlEvent(Event::powerOnRequest);
- setRestartCauseProperty(getRestartCause(RestartCause::powerPolicyOn));
+ // We check the reason for the BMC restart and
+ // if the BMC is after a cold boot,
+ // then start the "AlwaysOn" policy
+ if (getBmcRestartCause() == BMCRestartCause::power)
+ {
+ sendPowerControlEvent(Event::powerOnRequest);
+ setRestartCauseProperty(
+ getRestartCause(RestartCause::powerPolicyOn));
+ }
}
else if (powerRestorePolicy ==
"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
--
2.35.1
|