blob: 33920b1a565ed7f0170df107cbc98f8d35a1bed1 [file] [log] [blame]
#include "boottime_api/boottime_api.h"
#include "dbus_handler.hpp"
#include "gen.hpp"
#include "log.hpp"
#include "psm_handler.hpp"
#include "systemd_handler.hpp"
#include <fmt/printf.h>
#include <getopt.h> // For getopt_long
#include <boost/asio/io_service.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/server.hpp>
namespace btm = boot_time_monitor;
/*
* +-----------------+
* | main |
* +-----------------+
* |
* |
* v
* +-----------------+
* | data_sources |
* +-----------------+
* | | |
* | | psm_handler
* | dbus_handler
* systemd_handler
* |
* | interface between data source and actual checkpoint/duration records
* v
* +-----------------+
* | api |
* +-----------------+
* |
* | store checkpoints/durations
* v
* +-----------------+
* | files |
* +-----------------+
*
*/
void print_usage(const char* prog_name)
{
fmt::print(stderr, "Usage: {} [options]\n", prog_name);
fmt::print(stderr, "Options:\n");
fmt::print(stderr,
" -h, --help Show this help message and exit\n");
fmt::print(stderr,
" --host_count <num> Set number of hosts (default: 1)\n");
fmt::print(stderr,
" --bmc_count <num> Set number of BMCs (default: 1)\n");
}
int main(int argc, char* argv[])
{
int64_t hostCount = 1; // Default host count
int64_t bmcCount = 1; // Default BMC count
const struct option long_options[] = {
{"help", no_argument, nullptr, 'h'},
{"host_count", required_argument, nullptr, 'o'}, // 'o' for hOst
{"bmc_count", required_argument, nullptr, 'b'}, // 'b' for Bmc
{nullptr, 0, nullptr, 0}};
int opt;
int option_index = 0;
while ((opt = getopt_long(argc, argv, "h", long_options, &option_index)) !=
-1)
{
switch (opt)
{
case 'h':
print_usage(argv[0]);
return 0;
case 'o':
hostCount = std::strtol(optarg, nullptr, 10);
break;
case 'b':
bmcCount = std::strtol(optarg, nullptr, 10);
break;
default: /* '?' */
print_usage(argv[0]);
return 1;
}
}
if (hostCount < 0)
{
fmt::print(stderr, "hostCount({}) must be greater than zero.\n",
hostCount);
return 1;
}
if (bmcCount < 0)
{
fmt::print(stderr, "bmcCount({}) must be greater than zero.\n",
bmcCount);
return 1;
}
boost::asio::io_service io;
auto conn = std::make_shared<sdbusplus::asio::connection>(io);
conn->request_name("com.google.gbmc.boot_time_monitor");
auto server = std::make_shared<sdbusplus::asio::object_server>(conn);
auto& bus = static_cast<sdbusplus::bus::bus&>(*conn);
std::vector<btm::NodeConfig> hostNodeConfigs;
std::vector<btm::NodeConfig> bmcNodeConfigs;
std::vector<std::unique_ptr<btm::dbus::Handler>> hostDbusHandlers;
std::vector<std::unique_ptr<btm::dbus::Handler>> bmcDbusHandlers;
std::vector<btm::psm::Handler> psmHandlers;
std::shared_ptr<btm::api::BoottimeApi> api =
std::make_shared<btm::api::BoottimeApi>();
hostNodeConfigs.reserve(hostCount);
for (int i = 0; i < hostCount; i++)
{
hostNodeConfigs.emplace_back(btm::gen::GenHostNodeName(i),
std::string(btm::kBootTimeTagHost));
}
bmcNodeConfigs.reserve(bmcCount);
for (int i = 0; i < bmcCount; i++)
{
bmcNodeConfigs.emplace_back(btm::gen::GenBmcNodeName(bmcCount, i),
std::string(btm::kBootTimeTagBMC));
}
for (auto& nodeConfig : hostNodeConfigs)
{
absl::Status status = api->RegisterNode(nodeConfig);
btm::log::LogIfError(status);
hostDbusHandlers.emplace_back(std::make_unique<btm::dbus::Handler>(
bus, nodeConfig, btm::gen::GenDbusConfig(nodeConfig), api));
psmHandlers.emplace_back(
bus, nodeConfig,
btm::gen::GenPSMConfig(hostNodeConfigs, nodeConfig), api);
}
for (auto& nodeConfig : bmcNodeConfigs)
{
absl::Status status = api->RegisterNode(nodeConfig);
btm::log::LogIfError(status);
bmcDbusHandlers.emplace_back(std::make_unique<btm::dbus::Handler>(
bus, nodeConfig, btm::gen::GenDbusConfig(nodeConfig), api));
}
// Set up async systemd handler to update checkpoints/durations on this bmc.
btm::systemd::Handler systemdHandler(conn, api, bmcNodeConfigs[0]);
io.run();
return 0;
}