blob: ff176151471c0b5af472bfaa067c7cb6c6443bb0 [file] [log] [blame]
#pragma once
#include "boottime_api/boottime_api.h"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "generated/enums/google_boot_time.hpp"
#include "managed_store.hpp"
#include "utils/dbus_utils.hpp"
#include "utils/time_utils.hpp"
#include <algorithm>
#include <cstdint>
#include <cstring>
#include <map>
#include <span>
#include <string>
#include <string_view>
#include <vector>
#ifdef UNIT_TEST_BUILD
#include "test/g3/mock_managed_store.hpp" // NOLINT
#endif
namespace redfish::boot_time_utils
{
struct Checkpoint
{
std::string name;
int64_t wallTimeMs;
int64_t monoTimeMs;
};
struct Duration
{
std::string name;
int64_t durationMs;
};
using CheckpointTuple = std::tuple<std::string, int64_t, int64_t>;
using DurationTuple = std::tuple<std::string, int64_t>;
using BreakdownStagesInMs = std::map<std::string, int64_t>;
constexpr std::string_view kOSStatus = "OSStatus";
constexpr std::string_view kHostState = "HostState";
constexpr std::string_view kOff = "Off";
constexpr std::string_view kOSInactive = "OSStatus:Inactive";
constexpr std::string_view kOSStandby = "OSStatus:Standby";
constexpr std::string_view kHostRunning = "HostState:Running";
constexpr std::string_view kHostOff = "HostState:Off";
constexpr std::string_view kHostTransitioningToOff =
"HostState:TransitioningToOff";
constexpr std::string_view kBMCBootToHost = "BootToHost";
constexpr std::string_view kTrayPowerCycle = "TrayPowerCycle";
// Counts the number of power cycle events happened in the checkpoint list.
// If the list is empty or no power cycle event happened, returns 0.
int64_t PowerCycleCount(std::span<const Checkpoint> checkpoints);
// Parses the boot stage breakdown from the host checkpoints. There are some
// special rules when parsing HW related checkpoints. In addition, some
// breakdowns will be renamed instead of using HW checkpoint name directly for
// readability.
//
// If the input is invalid, returns empty map. Otherwise, returns a dictionary
// where key means stage name and value means duration of that stage.
void ParseEventDurations(std::map<std::string, int64_t>& rebootStages,
std::string_view name,
std::span<const Checkpoint> checkpoints,
const std::vector<std::string_view>& begWords,
const std::vector<std::string_view>& endWords);
void ParseOffDuration(std::map<std::string, int64_t>& rebootStages,
std::span<const Checkpoint> checkpoints);
// Parses the boot stage breakdown from the host checkpoints. There are some
// special rules when parsing HW related checkpoints. In addition, some
// breakdowns will be renamed instead of using HW checkpoint name directly for
// readability.
//
// If the input is invalid, returns empty map. Otherwise, returns a dictionary
// where key means stage name and value means duration of that stage.
BreakdownStagesInMs
ParseHostRebootStages(std::span<const Checkpoint> origCheckpoints);
// Parses the boot stage breakdown from BMC checkpoints.
//
// If the input is invalid, returns empty map. Otherwise, returns a dictionary
// where key means stage name and value means duration of that stage.
BreakdownStagesInMs
ParseBMCRebootStages(std::span<const Checkpoint> checkpoints);
// Updates the kernel stage in the stage map if duration list contains Kernel.
// Kernel stage cannot be recorded because network to BMC is not ready.
// In addition, SystemD provides an accurate measurement of this stage.
// Thus, this code sets Kernel duration from the duration records.
void UpdateKernelStageDuration(std::map<std::string, int64_t>& stages,
std::span<const Duration> duration_list);
// Returns the duration of time offset if it's set in the duration_list.
double GetTimeOffsetDuration(std::span<const Duration> durations);
// Returns total reboot time by using the timestamps from first and last
// checkpoint. When durations are given, the total reboot time will be
// subtracted by the TimeOffset duration. That duration is used for calibrating
// the wall clock offset and difference after reboot.
double GetTotalRebootTime(const Checkpoint& start, const Checkpoint& end,
std::span<const Duration> durations);
// Updates the "Off" stage duration in the dictionary. Off stage duration should
// be total_time - SUM(all other stages). In case of incorrect total_time, the
// calculation result might result in a minus number. In that case, Off stage
// will be set to zero instead.
void UpdateHostOffStageDuration(std::map<std::string, int64_t>& stages,
double totalTimeMs);
void PopulateDefaultBootTimeProperties(
const std::shared_ptr<bmcweb::AsyncResp>& aResp);
void PopulateDurationInResponse(
const std::shared_ptr<bmcweb::AsyncResp>& aResp,
const std::shared_ptr<std::vector<Duration>>& durations);
void PopulateStatIsRebootingInResponse(
const std::shared_ptr<bmcweb::AsyncResp>& aResp,
const std::shared_ptr<bool>& isRebooting);
void PopulateTotalTimeInResponse(
const std::shared_ptr<bmcweb::AsyncResp>& aResp,
const std::shared_ptr<std::vector<Checkpoint>>& checkpoints,
const std::shared_ptr<std::vector<Duration>>& durations);
void GetHostBreakdownStages(
const std::shared_ptr<bmcweb::AsyncResp>& aResp,
const std::shared_ptr<std::vector<Checkpoint>>& hostCheckpoints,
const std::shared_ptr<std::vector<Duration>>& hostDurations);
void GetBmcBreakdownStages(
const std::shared_ptr<bmcweb::AsyncResp>& aResp,
const std::shared_ptr<std::vector<Checkpoint>>& bmcCheckpoints);
void GetHostRebootFlow(
const std::shared_ptr<bmcweb::AsyncResp>& aResp,
const std::shared_ptr<std::vector<Checkpoint>>& hostCheckpoints);
void GetBmcRebootFlow(
const std::shared_ptr<bmcweb::AsyncResp>& aResp,
const std::shared_ptr<std::vector<Checkpoint>>& bmcCheckpoints);
void PopulateStatPowerSourceInResponse(
const std::shared_ptr<bmcweb::AsyncResp>& aResp,
const std::shared_ptr<std::vector<Checkpoint>>& checkpoints);
void GetBootTimeCheckpoints(
const std::shared_ptr<boot_time_monitor::api::IBoottimeApi>& api, const boot_time_monitor::NodeConfig& node,
const std::shared_ptr<std::vector<Checkpoint>>& checkpoints,
const std::function<void()>& successCb);
void GetBootTimeDurations(
const std::shared_ptr<boot_time_monitor::api::IBoottimeApi>& api, const boot_time_monitor::NodeConfig& node,
const std::shared_ptr<std::vector<Duration>>& durations,
const std::function<void()>& successCb);
void GetIsRebooting(const std::shared_ptr<boot_time_monitor::api::IBoottimeApi>& api,
const boot_time_monitor::NodeConfig& node,
const std::shared_ptr<bool>& isRebooting,
const std::function<void()>& successCb);
} // namespace redfish::boot_time_utils