1 #include "config.h"
2
3 #include "host_state_manager.hpp"
4
5 #include <getopt.h>
6
7 #include <phosphor-logging/lg2.hpp>
8 #include <sdbusplus/bus.hpp>
9
10 #include <cstdlib>
11 #include <exception>
12 #include <filesystem>
13 #include <format>
14 #include <iostream>
15
16 PHOSPHOR_LOG2_USING;
17
18 constexpr auto LEGACY_HOST_STATE_PERSIST_PATH =
19 "/var/lib/phosphor-state-manager/requestedHostTransition";
20
21 using HostState = sdbusplus::server::xyz::openbmc_project::state::Host;
22
main(int argc,char ** argv)23 int main(int argc, char** argv)
24 {
25 size_t hostId = 0;
26
27 int arg;
28 int optIndex = 0;
29
30 static struct option longOpts[] = {
31 {"host", required_argument, nullptr, 'h'}, {nullptr, 0, nullptr, 0}};
32
33 while ((arg = getopt_long(argc, argv, "h:", longOpts, &optIndex)) != -1)
34 {
35 switch (arg)
36 {
37 case 'h':
38 hostId = std::stoul(optarg);
39 break;
40 default:
41 break;
42 }
43 }
44
45 namespace fs = std::filesystem;
46
47 auto bus = sdbusplus::bus::new_default();
48
49 auto hostBusName = HostState::interface + std::to_string(hostId);
50 auto hostName = std::string(HostState::namespace_path::host) +
51 std::to_string(hostId);
52 const auto* objPath = HostState::namespace_path::value;
53 std::string objPathInst =
54 sdbusplus::message::object_path(objPath) / hostName;
55
56 if (hostId == 0)
57 {
58 // Host State Manager was only support single-host and there only one
59 // file to store persist values, to support multi-host state management,
60 // each service instance access new file path format with prefix 'hostN'
61 // now.For backward compatibility if there is a legacy persist file
62 // exist, rename it to the new file format of host0.
63
64 fs::path legacyPath{LEGACY_HOST_STATE_PERSIST_PATH};
65 fs::path newPath{std::format(HOST_STATE_PERSIST_PATH, hostId)};
66 if (fs::exists(legacyPath))
67 {
68 try
69 {
70 fs::rename(legacyPath, newPath);
71 }
72 catch (const fs::filesystem_error& e)
73 {
74 error("Failed to rename legacy file {LEGACY} to {NEW}: {ERROR}",
75 "LEGACY", legacyPath, "NEW", newPath, "ERROR", e.what());
76 }
77 }
78 }
79
80 // Add sdbusplus ObjectManager.
81 sdbusplus::server::manager_t objManager(bus, objPath);
82
83 phosphor::state::manager::Host manager(bus, objPathInst.c_str(), hostId);
84
85 auto dir = fs::path(HOST_STATE_PERSIST_PATH).parent_path();
86 try
87 {
88 fs::create_directories(dir);
89 }
90 catch (const fs::filesystem_error& e)
91 {
92 error("Failed to create persist directory {DIR}: {ERROR}", "DIR", dir,
93 "ERROR", e.what());
94 return 1;
95 }
96
97 // For backwards compatibility, request a busname without host id if
98 // input id is 0.
99 if (hostId == 0)
100 {
101 bus.request_name(HostState::interface);
102 }
103
104 bus.request_name(hostBusName.c_str());
105
106 while (true)
107 {
108 bus.process_discard();
109 bus.wait();
110 }
111 return 0;
112 }
113