blob: 201f7b0f933638dfb4a05740910ede727bc44e9c [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 Spinleree7f6422017-05-09 11:03:14 -050019#include "argument.hpp"
Matt Spinlere10416e2017-04-10 14:15:53 -050020#include "manager.hpp"
Matthew Barthf8ae7a52021-03-05 10:23:43 -060021#else
Mike Cappsa0819562022-06-13 10:17:10 -040022#include "../utils/flight_recorder.hpp"
Matthew Barth06764942021-03-04 09:28:40 -060023#include "json/manager.hpp"
24#endif
Mike Cappsb2e9a4f2022-06-13 10:15:42 -040025
Matthew Barthf8ae7a52021-03-05 10:23:43 -060026#include "sdbusplus.hpp"
Matthew Barth2feab082021-06-29 14:50:14 -050027#include "sdeventplus.hpp"
Matt Spinlere73446e2017-04-10 13:55:52 -050028
Matthew Barth3e1bb272020-05-26 11:09:21 -050029#include <phosphor-logging/log.hpp>
30#include <sdbusplus/bus.hpp>
31#include <sdeventplus/event.hpp>
Matthew Barthe91ac862021-05-25 16:22:17 -050032#include <sdeventplus/source/signal.hpp>
33#include <stdplus/signal.hpp>
Matthew Barth3e1bb272020-05-26 11:09:21 -050034
Matt Spinler7787def2021-10-14 16:33:16 -050035#include <fstream>
36
Matt Spinleree7f6422017-05-09 11:03:14 -050037using namespace phosphor::fan::control;
Matthew Barth8600d9a2017-06-23 14:38:05 -050038using namespace phosphor::logging;
Matt Spinleree7f6422017-05-09 11:03:14 -050039
Matt Spinler7787def2021-10-14 16:33:16 -050040#ifdef CONTROL_USE_JSON
41void dumpFlightRecorder()
42{
43 nlohmann::json data;
44 phosphor::fan::control::json::FlightRecorder::instance().dump(data);
45 std::ofstream file{json::Manager::dumpFile};
46 file << std::setw(4) << data;
47}
48#endif
49
Mike Cappsb2e9a4f2022-06-13 10:15:42 -040050int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[])
Matt Spinlere73446e2017-04-10 13:55:52 -050051{
Matthew Barth2feab082021-06-29 14:50:14 -050052 auto event = phosphor::fan::util::SDEventPlus::getEvent();
Matt Spinlere73446e2017-04-10 13:55:52 -050053
Matthew Barth06764942021-03-04 09:28:40 -060054#ifndef CONTROL_USE_JSON
55 phosphor::fan::util::ArgumentParser args(argc, argv);
Matt Spinleree7f6422017-05-09 11:03:14 -050056 if (argc != 2)
57 {
58 args.usage(argv);
William A. Kennington III3e781062018-10-19 17:18:34 -070059 return 1;
Matt Spinleree7f6422017-05-09 11:03:14 -050060 }
61
Matthew Barth14184132017-05-19 14:37:30 -050062 Mode mode;
Matt Spinleree7f6422017-05-09 11:03:14 -050063
64 if (args["init"] == "true")
65 {
Matthew Barth14184132017-05-19 14:37:30 -050066 mode = Mode::init;
Matt Spinleree7f6422017-05-09 11:03:14 -050067 }
68 else if (args["control"] == "true")
69 {
Matthew Barth14184132017-05-19 14:37:30 -050070 mode = Mode::control;
Matt Spinleree7f6422017-05-09 11:03:14 -050071 }
72 else
73 {
74 args.usage(argv);
William A. Kennington III3e781062018-10-19 17:18:34 -070075 return 1;
Matt Spinleree7f6422017-05-09 11:03:14 -050076 }
Matthew Barth06764942021-03-04 09:28:40 -060077#endif
Matt Spinleree7f6422017-05-09 11:03:14 -050078
Matthew Barth3e1bb272020-05-26 11:09:21 -050079 // Attach the event object to the bus object so we can
80 // handle both sd_events (for the timers) and dbus signals.
Matthew Barth9403a212021-05-17 09:31:50 -050081 phosphor::fan::util::SDBusPlus::getBus().attach_event(
82 event.get(), SD_EVENT_PRIORITY_NORMAL);
Matthew Barth8600d9a2017-06-23 14:38:05 -050083
Matt Spinlerba7b5fe2018-04-25 15:26:10 -050084 try
85 {
Matthew Barth06764942021-03-04 09:28:40 -060086#ifdef CONTROL_USE_JSON
Matt Spinler3ac99022021-10-04 16:02:49 -050087 phosphor::fan::control::json::FlightRecorder::instance().log("main",
88 "Startup");
Matthew Barth9403a212021-05-17 09:31:50 -050089 json::Manager manager(event);
Matthew Barthe91ac862021-05-25 16:22:17 -050090
Matthew Barth3770a1d2021-06-10 15:09:37 -050091 // Handle loading fan control's config file(s)
92 phosphor::fan::JsonConfig config(
93 std::bind(&json::Manager::load, &manager));
94
Matthew Barthe91ac862021-05-25 16:22:17 -050095 // Enable SIGHUP handling to reload JSON configs
96 stdplus::signal::block(SIGHUP);
97 sdeventplus::source::Signal signal(
98 event, SIGHUP,
99 std::bind(&json::Manager::sighupHandler, &manager,
100 std::placeholders::_1, std::placeholders::_2));
101
Matt Spinler2fc0a352021-10-04 15:10:57 -0500102 // Enable SIGUSR1 handling to dump the flight recorder
103 stdplus::signal::block(SIGUSR1);
104 sdeventplus::source::Signal sigUsr1(
105 event, SIGUSR1,
106 std::bind(&json::Manager::sigUsr1Handler, &manager,
107 std::placeholders::_1, std::placeholders::_2));
108
Matthew Barthe91ac862021-05-25 16:22:17 -0500109 phosphor::fan::util::SDBusPlus::getBus().request_name(CONTROL_BUSNAME);
Matthew Barth06764942021-03-04 09:28:40 -0600110#else
Matthew Barth9403a212021-05-17 09:31:50 -0500111 Manager manager(phosphor::fan::util::SDBusPlus::getBus(), event, mode);
Matt Spinleree7f6422017-05-09 11:03:14 -0500112
Matthew Barth3e1bb272020-05-26 11:09:21 -0500113 // Init mode will just set fans to max and delay
Matt Spinlerba7b5fe2018-04-25 15:26:10 -0500114 if (mode == Mode::init)
Matthew Barth8600d9a2017-06-23 14:38:05 -0500115 {
Matthew Barth06764942021-03-04 09:28:40 -0600116 manager.doInit(event);
Matt Spinlerba7b5fe2018-04-25 15:26:10 -0500117 return 0;
Matthew Barth8600d9a2017-06-23 14:38:05 -0500118 }
Matthew Barth06764942021-03-04 09:28:40 -0600119#endif
William A. Kennington III1cfc2f12018-10-19 17:29:46 -0700120 return event.loop();
Matt Spinlerba7b5fe2018-04-25 15:26:10 -0500121 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500122 // Log the useful metadata on these exceptions and let the app
123 // return 1 so it is restarted without a core dump.
Patrick Williamsddb773b2021-10-06 11:24:49 -0500124 catch (const phosphor::fan::util::DBusServiceError& e)
Matt Spinlerba7b5fe2018-04-25 15:26:10 -0500125 {
126 log<level::ERR>("Uncaught DBus service lookup failure exception",
Matthew Barth3e1bb272020-05-26 11:09:21 -0500127 entry("PATH=%s", e.path.c_str()),
128 entry("INTERFACE=%s", e.interface.c_str()));
Matt Spinlerba7b5fe2018-04-25 15:26:10 -0500129 }
Patrick Williamsddb773b2021-10-06 11:24:49 -0500130 catch (const phosphor::fan::util::DBusMethodError& e)
Matt Spinlerba7b5fe2018-04-25 15:26:10 -0500131 {
132 log<level::ERR>("Uncaught DBus method failure exception",
Matthew Barth3e1bb272020-05-26 11:09:21 -0500133 entry("BUSNAME=%s", e.busName.c_str()),
134 entry("PATH=%s", e.path.c_str()),
135 entry("INTERFACE=%s", e.interface.c_str()),
136 entry("METHOD=%s", e.method.c_str()));
Matt Spinlere73446e2017-04-10 13:55:52 -0500137 }
Patrick Williamsddb773b2021-10-06 11:24:49 -0500138 catch (const phosphor::fan::util::DBusPropertyError& e)
Matthew Barth88923a02018-05-11 10:14:44 -0500139 {
140 log<level::ERR>("Uncaught DBus property access failure exception",
Matthew Barth3e1bb272020-05-26 11:09:21 -0500141 entry("BUSNAME=%s", e.busName.c_str()),
142 entry("PATH=%s", e.path.c_str()),
143 entry("INTERFACE=%s", e.interface.c_str()),
144 entry("PROPERTY=%s", e.property.c_str()));
Matthew Barth88923a02018-05-11 10:14:44 -0500145 }
Matt Spinler3ac99022021-10-04 16:02:49 -0500146 catch (std::exception& e)
147 {
148#ifdef CONTROL_USE_JSON
149 phosphor::fan::control::json::FlightRecorder::instance().log(
150 "main", "Unexpected exception exit");
Matt Spinler7787def2021-10-14 16:33:16 -0500151 dumpFlightRecorder();
Matt Spinler3ac99022021-10-04 16:02:49 -0500152#endif
153 throw;
154 }
155
156#ifdef CONTROL_USE_JSON
157 phosphor::fan::control::json::FlightRecorder::instance().log(
158 "main", "Abnormal exit");
Matt Spinler7787def2021-10-14 16:33:16 -0500159 dumpFlightRecorder();
Matt Spinler3ac99022021-10-04 16:02:49 -0500160#endif
Matt Spinlere73446e2017-04-10 13:55:52 -0500161
William A. Kennington III3e781062018-10-19 17:18:34 -0700162 return 1;
Matt Spinlere73446e2017-04-10 13:55:52 -0500163}