Skip to content
This repository has been archived by the owner on Oct 28, 2024. It is now read-only.

Enumerate policies on start #2

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 143 additions & 12 deletions NodeManagerProxy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,11 @@ struct NonSuccessCompletionCode final : public sdbusplus::exception_t
"xyz.openbmc_project.Common.Error.NonSuccessCompletionCode: The "
"operation failed. Got non-success completion code.";

NonSuccessCompletionCode(uint8_t cc, const std::vector<uint8_t> &resp) :
cc{cc}, resp{resp}
{
}

const char *name() const noexcept override
{
return errName;
Expand All @@ -789,6 +794,19 @@ struct NonSuccessCompletionCode final : public sdbusplus::exception_t
{
return errWhat;
};

uint8_t getCc(void) const
{
return cc;
}
const std::vector<uint8_t> &getResp(void) const
{
return resp;
}

private:
uint8_t cc;
std::vector<uint8_t> resp;
};

/**
Expand Down Expand Up @@ -933,7 +951,7 @@ void ipmiSendReceive(std::shared_ptr<sdbusplus::asio::connection> conn,
phosphor::logging::log<phosphor::logging::level::ERR>(
"error while sending IPMB request, wrong cc: ",
phosphor::logging::entry("%d", cc));
throw NonSuccessCompletionCode();
throw NonSuccessCompletionCode(cc, dataReceived);
}

if (dataReceived.size() != sizeof(resp))
Expand Down Expand Up @@ -984,12 +1002,12 @@ class Policy
static constexpr uint8_t dmtfPowerPolicyId = 254;
static constexpr uint8_t dmtfPowerOemPolicyId = 255;

boost::container::flat_map<uint8_t, std::string> triggerIdToName = {
{0, "AlwaysOn"},
{1, "InletTemperature"},
{2, "MissingReadingsTimeout"},
{3, "TimeAfterHostReset"},
{6, "GPIO"}};
static const inline boost::container::flat_map<uint8_t, std::string>
triggerIdToName = {{0, "AlwaysOn"},
{1, "InletTemperature"},
{2, "MissingReadingsTimeout"},
{3, "TimeAfterHostReset"},
{6, "GPIO"}};

uint8_t triggerIdFromName(const std::string &nameToBeFound)
{
Expand All @@ -1004,13 +1022,14 @@ class Policy
return 255;
}

std::string setOrUpdatePolicy(PolicyParams &params)
std::string setOrUpdatePolicy(const PolicyParams &params,
bool enableArg = false)
{
nmIpmiSetNmPolicyReq req = {0};

ipmiSetIntelIanaNumber(req.iana);
req.domainId = domainId;
req.policyEnabled = 0x0; // Policy disabled during creation
req.policyEnabled = enableArg;
req.policyId = getIdAsInt();
req.triggerType = triggerIdFromName(params.triggerType);
req.configurationAction = 0x1; // Create or modify policy
Expand All @@ -1030,6 +1049,7 @@ class Policy
limit = params.limit;
failureAction = params.limitException;
correctionTime = params.correctionInMs;
enabled = enableArg;

return dbusPath;
}
Expand Down Expand Up @@ -1420,8 +1440,117 @@ class Domain
createCapabilitesInterface(server);
createPolicyManagerInterface(server);
createStatisticsInterface(server);
for (auto &&p : storedPolicies{*this})
{
if (std::get<0>(p) != Policy::dmtfPowerOemPolicyId)
createOrUpdatePolicy(server, std::to_string(std::get<0>(p)),
std::get<1>(p), std::get<2>(p));
}
}

class storedPolicies
{
const Domain &domain;

public:
storedPolicies(const Domain &domain) : domain{domain}
{
}

class iterator
: public std::iterator<std::input_iterator_tag,
std::tuple<int, const PolicyParams &, bool>>
{
const Domain &domain;

uint8_t policyIdInt;
PolicyParams params;
bool enabled;

void fetchPolicyParams(void)
{
nmIpmiGetNmPolicyReq req = {0};
ipmiSetIntelIanaNumber(req.iana);
req.domainId = domain.id;
nmIpmiGetNmPolicyResp resp = {0};

while (policyIdInt != 0)
{
req.policyId = policyIdInt;
try
{
ipmiSendReceive<nmIpmiGetNmPolicyReq,
nmIpmiGetNmPolicyResp>(
domain.conn, ipmiGetNmPolicyNetFn,
ipmiGetNmPolicyLun, ipmiGetNmPolicyCmd, req, resp);

enabled = resp.policyEnabled;
params.triggerType =
Policy::triggerIdToName.at(resp.triggerType);
params.powerCorrectionType = resp.cpuPowerCorrection;
params.policyStorage = resp.storageOption;
params.limit = resp.limit;
params.correctionInMs = resp.correctionTime;
params.triggerLimit = resp.triggerLimit;
params.statReportingPeriod = resp.statsPeriod;
params.limitException =
(resp.sendAlert << 1) | resp.shutdownSystem;
break;
}
catch (NonSuccessCompletionCode &e)
{
if (e.getCc() == 0x80)
{
// next valid policy ID
policyIdInt = e.getResp()[3];
}
else
throw(e);
}
}
}

public:
explicit iterator(uint8_t id, const Domain &domain) :
policyIdInt{id}, domain{domain}
{
fetchPolicyParams();
}
iterator &operator++()
{
policyIdInt++;
fetchPolicyParams();
return *this;
}
iterator operator++(int)
{
iterator retval = *this;
++(*this);
return retval;
}
bool operator==(iterator other) const
{
return policyIdInt == other.policyIdInt;
}
bool operator!=(iterator other) const
{
return !(*this == other);
}
value_type operator*() const
{
return {policyIdInt, params, enabled};
}
};
iterator begin() const
{
return iterator{1, domain};
}
iterator end() const
{
return iterator{0, domain};
}
};

private:
uint8_t id;
std::string dbusPath;
Expand Down Expand Up @@ -1485,13 +1614,14 @@ class Domain

std::string createOrUpdatePolicy(sdbusplus::asio::object_server &server,
std::string policyId,
PolicyParams &policyParams)
const PolicyParams &policyParams,
bool enable = false)
{
for (auto &policy : policies)
{
if (policy->getId() == policyId)
{
return policy->setOrUpdatePolicy(policyParams);
return policy->setOrUpdatePolicy(policyParams, enable);
}
}
auto policyTmp = std::make_unique<Policy>(
Expand All @@ -1506,7 +1636,8 @@ class Domain
}
}
});
std::string policyPath = policyTmp->setOrUpdatePolicy(policyParams);
std::string policyPath =
policyTmp->setOrUpdatePolicy(policyParams, enable);
policies.emplace_back(std::move(policyTmp));
return policyPath;
}
Expand Down