1 #include "config.h"
2 
3 #include "host_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_HOST_STATE_PERSIST_PATH =
16     "/var/lib/phosphor-state-manager/requestedHostTransition";
17 
18 using HostState = sdbusplus::server::xyz::openbmc_project::state::Host;
19 
main(int argc,char ** argv)20 int main(int argc, char** argv)
21 {
22     size_t hostId = 0;
23 
24     int arg;
25     int optIndex = 0;
26 
27     static struct option longOpts[] = {
28         {"host", required_argument, nullptr, 'h'}, {nullptr, 0, nullptr, 0}};
29 
30     while ((arg = getopt_long(argc, argv, "h:", longOpts, &optIndex)) != -1)
31     {
32         switch (arg)
33         {
34             case 'h':
35                 hostId = 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 hostBusName = HostState::interface + std::to_string(hostId);
47     auto hostName = std::string(HostState::namespace_path::host) +
48                     std::to_string(hostId);
49     const auto* objPath = HostState::namespace_path::value;
50     std::string objPathInst =
51         sdbusplus::message::object_path(objPath) / hostName;
52 
53     if (hostId == 0)
54     {
55         // Host State Manager was only support single-host and there only one
56         // file to store persist values, to support multi-host state management,
57         // each service instance access new file path format with prefix 'hostN'
58         // now.For backward compatibility if there is a legacy persist file
59         // exist, rename it to the new file format of host0.
60 
61         fs::path legacyPath{LEGACY_HOST_STATE_PERSIST_PATH};
62         fs::path newPath{std::format(HOST_STATE_PERSIST_PATH, hostId)};
63         if (fs::exists(legacyPath))
64         {
65             fs::rename(legacyPath, newPath);
66         }
67     }
68 
69     // Add sdbusplus ObjectManager.
70     sdbusplus::server::manager_t objManager(bus, objPath);
71 
72     phosphor::state::manager::Host manager(bus, objPathInst.c_str(), hostId);
73 
74     auto dir = fs::path(HOST_STATE_PERSIST_PATH).parent_path();
75     fs::create_directories(dir);
76 
77     // For backwards compatibility, request a busname without host id if
78     // input id is 0.
79     if (hostId == 0)
80     {
81         bus.request_name(HostState::interface);
82     }
83 
84     bus.request_name(hostBusName.c_str());
85 
86     while (true)
87     {
88         bus.process_discard();
89         bus.wait();
90     }
91     return 0;
92 }
93