blob: 243feaf74e3e993c5096fab4ef44dd40eab4887b [file] [log] [blame]
Kuiying Wang3a044402019-02-19 15:00:11 +08001/*
2// Copyright (c) 2019 Intel 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#pragma once
Manojkiran Eda84855ab2021-12-05 11:09:02 +053017#include <config.h>
Kuiying Wang3a044402019-02-19 15:00:11 +080018#include <fcntl.h>
19#include <unistd.h>
20
21#include <cereal/access.hpp>
22#include <cereal/archives/json.hpp>
23#include <cereal/cereal.hpp>
ZhikuiRen993d4dd2020-01-29 14:25:44 -080024#include <cereal/types/map.hpp>
Manojkiran Eda84a4c192021-02-25 15:23:42 +053025#include <cereal/types/tuple.hpp>
Kuiying Wang3a044402019-02-19 15:00:11 +080026#include <cereal/types/vector.hpp>
Kuiying Wang3a044402019-02-19 15:00:11 +080027#include <phosphor-logging/elog-errors.hpp>
ZhikuiRen993d4dd2020-01-29 14:25:44 -080028#include <xyz/openbmc_project/Collection/DeleteAll/server.hpp>
Kuiying Wang3a044402019-02-19 15:00:11 +080029#include <xyz/openbmc_project/Common/error.hpp>
30#include <xyz/openbmc_project/State/Boot/PostCode/server.hpp>
31#include <xyz/openbmc_project/State/Host/server.hpp>
32
Jonathan Domaneddf9602022-11-23 09:29:41 -080033#include <chrono>
34#include <filesystem>
35#include <fstream>
36#include <iostream>
37
38const static constexpr char* CurrentBootCycleCountName =
ZhikuiRen993d4dd2020-01-29 14:25:44 -080039 "CurrentBootCycleCount";
Jonathan Domaneddf9602022-11-23 09:29:41 -080040const static constexpr char* CurrentBootCycleIndexName =
Kuiying Wang3a044402019-02-19 15:00:11 +080041 "CurrentBootCycleIndex";
Kumar Thangavelfd45f782020-09-01 22:59:00 +053042
Jonathan Domanc7fed5c2022-11-23 11:14:42 -080043const static constexpr char* PostCodePath =
44 "/xyz/openbmc_project/state/boot/raw";
45const static constexpr char* PostCodeListPathPrefix =
46 "/var/lib/phosphor-post-code-manager/host";
47const static constexpr char* HostStatePathPrefix =
48 "/xyz/openbmc_project/state/host";
Kuiying Wang3a044402019-02-19 15:00:11 +080049
50struct EventDeleter
51{
Jonathan Domaneddf9602022-11-23 09:29:41 -080052 void operator()(sd_event* event) const
Kuiying Wang3a044402019-02-19 15:00:11 +080053 {
Manojkiran Edade8d3a52021-12-05 12:51:07 +053054 sd_event_unref(event);
Kuiying Wang3a044402019-02-19 15:00:11 +080055 }
56};
57using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
Manojkiran Eda84a4c192021-02-25 15:23:42 +053058using primarycode_t = uint64_t;
59using secondarycode_t = std::vector<uint8_t>;
60using postcode_t = std::tuple<primarycode_t, secondarycode_t>;
Manojkiran Eda410ba292021-12-05 10:55:56 +053061namespace fs = std::filesystem;
Kuiying Wang3a044402019-02-19 15:00:11 +080062namespace StateServer = sdbusplus::xyz::openbmc_project::State::server;
63
64using post_code =
65 sdbusplus::xyz::openbmc_project::State::Boot::server::PostCode;
ZhikuiRen993d4dd2020-01-29 14:25:44 -080066using delete_all =
67 sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll;
Kuiying Wang3a044402019-02-19 15:00:11 +080068
ZhikuiRen993d4dd2020-01-29 14:25:44 -080069struct PostCode : sdbusplus::server::object_t<post_code, delete_all>
Kuiying Wang3a044402019-02-19 15:00:11 +080070{
Jonathan Domanc7fed5c2022-11-23 11:14:42 -080071 PostCode(sdbusplus::bus_t& bus, const char* path, int nodeIndex) :
ZhikuiRen993d4dd2020-01-29 14:25:44 -080072 sdbusplus::server::object_t<post_code, delete_all>(bus, path), bus(bus),
Jonathan Domanc7fed5c2022-11-23 11:14:42 -080073 node(nodeIndex),
74 postCodeListPath(PostCodeListPathPrefix + std::to_string(node)),
Kuiying Wang3a044402019-02-19 15:00:11 +080075 propertiesChangedSignalRaw(
76 bus,
Jonathan Domanc7fed5c2022-11-23 11:14:42 -080077 sdbusplus::bus::match::rules::propertiesChanged(
78 PostCodePath + std::to_string(node),
79 "xyz.openbmc_project.State.Boot.Raw"),
Jonathan Domaneddf9602022-11-23 09:29:41 -080080 [this](sdbusplus::message_t& msg) {
Jonathan Domanc7fed5c2022-11-23 11:14:42 -080081 std::string intfName;
Manojkiran Eda84a4c192021-02-25 15:23:42 +053082 std::map<std::string, std::variant<postcode_t>> msgData;
Jonathan Domanc7fed5c2022-11-23 11:14:42 -080083 msg.read(intfName, msgData);
Kuiying Wang3a044402019-02-19 15:00:11 +080084 // Check if it was the Value property that changed.
85 auto valPropMap = msgData.find("Value");
Jonathan Domanc7fed5c2022-11-23 11:14:42 -080086 if (valPropMap != msgData.end())
Kuiying Wang3a044402019-02-19 15:00:11 +080087 {
Jonathan Domanc7fed5c2022-11-23 11:14:42 -080088 this->savePostCodes(
89 std::get<postcode_t>(valPropMap->second));
Kuiying Wang3a044402019-02-19 15:00:11 +080090 }
91 }),
92 propertiesChangedSignalCurrentHostState(
93 bus,
Jonathan Domanc7fed5c2022-11-23 11:14:42 -080094 sdbusplus::bus::match::rules::propertiesChanged(
95 HostStatePathPrefix + std::to_string(node),
96 "xyz.openbmc_project.State.Host"),
Jonathan Domaneddf9602022-11-23 09:29:41 -080097 [this](sdbusplus::message_t& msg) {
Jonathan Domanc7fed5c2022-11-23 11:14:42 -080098 std::string intfName;
Patrick Williams9d91a392020-05-13 17:59:26 -050099 std::map<std::string, std::variant<std::string>> msgData;
Jonathan Domanc7fed5c2022-11-23 11:14:42 -0800100 msg.read(intfName, msgData);
Kuiying Wang3a044402019-02-19 15:00:11 +0800101 // Check if it was the Value property that changed.
102 auto valPropMap = msgData.find("CurrentHostState");
Jonathan Domanc7fed5c2022-11-23 11:14:42 -0800103 if (valPropMap != msgData.end())
Kuiying Wang3a044402019-02-19 15:00:11 +0800104 {
Jonathan Domanc7fed5c2022-11-23 11:14:42 -0800105 StateServer::Host::HostState currentHostState =
106 StateServer::Host::convertHostStateFromString(
107 std::get<std::string>(valPropMap->second));
108 if (currentHostState == StateServer::Host::HostState::Off)
Kuiying Wang3a044402019-02-19 15:00:11 +0800109 {
Jonathan Domanc7fed5c2022-11-23 11:14:42 -0800110 if (this->postCodes.empty())
Kuiying Wang3a044402019-02-19 15:00:11 +0800111 {
Jonathan Domanc7fed5c2022-11-23 11:14:42 -0800112 std::cerr << "HostState changed to OFF. Empty "
113 "postcode log, keep boot cycle at "
114 << this->currentBootCycleIndex
115 << std::endl;
116 }
117 else
118 {
119 this->postCodes.clear();
Kuiying Wang3a044402019-02-19 15:00:11 +0800120 }
121 }
122 }
123 })
124 {
125 phosphor::logging::log<phosphor::logging::level::INFO>(
126 "PostCode is created");
Jonathan Domanc7fed5c2022-11-23 11:14:42 -0800127 fs::create_directories(postCodeListPath);
128 deserialize(postCodeListPath / CurrentBootCycleIndexName,
129 currentBootCycleIndex);
ZhikuiRen993d4dd2020-01-29 14:25:44 -0800130 uint16_t count = 0;
Jonathan Domanc7fed5c2022-11-23 11:14:42 -0800131 deserialize(postCodeListPath / CurrentBootCycleCountName, count);
ZhikuiRen993d4dd2020-01-29 14:25:44 -0800132 currentBootCycleCount(count);
Manojkiran Edaaed7b3d2021-06-19 09:39:30 +0530133 maxBootCycleNum(MAX_BOOT_CYCLE_COUNT);
Kuiying Wang3a044402019-02-19 15:00:11 +0800134 }
Jonathan Domaneddf9602022-11-23 09:29:41 -0800135 ~PostCode() {}
Kuiying Wang3a044402019-02-19 15:00:11 +0800136
Manojkiran Eda84a4c192021-02-25 15:23:42 +0530137 std::vector<postcode_t> getPostCodes(uint16_t index) override;
138 std::map<uint64_t, postcode_t>
ZhikuiRen993d4dd2020-01-29 14:25:44 -0800139 getPostCodesWithTimeStamp(uint16_t index) override;
140 void deleteAll() override;
Kuiying Wang3a044402019-02-19 15:00:11 +0800141
142 private:
ZhikuiRen993d4dd2020-01-29 14:25:44 -0800143 void incrBootCycle();
144 uint16_t getBootNum(const uint16_t index) const;
145
Jonathan Domaneddf9602022-11-23 09:29:41 -0800146 sdbusplus::bus_t& bus;
Jonathan Domanc7fed5c2022-11-23 11:14:42 -0800147 int node;
ZhikuiRen993d4dd2020-01-29 14:25:44 -0800148 std::chrono::time_point<std::chrono::steady_clock> firstPostCodeTimeSteady;
149 uint64_t firstPostCodeUsSinceEpoch;
Manojkiran Eda84a4c192021-02-25 15:23:42 +0530150 std::map<uint64_t, postcode_t> postCodes;
Jonathan Domanc7fed5c2022-11-23 11:14:42 -0800151 fs::path postCodeListPath;
152 uint16_t currentBootCycleIndex = 0;
Kuiying Wang3a044402019-02-19 15:00:11 +0800153 sdbusplus::bus::match_t propertiesChangedSignalRaw;
154 sdbusplus::bus::match_t propertiesChangedSignalCurrentHostState;
Jonathan Domanc7fed5c2022-11-23 11:14:42 -0800155
156 void savePostCodes(postcode_t code);
157 fs::path serialize(const fs::path& path);
Jonathan Domaneddf9602022-11-23 09:29:41 -0800158 bool deserialize(const fs::path& path, uint16_t& index);
159 bool deserializePostCodes(const fs::path& path,
160 std::map<uint64_t, postcode_t>& codes);
Kuiying Wang3a044402019-02-19 15:00:11 +0800161};