xref: /openbmc/phosphor-state-manager/host_state_manager_main.cpp (revision 17846992b844c78415a226247dd6d28e4b33b900)
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