blob: dfbf876b6020d49ab35f4e73f8f3a7cdef53cfe4 [file] [log] [blame]
Michael Tritzd50f6572017-09-05 16:38:11 -05001#include <getopt.h>
Michael Tritz3ed10082017-03-20 23:28:09 -05002#include <iostream>
3#include <map>
4#include <string>
5#include <config.h>
6#include <systemd/sd-bus.h>
7#include <sdbusplus/server.hpp>
8#include <phosphor-logging/log.hpp>
Deepak Kodihalli55f132b2017-07-25 07:36:06 -05009#include <phosphor-logging/elog-errors.hpp>
Michael Tritz3ed10082017-03-20 23:28:09 -050010#include "host_state_manager.hpp"
Deepak Kodihalli55f132b2017-07-25 07:36:06 -050011#include "settings.hpp"
12#include "xyz/openbmc_project/Common/error.hpp"
13#include "xyz/openbmc_project/Control/Power/RestorePolicy/server.hpp"
Michael Tritz3ed10082017-03-20 23:28:09 -050014
15namespace phosphor
16{
17namespace state
18{
19namespace manager
20{
21
22using namespace phosphor::logging;
Deepak Kodihalli55f132b2017-07-25 07:36:06 -050023using namespace sdbusplus::xyz::openbmc_project::Common::Error;
24using namespace sdbusplus::xyz::openbmc_project::Control::Power::server;
Michael Tritz3ed10082017-03-20 23:28:09 -050025
26constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
27constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
28constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
29
30constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
31
Michael Tritz3ed10082017-03-20 23:28:09 -050032std::string getService(sdbusplus::bus::bus& bus, std::string path,
33 std::string interface)
34{
Andrew Geissler58a18012018-01-19 19:36:05 -080035 auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
36 MAPPER_INTERFACE, "GetObject");
Michael Tritz3ed10082017-03-20 23:28:09 -050037
38 mapper.append(path, std::vector<std::string>({interface}));
39 auto mapperResponseMsg = bus.call(mapper);
40
41 if (mapperResponseMsg.is_method_error())
42 {
Andrew Geissler58a18012018-01-19 19:36:05 -080043 log<level::ERR>("Error in mapper call", entry("PATH=%s", path.c_str()),
Michael Tritz3ed10082017-03-20 23:28:09 -050044 entry("INTERFACE=%s", interface.c_str()));
45 throw std::runtime_error("Error in mapper call");
46 }
47
48 std::map<std::string, std::vector<std::string>> mapperResponse;
49 mapperResponseMsg.read(mapperResponse);
50 if (mapperResponse.empty())
51 {
52 log<level::ERR>("Error reading mapper response",
53 entry("PATH=%s", path.c_str()),
54 entry("INTERFACE=%s", interface.c_str()));
55 throw std::runtime_error("Error reading mapper response");
56 }
57
58 return mapperResponse.begin()->first;
59}
60
61std::string getProperty(sdbusplus::bus::bus& bus, std::string path,
62 std::string interface, std::string propertyName)
63{
64 sdbusplus::message::variant<std::string> property;
65 std::string service = getService(bus, path, interface);
66
Andrew Geissler58a18012018-01-19 19:36:05 -080067 auto method = bus.new_method_call(service.c_str(), path.c_str(),
68 PROPERTY_INTERFACE, "Get");
Michael Tritz3ed10082017-03-20 23:28:09 -050069
70 method.append(interface, propertyName);
71 auto reply = bus.call(method);
72
73 if (reply.is_method_error())
74 {
75 log<level::ERR>("Error in property Get",
76 entry("PROPERTY=%s", propertyName.c_str()));
77 throw std::runtime_error("Error in property Get");
78 }
79
80 reply.read(property);
81
82 if (sdbusplus::message::variant_ns::get<std::string>(property).empty())
83 {
84 log<level::ERR>("Error reading property response",
85 entry("PROPERTY=%s", propertyName.c_str()));
86 throw std::runtime_error("Error reading property response");
87 }
88
89 return sdbusplus::message::variant_ns::get<std::string>(property);
90}
91
92void setProperty(sdbusplus::bus::bus& bus, std::string path,
93 std::string interface, std::string property, std::string value)
94{
95 sdbusplus::message::variant<std::string> variantValue = value;
96 std::string service = getService(bus, path, interface);
97
Andrew Geissler58a18012018-01-19 19:36:05 -080098 auto method = bus.new_method_call(service.c_str(), path.c_str(),
99 PROPERTY_INTERFACE, "Set");
Michael Tritz3ed10082017-03-20 23:28:09 -0500100
101 method.append(interface, property, variantValue);
102 bus.call_noreply(method);
103
104 return;
105}
106
107} // namespace manager
108} // namespace state
Andrew Geisslera965cf02018-08-31 08:37:05 -0700109} // namespace phosphor
Michael Tritz3ed10082017-03-20 23:28:09 -0500110
Michael Tritzd50f6572017-09-05 16:38:11 -0500111int main(int argc, char** argv)
Michael Tritz3ed10082017-03-20 23:28:09 -0500112{
Deepak Kodihalli55f132b2017-07-25 07:36:06 -0500113 using namespace phosphor::logging;
114
Michael Tritzd50f6572017-09-05 16:38:11 -0500115 std::string hostPath = "/xyz/openbmc_project/state/host0";
116 int arg;
117 int optIndex = 0;
118
Andrew Geissler58a18012018-01-19 19:36:05 -0800119 static struct option longOpts[] = {{"host", required_argument, 0, 'h'},
120 {0, 0, 0, 0}};
Michael Tritzd50f6572017-09-05 16:38:11 -0500121
Andrew Geissler58a18012018-01-19 19:36:05 -0800122 while ((arg = getopt_long(argc, argv, "h:", longOpts, &optIndex)) != -1)
Michael Tritzd50f6572017-09-05 16:38:11 -0500123 {
124 switch (arg)
125 {
126 case 'h':
Andrew Geissler58a18012018-01-19 19:36:05 -0800127 hostPath =
128 std::string("/xyz/openbmc_project/state/host") + optarg;
Michael Tritzd50f6572017-09-05 16:38:11 -0500129 break;
130 default:
131 break;
132 }
133 }
134
Michael Tritz3ed10082017-03-20 23:28:09 -0500135 auto bus = sdbusplus::bus::new_default();
136
Deepak Kodihalli55f132b2017-07-25 07:36:06 -0500137 using namespace settings;
138 Objects settings(bus);
139
Michael Tritz3ed10082017-03-20 23:28:09 -0500140 using namespace phosphor::state::manager;
141 namespace server = sdbusplus::xyz::openbmc_project::State::server;
142
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500143 // This application is only run if chassis power is off
Michael Tritz3ed10082017-03-20 23:28:09 -0500144
Andrew Geissler58a18012018-01-19 19:36:05 -0800145 auto method = bus.new_method_call(
146 settings.service(settings.powerRestorePolicy, powerRestoreIntf).c_str(),
147 settings.powerRestorePolicy.c_str(), "org.freedesktop.DBus.Properties",
148 "Get");
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500149 method.append(powerRestoreIntf, "PowerRestorePolicy");
150 auto reply = bus.call(method);
151 if (reply.is_method_error())
Michael Tritz3ed10082017-03-20 23:28:09 -0500152 {
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500153 log<level::ERR>("Error in PowerRestorePolicy Get");
154 elog<InternalFailure>();
155 }
Deepak Kodihalli55f132b2017-07-25 07:36:06 -0500156
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500157 sdbusplus::message::variant<std::string> result;
158 reply.read(result);
159 auto powerPolicy = result.get<std::string>();
Michael Tritz3ed10082017-03-20 23:28:09 -0500160
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500161 log<level::INFO>("Host power is off, checking power policy",
162 entry("POWER_POLICY=%s", powerPolicy.c_str()));
Michael Tritz3ed10082017-03-20 23:28:09 -0500163
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500164 if (RestorePolicy::Policy::AlwaysOn ==
165 RestorePolicy::convertPolicyFromString(powerPolicy))
166 {
167 log<level::INFO>("power_policy=ALWAYS_POWER_ON, powering host on");
Andrew Geissler58a18012018-01-19 19:36:05 -0800168 setProperty(bus, hostPath, HOST_BUSNAME, "RequestedHostTransition",
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500169 convertForMessage(server::Host::Transition::On));
170 }
Andrew Geissler58a18012018-01-19 19:36:05 -0800171 else if (RestorePolicy::Policy::Restore ==
172 RestorePolicy::convertPolicyFromString(powerPolicy))
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500173 {
174 log<level::INFO>("power_policy=RESTORE, restoring last state");
Michael Tritz3ed10082017-03-20 23:28:09 -0500175
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500176 // Read last requested state and re-request it to execute it
Andrew Geissler58a18012018-01-19 19:36:05 -0800177 auto hostReqState =
178 getProperty(bus, hostPath, HOST_BUSNAME, "RequestedHostTransition");
179 setProperty(bus, hostPath, HOST_BUSNAME, "RequestedHostTransition",
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500180 hostReqState);
Michael Tritz3ed10082017-03-20 23:28:09 -0500181 }
182
183 return 0;
184}