summaryrefslogtreecommitdiff
path: root/meta-yadro/meta-nicole/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Add-support-for-persistent-only-settings.patch
blob: f1e2c4ae4398b05fd7fc1afb21cf857a8cab74c2 (plain)
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
From aaf8a4a5b82baff679f557ed83b25af6ff2919cf Mon Sep 17 00:00:00 2001
From: Alexander Amelkin <a.amelkin@yadro.com>
Date: Thu, 23 May 2019 20:39:57 +0300
Subject: [PATCH] Add support for persistent-only settings

Some settings such as Boot Initiator Mailbox do not support
one-time setting mode (as per IPMI 2.0 specification).

This commit adds support for such persistent-only settings.

Partially resolves openbmc/openbmc#3391

Change-Id: Iec8e2f5bddbc50d270916567effe334f10db2987
Signed-off-by: Alexander Amelkin <a.amelkin@yadro.com>
Signed-off-by: Ivan Mikhaylov <i.mikhaylov@yadro.com>
---
 settings.cpp | 35 +++++++++++++++++++++++++++++++----
 1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/settings.cpp b/settings.cpp
index 2fa2511..6002365 100644
--- a/settings.cpp
+++ b/settings.cpp
@@ -95,19 +95,44 @@ namespace boot
 std::tuple<Path, OneTimeEnabled> setting(const Objects& objects,
                                          const Interface& iface)
 {
-    constexpr auto bootObjCount = 2;
+    constexpr auto ambiguousOperationCount = 2;
     constexpr auto oneTime = "one_time";
     constexpr auto enabledIntf = "xyz.openbmc_project.Object.Enable";
+    bool oneTimeEnabled = false;
 
     const std::vector<Path>& paths = objects.map.at(iface);
     auto count = paths.size();
-    if (count != bootObjCount)
+    if (!count)
     {
-        log<level::ERR>("Exactly two objects expected",
+        // If there are no objects implementing the requested interface,
+        // that must be an error.
+        log<level::ERR>("Interface objects not found",
+                        entry("INTERFACE=%s", iface.c_str()));
+        elog<InternalFailure>();
+    }
+    else if (count < ambiguousOperationCount)
+    {
+        // On the contrary, if there is just one object, that may mean
+        // that this particular interface doesn't support one-time
+        // setting mode (e.g. Boot Initiator Mailbox).
+        // That is not an error, just return the regular setting.
+        // If there's just one object, that's the only kind of setting
+        // mode this interface supports, so just return that setting path.
+        const Path& regularSetting = paths[0];
+        return std::make_tuple(regularSetting, oneTimeEnabled);
+    }
+    else if (count > ambiguousOperationCount)
+    {
+        // Something must be wrong if there are more objects than expected
+        log<level::ERR>("Exactly 1 or 2 interface objects are required",
                         entry("INTERFACE=%s", iface.c_str()),
                         entry("COUNT=%d", count));
         elog<InternalFailure>();
     }
+
+    // We are here because there were exactly two objects implementing the
+    // same interface. Take those two and find out which of them is the
+    // one-time setting, consider the other the persistent setting.
     size_t index = 0;
     if (std::string::npos == paths[0].rfind(oneTime))
     {
@@ -116,6 +141,8 @@ std::tuple<Path, OneTimeEnabled> setting(const Objects& objects,
     const Path& oneTimeSetting = paths[index];
     const Path& regularSetting = paths[!index];
 
+    // Now see if the one-time setting is enabled and return the path for it
+    // if so. Otherwise return the path for the persistent setting.
     auto method = objects.bus.new_method_call(
         objects.service(oneTimeSetting, iface).c_str(), oneTimeSetting.c_str(),
         ipmi::PROP_INTF, "Get");
@@ -131,7 +158,7 @@ std::tuple<Path, OneTimeEnabled> setting(const Objects& objects,
 
     std::variant<bool> enabled;
     reply.read(enabled);
-    auto oneTimeEnabled = std::get<bool>(enabled);
+    oneTimeEnabled = std::get<bool>(enabled);
     const Path& setting = oneTimeEnabled ? oneTimeSetting : regularSetting;
     return std::make_tuple(setting, oneTimeEnabled);
 }
-- 
2.21.1