xref: /openbmc/phosphor-dbus-monitor/mslverify/verify.cpp (revision ecef119120e31b5bdf0d316c7303a9ce48831464)
1 /**
2  * Copyright © 2017 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "util.hpp"
18 
19 #include <algorithm>
20 #include <map>
21 #include <string>
22 
23 using namespace std::literals::string_literals;
24 
25 template <typename T>
26 struct BusMeetsMSL
27 {
28     std::string path;
29 
30     explicit BusMeetsMSL(const std::string& p) : path(p)
31     {}
32 
33     auto operator()(const T& arg)
34     {
35         // Query each service hosting
36         // xyz.openbmc_project.Inventory.Decorator.MeetsMinimumShipLevel.
37 
38         const auto& busName = arg.first;
39         return util::sdbusplus::getProperty<bool>(
40             busName, path,
41             "xyz.openbmc_project.Inventory."
42             "Decorator.MeetsMinimumShipLevel"s,
43             "MeetsMinimumShipLevel"s);
44     }
45 };
46 
47 template <typename T>
48 struct PathMeetsMSL
49 {
50     auto operator()(const T& arg)
51     {
52         // A given path in the mapper response is composed of
53         // a map of services/interfaces.  Validate each service
54         // that hosts the MSL interface meets the MSL.
55 
56         const auto& path = arg.first;
57         return std::all_of(
58             arg.second.begin(), arg.second.end(),
59             BusMeetsMSL<typename decltype(arg.second)::value_type>(path));
60     }
61 };
62 
63 int main(void)
64 {
65     auto mslVerificationRequired = util::sdbusplus::getProperty<bool>(
66         "/xyz/openbmc_project/control/minimum_ship_level_required"s,
67         "xyz.openbmc_project.Control.MinimumShipLevel"s,
68         "MinimumShipLevelRequired"s);
69 
70     if (!mslVerificationRequired)
71     {
72         return 0;
73     }
74 
75     // Obtain references to all objects hosting
76     // xyz.openbmc_project.Inventory.Decorator.MeetsMinimumShipLevel
77     // with a mapper subtree query.  For each object, validate that
78     // the minimum ship level has been met.
79 
80     using SubTreeType =
81         std::map<std::string, std::map<std::string, std::vector<std::string>>>;
82 
83     auto subtree = util::sdbusplus::callMethodAndRead<SubTreeType>(
84         "xyz.openbmc_project.ObjectMapper"s,
85         "/xyz/openbmc_project/object_mapper"s,
86         "xyz.openbmc_project.ObjectMapper"s, "GetSubTree"s, "/"s, 0,
87         std::vector<std::string>{"xyz.openbmc_project.Inventory"
88                                  ".Decorator.MeetsMinimumShipLevel"s});
89 
90     auto result = std::all_of(subtree.begin(), subtree.end(),
91                               PathMeetsMSL<SubTreeType::value_type>());
92 
93     if (!result)
94     {
95         lg2::info(
96             "The physical system configuration does not satisfy the minimum ship level.");
97 
98         return 1;
99     }
100 
101     return 0;
102 }
103