1e73446e3SMatt Spinler /**
2b2e9a4fcSMike Capps * Copyright © 2022 IBM Corporation
3e73446e3SMatt Spinler *
4e73446e3SMatt Spinler * Licensed under the Apache License, Version 2.0 (the "License");
5e73446e3SMatt Spinler * you may not use this file except in compliance with the License.
6e73446e3SMatt Spinler * You may obtain a copy of the License at
7e73446e3SMatt Spinler *
8e73446e3SMatt Spinler * http://www.apache.org/licenses/LICENSE-2.0
9e73446e3SMatt Spinler *
10e73446e3SMatt Spinler * Unless required by applicable law or agreed to in writing, software
11e73446e3SMatt Spinler * distributed under the License is distributed on an "AS IS" BASIS,
12e73446e3SMatt Spinler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e73446e3SMatt Spinler * See the License for the specific language governing permissions and
14e73446e3SMatt Spinler * limitations under the License.
15e73446e3SMatt Spinler */
16f8ae7a5eSMatthew Barth #include "config.h"
17f8ae7a5eSMatthew Barth
18f8ae7a5eSMatthew Barth #ifndef CONTROL_USE_JSON
19e10416ecSMatt Spinler #include "manager.hpp"
20854abad4SGeorge Liu
21854abad4SGeorge Liu #include <CLI/CLI.hpp>
22f8ae7a5eSMatthew Barth #else
23a081956fSMike Capps #include "../utils/flight_recorder.hpp"
2406764946SMatthew Barth #include "json/manager.hpp"
2506764946SMatthew Barth #endif
26b2e9a4fcSMike Capps
27bf8e56f6SMike Capps #include "dbus_paths.hpp"
28f8ae7a5eSMatthew Barth #include "sdbusplus.hpp"
292feab087SMatthew Barth #include "sdeventplus.hpp"
30e73446e3SMatt Spinler
313e1bb274SMatthew Barth #include <phosphor-logging/log.hpp>
323e1bb274SMatthew Barth #include <sdbusplus/bus.hpp>
333e1bb274SMatthew Barth #include <sdeventplus/event.hpp>
34e91ac864SMatthew Barth #include <sdeventplus/source/signal.hpp>
35e91ac864SMatthew Barth #include <stdplus/signal.hpp>
363e1bb274SMatthew Barth
377787def0SMatt Spinler #include <fstream>
387787def0SMatt Spinler
39ee7f6428SMatt Spinler using namespace phosphor::fan::control;
408600d9a0SMatthew Barth using namespace phosphor::logging;
41ee7f6428SMatt Spinler
427787def0SMatt Spinler #ifdef CONTROL_USE_JSON
dumpFlightRecorder()437787def0SMatt Spinler void dumpFlightRecorder()
447787def0SMatt Spinler {
457787def0SMatt Spinler nlohmann::json data;
467787def0SMatt Spinler phosphor::fan::control::json::FlightRecorder::instance().dump(data);
477787def0SMatt Spinler std::ofstream file{json::Manager::dumpFile};
487787def0SMatt Spinler file << std::setw(4) << data;
497787def0SMatt Spinler }
507787def0SMatt Spinler #endif
517787def0SMatt Spinler
main(int argc,char * argv[])52b2e9a4fcSMike Capps int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[])
53e73446e3SMatt Spinler {
542feab087SMatthew Barth auto event = phosphor::fan::util::SDEventPlus::getEvent();
55e73446e3SMatt Spinler
5606764946SMatthew Barth #ifndef CONTROL_USE_JSON
57854abad4SGeorge Liu CLI::App app{"Phosphor Fan Control"};
58854abad4SGeorge Liu
59854abad4SGeorge Liu bool init = false;
60854abad4SGeorge Liu bool control = false;
61854abad4SGeorge Liu app.add_flag("-i,--init", init, "Sets fans to full speed, delays, exits");
62854abad4SGeorge Liu app.add_flag("-c,--control", control, "Start fan control algorithm");
63854abad4SGeorge Liu app.require_option();
64854abad4SGeorge Liu
65854abad4SGeorge Liu try
66ee7f6428SMatt Spinler {
67854abad4SGeorge Liu app.parse(argc, argv);
68854abad4SGeorge Liu }
69854abad4SGeorge Liu catch (const CLI::Error& e)
70854abad4SGeorge Liu {
71854abad4SGeorge Liu return app.exit(e);
72ee7f6428SMatt Spinler }
73ee7f6428SMatt Spinler
7414184131SMatthew Barth Mode mode;
75854abad4SGeorge Liu if (init)
76ee7f6428SMatt Spinler {
7714184131SMatthew Barth mode = Mode::init;
78ee7f6428SMatt Spinler }
79854abad4SGeorge Liu else if (control)
80ee7f6428SMatt Spinler {
8114184131SMatthew Barth mode = Mode::control;
82ee7f6428SMatt Spinler }
8306764946SMatthew Barth #endif
84ee7f6428SMatt Spinler
858600d9a0SMatthew Barth // Attach the event object to the bus object so we can
868600d9a0SMatthew Barth // handle both sd_events (for the timers) and dbus signals.
879403a217SMatthew Barth phosphor::fan::util::SDBusPlus::getBus().attach_event(
889403a217SMatthew Barth event.get(), SD_EVENT_PRIORITY_NORMAL);
898600d9a0SMatthew Barth
90ba7b5feaSMatt Spinler try
91ba7b5feaSMatt Spinler {
9206764946SMatthew Barth #ifdef CONTROL_USE_JSON
93*dfddd648SPatrick Williams phosphor::fan::control::json::FlightRecorder::instance().log(
94*dfddd648SPatrick Williams "main", "Startup");
959403a217SMatthew Barth json::Manager manager(event);
96e91ac864SMatthew Barth
973770a1daSMatthew Barth // Handle loading fan control's config file(s)
983770a1daSMatthew Barth phosphor::fan::JsonConfig config(
993770a1daSMatthew Barth std::bind(&json::Manager::load, &manager));
1003770a1daSMatthew Barth
101e91ac864SMatthew Barth // Enable SIGHUP handling to reload JSON configs
102e91ac864SMatthew Barth stdplus::signal::block(SIGHUP);
103e91ac864SMatthew Barth sdeventplus::source::Signal signal(
104e91ac864SMatthew Barth event, SIGHUP,
105e91ac864SMatthew Barth std::bind(&json::Manager::sighupHandler, &manager,
106e91ac864SMatthew Barth std::placeholders::_1, std::placeholders::_2));
107e91ac864SMatthew Barth
1082fc0a35dSMatt Spinler // Enable SIGUSR1 handling to dump the flight recorder
1092fc0a35dSMatt Spinler stdplus::signal::block(SIGUSR1);
1102fc0a35dSMatt Spinler sdeventplus::source::Signal sigUsr1(
1112fc0a35dSMatt Spinler event, SIGUSR1,
11227f5f4e9SMatt Spinler std::bind(&json::Manager::dumpDebugData, &manager,
1132fc0a35dSMatt Spinler std::placeholders::_1, std::placeholders::_2));
1142fc0a35dSMatt Spinler
115e91ac864SMatthew Barth phosphor::fan::util::SDBusPlus::getBus().request_name(CONTROL_BUSNAME);
11606764946SMatthew Barth #else
1179403a217SMatthew Barth Manager manager(phosphor::fan::util::SDBusPlus::getBus(), event, mode);
118ee7f6428SMatt Spinler
119ee7f6428SMatt Spinler // Init mode will just set fans to max and delay
12014184131SMatthew Barth if (mode == Mode::init)
121ee7f6428SMatt Spinler {
12206764946SMatthew Barth manager.doInit(event);
123ee7f6428SMatt Spinler return 0;
124ee7f6428SMatt Spinler }
12506764946SMatthew Barth #endif
1261cfc2f11SWilliam A. Kennington III return event.loop();
127ba7b5feaSMatt Spinler }
128ba7b5feaSMatt Spinler // Log the useful metadata on these exceptions and let the app
1293e781064SWilliam A. Kennington III // return 1 so it is restarted without a core dump.
130ddb773b2SPatrick Williams catch (const phosphor::fan::util::DBusServiceError& e)
131ba7b5feaSMatt Spinler {
132ba7b5feaSMatt Spinler log<level::ERR>("Uncaught DBus service lookup failure exception",
133ba7b5feaSMatt Spinler entry("PATH=%s", e.path.c_str()),
134ba7b5feaSMatt Spinler entry("INTERFACE=%s", e.interface.c_str()));
135ba7b5feaSMatt Spinler }
136ddb773b2SPatrick Williams catch (const phosphor::fan::util::DBusMethodError& e)
137ba7b5feaSMatt Spinler {
138ba7b5feaSMatt Spinler log<level::ERR>("Uncaught DBus method failure exception",
139ba7b5feaSMatt Spinler entry("BUSNAME=%s", e.busName.c_str()),
140ba7b5feaSMatt Spinler entry("PATH=%s", e.path.c_str()),
141ba7b5feaSMatt Spinler entry("INTERFACE=%s", e.interface.c_str()),
142ba7b5feaSMatt Spinler entry("METHOD=%s", e.method.c_str()));
143ba7b5feaSMatt Spinler }
144ddb773b2SPatrick Williams catch (const phosphor::fan::util::DBusPropertyError& e)
14588923a06SMatthew Barth {
14688923a06SMatthew Barth log<level::ERR>("Uncaught DBus property access failure exception",
14788923a06SMatthew Barth entry("BUSNAME=%s", e.busName.c_str()),
14888923a06SMatthew Barth entry("PATH=%s", e.path.c_str()),
14988923a06SMatthew Barth entry("INTERFACE=%s", e.interface.c_str()),
15088923a06SMatthew Barth entry("PROPERTY=%s", e.property.c_str()));
15188923a06SMatthew Barth }
1523ac99025SMatt Spinler catch (std::exception& e)
1533ac99025SMatt Spinler {
1543ac99025SMatt Spinler #ifdef CONTROL_USE_JSON
1553ac99025SMatt Spinler phosphor::fan::control::json::FlightRecorder::instance().log(
1563ac99025SMatt Spinler "main", "Unexpected exception exit");
1577787def0SMatt Spinler dumpFlightRecorder();
1583ac99025SMatt Spinler #endif
1593ac99025SMatt Spinler throw;
1603ac99025SMatt Spinler }
1613ac99025SMatt Spinler
1623ac99025SMatt Spinler #ifdef CONTROL_USE_JSON
1633ac99025SMatt Spinler phosphor::fan::control::json::FlightRecorder::instance().log(
1643ac99025SMatt Spinler "main", "Abnormal exit");
1657787def0SMatt Spinler dumpFlightRecorder();
1663ac99025SMatt Spinler #endif
167e73446e3SMatt Spinler
1683e781064SWilliam A. Kennington III return 1;
169e73446e3SMatt Spinler }
170