blob: fddfb258389938b27bf4807d4baaea0fa27ef05b [file] [log] [blame]
Matt Spinlere73446e2017-04-10 13:55:52 -05001/**
Mike Cappsb2e9a4f2022-06-13 10:15:42 -04002 * Copyright © 2022 IBM Corporation
Matt Spinlere73446e2017-04-10 13:55:52 -05003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Matthew Barthf8ae7a52021-03-05 10:23:43 -060016#include "config.h"
17
18#ifndef CONTROL_USE_JSON
Matt Spinlere10416e2017-04-10 14:15:53 -050019#include "manager.hpp"
George Liu854abad2023-08-15 17:33:12 +080020
21#include <CLI/CLI.hpp>
Matthew Barthf8ae7a52021-03-05 10:23:43 -060022#else
Mike Cappsa0819562022-06-13 10:17:10 -040023#include "../utils/flight_recorder.hpp"
Matthew Barth06764942021-03-04 09:28:40 -060024#include "json/manager.hpp"
25#endif
Mike Cappsb2e9a4f2022-06-13 10:15:42 -040026
Mike Cappsbf8e56f2022-06-29 14:23:07 -040027#include "dbus_paths.hpp"
Matthew Barthf8ae7a52021-03-05 10:23:43 -060028#include "sdbusplus.hpp"
Matthew Barth2feab082021-06-29 14:50:14 -050029#include "sdeventplus.hpp"
Matt Spinlere73446e2017-04-10 13:55:52 -050030
Anwaar Hadi64b5ac22025-04-04 23:54:53 +000031#include <phosphor-logging/lg2.hpp>
Matthew Barth3e1bb272020-05-26 11:09:21 -050032#include <sdbusplus/bus.hpp>
33#include <sdeventplus/event.hpp>
Matthew Barthe91ac862021-05-25 16:22:17 -050034#include <sdeventplus/source/signal.hpp>
35#include <stdplus/signal.hpp>
Matthew Barth3e1bb272020-05-26 11:09:21 -050036
Matt Spinler7787def2021-10-14 16:33:16 -050037#include <fstream>
38
Matt Spinleree7f6422017-05-09 11:03:14 -050039using namespace phosphor::fan::control;
40
Matt Spinler7787def2021-10-14 16:33:16 -050041#ifdef CONTROL_USE_JSON
42void dumpFlightRecorder()
43{
44 nlohmann::json data;
45 phosphor::fan::control::json::FlightRecorder::instance().dump(data);
46 std::ofstream file{json::Manager::dumpFile};
47 file << std::setw(4) << data;
48}
49#endif
50
Mike Cappsb2e9a4f2022-06-13 10:15:42 -040051int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[])
Matt Spinlere73446e2017-04-10 13:55:52 -050052{
Matthew Barth2feab082021-06-29 14:50:14 -050053 auto event = phosphor::fan::util::SDEventPlus::getEvent();
Matt Spinlere73446e2017-04-10 13:55:52 -050054
Matthew Barth06764942021-03-04 09:28:40 -060055#ifndef CONTROL_USE_JSON
George Liu854abad2023-08-15 17:33:12 +080056 CLI::App app{"Phosphor Fan Control"};
57
58 bool init = false;
59 bool control = false;
60 app.add_flag("-i,--init", init, "Sets fans to full speed, delays, exits");
61 app.add_flag("-c,--control", control, "Start fan control algorithm");
62 app.require_option();
63
64 try
Matt Spinleree7f6422017-05-09 11:03:14 -050065 {
George Liu854abad2023-08-15 17:33:12 +080066 app.parse(argc, argv);
67 }
68 catch (const CLI::Error& e)
69 {
70 return app.exit(e);
Matt Spinleree7f6422017-05-09 11:03:14 -050071 }
72
Matthew Barth14184132017-05-19 14:37:30 -050073 Mode mode;
George Liu854abad2023-08-15 17:33:12 +080074 if (init)
Matt Spinleree7f6422017-05-09 11:03:14 -050075 {
Matthew Barth14184132017-05-19 14:37:30 -050076 mode = Mode::init;
Matt Spinleree7f6422017-05-09 11:03:14 -050077 }
George Liu854abad2023-08-15 17:33:12 +080078 else if (control)
Matt Spinleree7f6422017-05-09 11:03:14 -050079 {
Matthew Barth14184132017-05-19 14:37:30 -050080 mode = Mode::control;
Matt Spinleree7f6422017-05-09 11:03:14 -050081 }
Matthew Barth06764942021-03-04 09:28:40 -060082#endif
Matt Spinleree7f6422017-05-09 11:03:14 -050083
Matthew Barth3e1bb272020-05-26 11:09:21 -050084 // Attach the event object to the bus object so we can
85 // handle both sd_events (for the timers) and dbus signals.
Matthew Barth9403a212021-05-17 09:31:50 -050086 phosphor::fan::util::SDBusPlus::getBus().attach_event(
87 event.get(), SD_EVENT_PRIORITY_NORMAL);
Matthew Barth8600d9a2017-06-23 14:38:05 -050088
Matt Spinlerba7b5fe2018-04-25 15:26:10 -050089 try
90 {
Matthew Barth06764942021-03-04 09:28:40 -060091#ifdef CONTROL_USE_JSON
Patrick Williamsdfddd642024-08-16 15:21:51 -040092 phosphor::fan::control::json::FlightRecorder::instance().log(
93 "main", "Startup");
Matthew Barth9403a212021-05-17 09:31:50 -050094 json::Manager manager(event);
Matthew Barthe91ac862021-05-25 16:22:17 -050095
Matthew Barth3770a1d2021-06-10 15:09:37 -050096 // Handle loading fan control's config file(s)
97 phosphor::fan::JsonConfig config(
98 std::bind(&json::Manager::load, &manager));
99
Matthew Barthe91ac862021-05-25 16:22:17 -0500100 // Enable SIGHUP handling to reload JSON configs
101 stdplus::signal::block(SIGHUP);
102 sdeventplus::source::Signal signal(
103 event, SIGHUP,
104 std::bind(&json::Manager::sighupHandler, &manager,
105 std::placeholders::_1, std::placeholders::_2));
106
Matt Spinler2fc0a352021-10-04 15:10:57 -0500107 // Enable SIGUSR1 handling to dump the flight recorder
108 stdplus::signal::block(SIGUSR1);
109 sdeventplus::source::Signal sigUsr1(
110 event, SIGUSR1,
Matt Spinler27f5f4e2022-09-01 14:57:39 -0500111 std::bind(&json::Manager::dumpDebugData, &manager,
Matt Spinler2fc0a352021-10-04 15:10:57 -0500112 std::placeholders::_1, std::placeholders::_2));
113
Matthew Barthe91ac862021-05-25 16:22:17 -0500114 phosphor::fan::util::SDBusPlus::getBus().request_name(CONTROL_BUSNAME);
Matthew Barth06764942021-03-04 09:28:40 -0600115#else
Matthew Barth9403a212021-05-17 09:31:50 -0500116 Manager manager(phosphor::fan::util::SDBusPlus::getBus(), event, mode);
Matt Spinleree7f6422017-05-09 11:03:14 -0500117
Matthew Barth3e1bb272020-05-26 11:09:21 -0500118 // Init mode will just set fans to max and delay
Matt Spinlerba7b5fe2018-04-25 15:26:10 -0500119 if (mode == Mode::init)
Matthew Barth8600d9a2017-06-23 14:38:05 -0500120 {
Matthew Barth06764942021-03-04 09:28:40 -0600121 manager.doInit(event);
Matt Spinlerba7b5fe2018-04-25 15:26:10 -0500122 return 0;
Matthew Barth8600d9a2017-06-23 14:38:05 -0500123 }
Matthew Barth06764942021-03-04 09:28:40 -0600124#endif
William A. Kennington III1cfc2f12018-10-19 17:29:46 -0700125 return event.loop();
Matt Spinlerba7b5fe2018-04-25 15:26:10 -0500126 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500127 // Log the useful metadata on these exceptions and let the app
128 // return 1 so it is restarted without a core dump.
Patrick Williamsddb773b2021-10-06 11:24:49 -0500129 catch (const phosphor::fan::util::DBusServiceError& e)
Matt Spinlerba7b5fe2018-04-25 15:26:10 -0500130 {
Anwaar Hadi64b5ac22025-04-04 23:54:53 +0000131 lg2::error(
132 "Uncaught DBus service lookup failure exception, Path={PATH}, Interface={INTERFACE}",
133 "PATH", e.path, "INTERFACE", e.interface);
Matt Spinlerba7b5fe2018-04-25 15:26:10 -0500134 }
Patrick Williamsddb773b2021-10-06 11:24:49 -0500135 catch (const phosphor::fan::util::DBusMethodError& e)
Matt Spinlerba7b5fe2018-04-25 15:26:10 -0500136 {
Anwaar Hadi64b5ac22025-04-04 23:54:53 +0000137 lg2::error(
138 "Uncaught DBus method failure exception, Busname={BUSNAME}, Path={PATH}, Interface={INTERFACE}, Method={METHOD}",
139 "BUSNAME", e.busName, "PATH", e.path, "INTERFACE", e.interface,
140 "METHOD", e.method);
Matt Spinlere73446e2017-04-10 13:55:52 -0500141 }
Patrick Williamsddb773b2021-10-06 11:24:49 -0500142 catch (const phosphor::fan::util::DBusPropertyError& e)
Matthew Barth88923a02018-05-11 10:14:44 -0500143 {
Anwaar Hadi64b5ac22025-04-04 23:54:53 +0000144 lg2::error(
145 "Uncaught DBus property access failure exception, Busname={BUSNAME}, Path={PATH}, Interface={INTERFACE}, Property={PROPERTY}",
146 "BUSNAME", e.busName, "PATH", e.path, "INTERFACE", e.interface,
147 "PROPERTY", e.property);
Matthew Barth88923a02018-05-11 10:14:44 -0500148 }
Matt Spinler3ac99022021-10-04 16:02:49 -0500149 catch (std::exception& e)
150 {
151#ifdef CONTROL_USE_JSON
152 phosphor::fan::control::json::FlightRecorder::instance().log(
153 "main", "Unexpected exception exit");
Matt Spinler7787def2021-10-14 16:33:16 -0500154 dumpFlightRecorder();
Matt Spinler3ac99022021-10-04 16:02:49 -0500155#endif
156 throw;
157 }
158
159#ifdef CONTROL_USE_JSON
160 phosphor::fan::control::json::FlightRecorder::instance().log(
161 "main", "Abnormal exit");
Matt Spinler7787def2021-10-14 16:33:16 -0500162 dumpFlightRecorder();
Matt Spinler3ac99022021-10-04 16:02:49 -0500163#endif
Matt Spinlere73446e2017-04-10 13:55:52 -0500164
William A. Kennington III3e781062018-10-19 17:18:34 -0700165 return 1;
Matt Spinlere73446e2017-04-10 13:55:52 -0500166}