1 #include "config.h"
2 
3 #include "chassis_state_manager.hpp"
4 
5 #include <getopt.h>
6 
7 #include <sdbusplus/bus.hpp>
8 
9 #include <cstdlib>
10 #include <exception>
11 #include <filesystem>
12 #include <format>
13 #include <iostream>
14 
15 constexpr auto LEGACY_POH_COUNTER_PERSIST_PATH =
16     "/var/lib/phosphor-state-manager/POHCounter";
17 constexpr auto LEGACY_STATE_CHANGE_PERSIST_PATH =
18     "/var/lib/phosphor-state-manager/chassisStateChangeTime";
19 
20 using ChassisState = sdbusplus::server::xyz::openbmc_project::state::Chassis;
21 
main(int argc,char ** argv)22 int main(int argc, char** argv)
23 {
24     size_t chassisId = 0;
25     int arg;
26     int optIndex = 0;
27     static struct option longOpts[] = {
28         {"chassis", required_argument, nullptr, 'c'}, {nullptr, 0, nullptr, 0}};
29 
30     while ((arg = getopt_long(argc, argv, "c:", longOpts, &optIndex)) != -1)
31     {
32         switch (arg)
33         {
34             case 'c':
35                 chassisId = std::stoul(optarg);
36                 break;
37             default:
38                 break;
39         }
40     }
41 
42     namespace fs = std::filesystem;
43 
44     auto bus = sdbusplus::bus::new_default();
45 
46     auto chassisBusName = ChassisState::interface + std::to_string(chassisId);
47     const auto* objPath = ChassisState::namespace_path::value;
48     auto chassisName = std::string(ChassisState::namespace_path::chassis) +
49                        std::to_string(chassisId);
50     std::string objPathInst =
51         sdbusplus::message::object_path(objPath) / chassisName;
52 
53     if (chassisId == 0)
54     {
55         // Chassis State Manager was only support single-chassis and there only
56         // two file to store persist values(POH and state change time), to
57         // support multi-chassis state management, each service access new file
58         // paths with prefix 'chassisN', if any legacy persist file is exist,
59         // rename it to the new file format of chassis0.
60 
61         fs::path legacyPohPath{LEGACY_POH_COUNTER_PERSIST_PATH};
62         fs::path legacyStateChangePath{LEGACY_STATE_CHANGE_PERSIST_PATH};
63         fs::path newPohPath{std::format(POH_COUNTER_PERSIST_PATH, chassisId)};
64         fs::path newStateChangePath{
65             std::format(CHASSIS_STATE_CHANGE_PERSIST_PATH, chassisId)};
66         if (fs::exists(legacyPohPath))
67         {
68             fs::rename(legacyPohPath, newPohPath);
69         }
70         if (fs::exists(legacyStateChangePath))
71         {
72             fs::rename(legacyStateChangePath, newStateChangePath);
73         }
74     }
75 
76     // Add sdbusplus ObjectManager.
77     sdbusplus::server::manager_t objManager(bus, objPath);
78     phosphor::state::manager::Chassis manager(bus, objPathInst.c_str(),
79                                               chassisId);
80 
81     // For backwards compatibility, request a busname without chassis id if
82     // input id is 0.
83     if (chassisId == 0)
84     {
85         bus.request_name(ChassisState::interface);
86     }
87 
88     bus.request_name(chassisBusName.c_str());
89     manager.startPOHCounter();
90     return 0;
91 }
92