Skip to content

Commit a25e264

Browse files
committed
CFAM: Support FailoverImminent field in CFAM
This new field is used so that one BMC can tell that the other is starting a failover to allow it to prepare. It will use bit 18 in the first scratchpad register. Tested: New unit tests pass On D-Bus: ``` $ busctl get-property xyz.openbmc_project.State.BMC.Redundancy.Sibling \ /xyz/openbmc_project/state/bmc1 \ xyz.openbmc_project.State.BMC.Redundancy.Sibling FailoverImminent b false ``` In cfamstool output: ``` $ ./cfamstool -d | grep -e 'Local BMC' -e 'Sibling BMC' -e Imminent Local BMC CFAM-S scratchpad fields Failover Imminent false Sibling BMC CFAM-S scratchpad fields Failover Imminent false ``` Change-Id: I2c885841aa55a70ec8f6cc8bc84a2b640993302e Signed-off-by: Matt Spinler <[email protected]>
1 parent 6c94b7f commit a25e264

13 files changed

+114
-16
lines changed

rbmc-cfam-daemon/README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ The `rbmc-cfam-daemon` meson option will enable building this code.
2929
| Provisioned | 1 | 13 | 1 |
3030
| BMC State | 1 | 14 | 3 |
3131
| Sibling Comms OK | 1 | 17 | 1 |
32-
| Reserved | 1 | 18 | 6 |
32+
| Failover Imminent | 1 | 18 | 1 |
33+
| Reserved | 1 | 19 | 5 |
3334
| Heartbeat | 1 | 24 | 8 |
3435
| FW Version | 2 | 0 | 32 |
3536
| Reserved | 3 | 0 | 32 |
@@ -58,6 +59,9 @@ property from the BMC state daemon.
5859

5960
**Sibling Comms OK**: If this BMC can read the sibling BMC's CFAM.
6061

62+
**Failover Imminent**: If the sibling will start a failover soon. Only the
63+
passive BMC will set this, soon before it starts a failover to become active.
64+
6165
**Heartbeat**: This field is incremented by one every time the CFAM application
6266
receives the Heartbeat signal from the RBMC state manager application. This can
6367
be used by the sibling to know the management daemon is alive.
@@ -80,6 +84,7 @@ Failovers Allowed true
8084
Provisioned true
8185
BMC State xyz.openbmc_project.State.BMC.BMCState.Ready
8286
Sibling Communication OK true
87+
Failover Imminent false
8388
Heartbeat 0x25
8489
FW Version 0x1c9c4045
8590

