blob: a4b3ece5517ec7599ed6c218a48a5961288c239f [file] [log] [blame]
/**
* Copyright © 2017 IBM Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "util.hpp"
#include <algorithm>
#include <map>
#include <string>
using namespace std::literals::string_literals;
template <typename T>
struct BusMeetsMSL
{
std::string path;
BusMeetsMSL(const std::string& p) : path(p)
{
}
auto operator()(const T& arg)
{
// Query each service hosting
// xyz.openbmc_project.Inventory.Decorator.MeetsMinimumShipLevel.
const auto& busName = arg.first;
return util::sdbusplus::getProperty<bool>(
busName, path,
"xyz.openbmc_project.Inventory."
"Decorator.MeetsMinimumShipLevel"s,
"MeetsMinimumShipLevel"s);
}
};
template <typename T>
struct PathMeetsMSL
{
auto operator()(const T& arg)
{
// A given path in the mapper response is composed of
// a map of services/interfaces. Validate each service
// that hosts the MSL interface meets the MSL.
const auto& path = arg.first;
return std::all_of(
arg.second.begin(), arg.second.end(),
BusMeetsMSL<typename decltype(arg.second)::value_type>(path));
}
};
int main(void)
{
auto mslVerificationRequired = util::sdbusplus::getProperty<bool>(
"/xyz/openbmc_project/control/minimum_ship_level_required"s,
"xyz.openbmc_project.Control.MinimumShipLevel"s,
"MinimumShipLevelRequired"s);
if (!mslVerificationRequired)
{
return 0;
}
// Obtain references to all objects hosting
// xyz.openbmc_project.Inventory.Decorator.MeetsMinimumShipLevel
// with a mapper subtree query. For each object, validate that
// the minimum ship level has been met.
using SubTreeType =
std::map<std::string, std::map<std::string, std::vector<std::string>>>;
auto subtree = util::sdbusplus::callMethodAndRead<SubTreeType>(
"xyz.openbmc_project.ObjectMapper"s,
"/xyz/openbmc_project/object_mapper"s,
"xyz.openbmc_project.ObjectMapper"s, "GetSubTree"s, "/"s, 0,
std::vector<std::string>{"xyz.openbmc_project.Inventory"
".Decorator.MeetsMinimumShipLevel"s});
auto result = std::all_of(subtree.begin(), subtree.end(),
PathMeetsMSL<SubTreeType::value_type>());
if (!result)
{
phosphor::logging::log<phosphor::logging::level::INFO>(
"The physical system configuration does not "
"satisfy the minimum ship level.");
return 1;
}
return 0;
}