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 <algorithm> 18 #include <map> 19 #include <string> 20 #include "util.hpp" 21 22 using namespace std::literals::string_literals; 23 24 template <typename T> 25 struct BusMeetsMSL 26 { 27 std::string path; 28 29 BusMeetsMSL(const std::string& p) 30 :path(p) {} 31 32 auto operator()(const T& arg) 33 { 34 // Query each service hosting 35 // xyz.openbmc_project.Inventory.Decorator.MeetsMinimumShipLevel. 36 37 const auto& busName = arg.first; 38 return util::sdbusplus::getProperty<bool>( 39 busName, 40 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(), 59 arg.second.end(), 60 BusMeetsMSL<typename decltype(arg.second)::value_type>(path)); 61 } 62 }; 63 64 int main(void) 65 { 66 auto mslVerificationRequired = 67 util::sdbusplus::getProperty<bool>( 68 "/xyz/openbmc_project/control/minimum_ship_level_required"s, 69 "xyz.openbmc_project.Control.MinimumShipLevel"s, 70 "MinimumShipLevelRequired"s); 71 72 if (!mslVerificationRequired) 73 { 74 return 0; 75 } 76 77 // Obtain references to all objects hosting 78 // xyz.openbmc_project.Inventory.Decorator.MeetsMinimumShipLevel 79 // with a mapper subtree query. For each object, validate that 80 // the minimum ship level has been met. 81 82 using SubTreeType = 83 std::map< 84 std::string, 85 std::map<std::string, std::vector<std::string>>>; 86 87 auto subtree = 88 util::sdbusplus::callMethodAndRead<SubTreeType>( 89 "xyz.openbmc_project.ObjectMapper"s, 90 "/xyz/openbmc_project/object_mapper"s, 91 "xyz.openbmc_project.ObjectMapper"s, 92 "GetSubTree"s, 93 "/"s, 94 0, 95 std::vector<std::string>{ 96 "xyz.openbmc_project.Inventory" 97 ".Decorator.MeetsMinimumShipLevel"s}); 98 99 auto result = std::all_of( 100 subtree.begin(), 101 subtree.end(), 102 PathMeetsMSL<SubTreeType::value_type>()); 103 104 if (!result) 105 { 106 phosphor::logging::log<phosphor::logging::level::INFO>( 107 "The physical system configuration does not " 108 "satisfy the minimum ship level."); 109 110 return 1; 111 } 112 113 return 0; 114 } 115