@@ -92,6 +97,7 @@ Failovers Allowed true
9297
Provisioned true
9398
BMC State xyz.openbmc_project.State.BMC.BMCState.Ready
9499
Sibling Communication OK true
100+
Failover Imminent false
95101
Heartbeat 0x24
96102
FW Version 0x1c9c4045
97103
```

rbmc-cfam-daemon/src/bmc_cfam.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class BMCCFAM
3434
provisioned,
3535
bmcState,
3636
siblingCommsOK,
37+
failoverImminent,
3738
heartbeat,
3839
fwVersion
3940
};
@@ -53,6 +54,8 @@ class BMCCFAM
5354
{Field::bmcState, {cfam::ScratchPadReg::one, 14, 3, "BMC State"}},
5455
{Field::siblingCommsOK,
5556
{cfam::ScratchPadReg::one, 17, 1, "Sibling Communication OK"}},
57+
{Field::failoverImminent,
58+
{cfam::ScratchPadReg::one, 18, 1, "Failover Imminent"}},
5659
{Field::heartbeat, {cfam::ScratchPadReg::one, 24, 8, "Heartbeat"}},
5760
{Field::fwVersion, {cfam::ScratchPadReg::two, 0, 32, "FW Version"}}};
5861

rbmc-cfam-daemon/src/cfams_tool.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ std::string formatValue(BMCCFAM::Field field, uint32_t value)
2929
case failoversAllowed:
3030
case provisioned:
3131
case siblingCommsOK:
32+
case failoverImminent:
3233
result = std::format("{}", value ? "true" : "false");
3334
break;
3435
case role:

rbmc-cfam-daemon/src/local_bmc.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ sdbusplus::async::task<> LocalBMC::start()
2222
ctx, [this](auto state) { bmcStateChanged(state); },
2323
[this](auto role) { roleChanged(role); },
2424
[this](auto enabled) { redEnabledChanged(enabled); },
25-
[this](auto allowed) { failoversAllowedChanged(allowed); });
25+
[this](auto allowed) { failoversAllowedChanged(allowed); },
26+
[this](auto imminent) { failoverImminentChanged(imminent); });
2627

2728
co_await writeRedundancyProps();
2829
co_await writeBMCState();
@@ -122,18 +123,28 @@ void LocalBMC::failoversAllowedChanged(bool allowed)
122123
cfam.writeFailoversAllowed(allowed);
123124
}
124125

126+
void LocalBMC::failoverImminentChanged(bool imminent)
127+
{
128+
lg2::info("Local Failover Imminent changed to {IMMINENT}", "IMMINENT",
129+
imminent);
130+
cfam.writeFailoverImminent(imminent);
131+
}
132+
125133
sdbusplus::async::task<> LocalBMC::writeRedundancyProps()
126134
{
127135
try
128136
{
129-
auto [role, enabled, allowed] = co_await services->getRedundancyProps();
137+
auto [role, enabled, allowed,
138+
imminent] = co_await services->getRedundancyProps();
130139
lg2::info(
131-
"Initial values of local role, redEnabled, fo allowed: {ROLE} {ENABLED} {ALLOWED}",
132-
"ROLE", role, "ENABLED", enabled, "ALLOWED", allowed);
140+
"Initial values of local role, redEnabled, fo allowed, fo imminent: {ROLE} {ENABLED} {ALLOWED} {IMMINENT}",
141+
"ROLE", role, "ENABLED", enabled, "ALLOWED", allowed, "IMMINENT",
142+
imminent);
133143

134144
cfam.writeRole(role);
135145
cfam.writeRedundancyEnabled(enabled);
136146
cfam.writeFailoversAllowed(allowed);
147+
cfam.writeFailoverImminent(imminent);
137148
}
138149
catch (const sdbusplus::exception_t& e)
139150
{

rbmc-cfam-daemon/src/local_bmc.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,17 @@ class LocalBMC
138138
*/
139139
void failoversAllowedChanged(bool allowed);
140140

141+
/**
142+
* @brief Callback function for when the failover
143+
* imminent D-Bus property changes.
144+
*
145+
* Writes the new value into the CFAM in the
146+
* FailoverImminent field.
147+
*
148+
* @param[in] imminent - the value to write
149+
*/
150+
void failoverImminentChanged(bool imminent);
151+
141152
/**
142153
* @brief The context object
143154
*/

rbmc-cfam-daemon/src/local_cfam.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,17 @@ void LocalCFAM::writeSiblingCommsOK(bool ok)
126126
}
127127
}
128128

129+
void LocalCFAM::writeFailoverImminent(bool imminent)
130+
{
131+
auto rc = writeField(Field::failoverImminent, imminent);
132+
if (rc != 0)
133+
{
134+
lg2::error("Failed writing Failover Imminent field {IMM} in local CFAM",
135+
"IMM", imminent);
136+
throw std::system_error(rc, std::generic_category());
137+
}
138+
}
139+
129140
std::expected<uint32_t, int> LocalCFAM::readField(Field field)
130141
{
131142
auto data = cfamAccess.readScratchReg(cfamFields.at(field).reg);

rbmc-cfam-daemon/src/local_cfam.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,13 @@ class LocalCFAM : public BMCCFAM
120120
*/
121121
void writeSiblingCommsOK(bool ok);
122122

123+
/**
124+
* @brief Writes the failover imminent field into the CFAM
125+
*
126+
* @param[in] imminent - If a failover is imminent
127+
*/
128+
void writeFailoverImminent(bool imminent);
129+
123130
/**
124131
* @brief Increments the heartbeat field in the CFAM
125132
*/

rbmc-cfam-daemon/src/services.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,16 @@ sdbusplus::async::task<std::string> getService(sdbusplus::async::context& ctx,
3838

3939
} // namespace util
4040

41-
Services::Services(sdbusplus::async::context& ctx,
42-
BMCStateCallback&& stateCallback,
43-
RoleCallback&& roleCallback,
44-
RedEnabledCallback&& redEnabledCallback,
45-
FailoversAllowedCallback&& failoversAllowedCallback) :
41+
Services::Services(
42+
sdbusplus::async::context& ctx, BMCStateCallback&& stateCallback,
43+
RoleCallback&& roleCallback, RedEnabledCallback&& redEnabledCallback,
44+
FailoversAllowedCallback&& failoversAllowedCallback,
45+
FailoverImminentCallback&& failoverImminentCallback) :
4646
ctx(ctx), bmcStateCallback(std::move(stateCallback)),
4747
roleCallback(std::move(roleCallback)),
4848
redEnabledCallback(std::move(redEnabledCallback)),
4949
failoversAllowedCallback(std::move(failoversAllowedCallback)),
50+
failoverImminentCallback(std::move(failoverImminentCallback)),
5051
localBMCPath(
5152
sdbusplus::message::object_path{RedNSPath::value} / RedNSPath::bmc)
5253
{
@@ -147,7 +148,7 @@ sdbusplus::async::task<Services::BMCState> Services::getBMCState()
147148
.current_bmc_state();
148149
}
149150

150-
sdbusplus::async::task<std::tuple<Services::Role, bool, bool>>
151+
sdbusplus::async::task<std::tuple<Services::Role, bool, bool, bool>>
151152
Services::getRedundancyProps()
152153
{
153154
auto service = co_await util::getService(ctx, localBMCPath,
@@ -162,7 +163,7 @@ sdbusplus::async::task<std::tuple<Services::Role, bool, bool>>
162163
.properties();
163164

164165
co_return std::make_tuple(props.role, props.redundancy_enabled,
165-
props.failovers_allowed);
166+
props.failovers_allowed, props.failover_imminent);
166167
}
167168

168169
sdbusplus::async::task<> Services::watchBMCStateProp()
@@ -216,6 +217,12 @@ sdbusplus::async::task<> Services::watchRedundancyProps()
216217
{
217218
failoversAllowedCallback(std::get<bool>(it->second));
218219
}
220+
221+
it = propertyMap.find("FailoverImminent");
222+
if (it != propertyMap.end())
223+
{
224+
failoverImminentCallback(std::get<bool>(it->second));
225+
}
219226
}
220227
}
221228

@@ -269,6 +276,12 @@ sdbusplus::async::task<> Services::watchBMCInterfaceAdded()
269276
{
270277
failoversAllowedCallback(std::get<bool>(propIt->second));
271278
}
279+
280+
propIt = props.find("FailoverImminent");
281+
if (propIt != props.end())
282+
{
283+
failoverImminentCallback(std::get<bool>(propIt->second));
284+
}
272285
}
273286
}
274287
}

rbmc-cfam-daemon/src/services.hpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class Services
2424
using RoleCallback = std::function<void(Role)>;
2525
using RedEnabledCallback = std::function<void(bool)>;
2626
using FailoversAllowedCallback = std::function<void(bool)>;
27+
using FailoverImminentCallback = std::function<void(bool)>;
2728

2829
Services() = delete;
2930
~Services() = default;
@@ -44,11 +45,14 @@ class Services
4445
* redundancyEnabled prop changes
4546
* @param[in] failoversAllowedCallback - Function to run when this prop
4647
* changes
48+
* @param[in] failoverImminentCallback - Function to run when this
49+
* prop changes
4750
*/
4851
Services(sdbusplus::async::context& ctx, BMCStateCallback&& stateCallback,
4952
RoleCallback&& roleCallback,
5053
RedEnabledCallback&& redEnabledCallback,
51-
FailoversAllowedCallback&& failoversAllowedCallback);
54+
FailoversAllowedCallback&& failoversAllowedCallback,
55+
FailoverImminentCallback&& failoverImminentCallback);
5256

5357
/**
5458
* @brief Reads the CurrentBMCState property
@@ -60,9 +64,10 @@ class Services
6064
/**
6165
* @brief Reads the role and redundancyEnabled properties
6266
*
63-
* @return - A tuple of the role and redundancyEnabled property
67+
* @return - A tuple of role, redundancyEnabled, FailoversAllowed
68+
* FailoverImminent
6469
*/
65-
sdbusplus::async::task<std::tuple<Services::Role, bool, bool>>
70+
sdbusplus::async::task<std::tuple<Services::Role, bool, bool, bool>>
6671
getRedundancyProps();
6772

6873
/**
@@ -139,6 +144,11 @@ class Services
139144
*/
140145
FailoversAllowedCallback failoversAllowedCallback;
141146

147+
/**
148+
* @brief The callback function for FailoverImminent
149+
*/
150+
FailoverImminentCallback failoverImminentCallback;
151+
142152
/**
143153
* @brief Object path for this BMC's redundancy and state interfaces.
144154
*/

rbmc-cfam-daemon/src/sibling_bmc.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ void SiblingBMC::read()
7171
createdObject);
7272
siblingObject->failoversAllowed(cfam.getFailoversAllowed(), createdObject);
7373
siblingObject->currentBMCState(cfam.getBMCState(), createdObject);
74+
siblingObject->failoverImminent(cfam.getFailoverImminent(), createdObject);
7475

7576
auto version = std::format("{:08X}", cfam.getFWVersion());
7677
siblingObject->version(version, createdObject);

0 commit comments

Comments
 (0)