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