summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2017-05-09 11:03:14 -0500
committerMatthew Barth <msbarth@us.ibm.com>2017-05-16 17:27:46 -0500
commitee7f64283f2fe728fd4bd67280bf59daaec9df54 (patch)
tree94df674fdcd96606d10ed55976dffda9d87fa78b
parent389ca67fcd47dbc5375fe9993f3b35ba1af32cff (diff)
downloadphosphor-fan-presence-ee7f64283f2fe728fd4bd67280bf59daaec9df54.tar.gz
phosphor-fan-presence-ee7f64283f2fe728fd4bd67280bf59daaec9df54.zip
Add modes to phosphor-fan-control
phosphor-fan-control can behave differently based on its command line arguments --init: Set fans to full speed, delay for a configurable amount of time to allow fans to ramp up, start the fan control ready target, and then exit. --control: Start the control algorithm. Never exits. Will be started as part of the fan control ready target. Change-Id: I453daf8cc05a5c85a19c098e1cca64cac2ad9520 Signed-off-by: Matt Spinler <spinler@us.ibm.com>
-rw-r--r--control/Makefile.am1
-rw-r--r--control/example/zones.yaml56
-rwxr-xr-xcontrol/gen-fan-zone-defs.py15
-rw-r--r--control/main.cpp35
-rw-r--r--control/manager.cpp46
-rw-r--r--control/manager.hpp34
6 files changed, 157 insertions, 30 deletions
diff --git a/control/Makefile.am b/control/Makefile.am
index 04d7d96..7599977 100644
--- a/control/Makefile.am
+++ b/control/Makefile.am
@@ -5,6 +5,7 @@ sbin_PROGRAMS = \
phosphor-fan-control
phosphor_fan_control_SOURCES = \
+ argument.cpp \
fan.cpp \
main.cpp \
manager.cpp \
diff --git a/control/example/zones.yaml b/control/example/zones.yaml
index 5f3b549..00929cd 100644
--- a/control/example/zones.yaml
+++ b/control/example/zones.yaml
@@ -17,33 +17,43 @@
#case, the fan yaml would have a cooling_profile of 'air' to match
#the zone cooling profile.
-#- zone_conditions:
-# - name: [Name of a condition, if any. Valid names are TBD]
+#manager_configuration:
+# power_on_delay: [Number of seconds that phosphor-fan-control --init
+# should delay after setting fans to full speed on
+# a power on.]
#
-# zones:
-# - zone: [zone number]
-# cooling_profiles:
-# - [cooling profile]
-# initial_speed: [Speed to set the zone to when app starts]
+#zone_configuration:
+# - zone_conditions:
+# - name: [Name of a condition, if any. Valid names are TBD.]
+#
+# zones:
+# - zone: [zone number]
+# cooling_profiles:
+# - [cooling profile]
+# initial_speed: [Speed to set the zone to when app starts.]
#Example:
-#- zone_conditions:
-# - name: air_cooled_chassis
+#manager_configuration:
+# power_on_delay: 20
+#
+#zone_configuration:
+# - zone_conditions:
+# - name: air_cooled_chassis
#
-# zones:
-# - zone: 0
-# cooling_profiles:
-# - air
-# - all
-# initial_speed: 10500
+# zones:
+# - zone: 0
+# cooling_profiles:
+# - air
+# - all
+# initial_speed: 10500
#
-#- zone_conditions:
-# - name: water_and_air_cooled_chassis
+# - zone_conditions:
+# - name: water_and_air_cooled_chassis
#
-# zones:
-# - zone: 0
-# cooling_profiles:
-# - water
-# - all
-# initial_speed: 4000
+# zones:
+# - zone: 0
+# cooling_profiles:
+# - water
+# - all
+# initial_speed: 4000
diff --git a/control/gen-fan-zone-defs.py b/control/gen-fan-zone-defs.py
index 3457d41..04f206f 100755
--- a/control/gen-fan-zone-defs.py
+++ b/control/gen-fan-zone-defs.py
@@ -11,12 +11,14 @@ import yaml
from argparse import ArgumentParser
from mako.template import Template
-#Note: Condition is a TODO
+#Note: Condition is a TODO (openbmc/openbmc#1500)
tmpl = '''/* This is a generated file. */
#include "manager.hpp"
using namespace phosphor::fan::control;
+const unsigned int Manager::_powerOnDelay{${mgr_data['power_on_delay']}};
+
const std::vector<ZoneGroup> Manager::_zoneLayouts
{
%for zone_group in zones:
@@ -151,8 +153,15 @@ if __name__ == '__main__':
with open(args.fan_yaml, 'r') as fan_input:
fan_data = yaml.safe_load(fan_input) or {}
- zone_data = buildZoneData(zone_data, fan_data)
+ zone_config = buildZoneData(zone_data.get('zone_configuration', {}),
+ fan_data)
+
+ manager_config = zone_data.get('manager_configuration', {})
+
+ if manager_config.get('power_on_delay') is None:
+ manager_config['power_on_delay'] = 0
output_file = os.path.join(args.output_dir, "fan_zone_defs.cpp")
with open(output_file, 'w') as output:
- output.write(Template(tmpl).render(zones=zone_data))
+ output.write(Template(tmpl).render(zones=zone_config,
+ mgr_data=manager_config))
diff --git a/control/main.cpp b/control/main.cpp
index 08a7dc9..be5b59e 100644
--- a/control/main.cpp
+++ b/control/main.cpp
@@ -14,13 +14,46 @@
* limitations under the License.
*/
#include <sdbusplus/bus.hpp>
+#include "argument.hpp"
#include "manager.hpp"
+using namespace phosphor::fan::control;
+
int main(int argc, char* argv[])
{
auto bus = sdbusplus::bus::new_default();
+ phosphor::fan::util::ArgumentParser args(argc, argv);
+
+ if (argc != 2)
+ {
+ args.usage(argv);
+ exit(-1);
+ }
- phosphor::fan::control::Manager manager(bus);
+ Manager::Mode mode;
+
+ if (args["init"] == "true")
+ {
+ mode = Manager::Mode::init;
+ }
+ else if (args["control"] == "true")
+ {
+ mode = Manager::Mode::control;
+ }
+ else
+ {
+ args.usage(argv);
+ exit(-1);
+ }
+
+ Manager manager(bus, mode);
+
+ //Init mode will just set fans to max and delay
+ if (mode == Manager::Mode::init)
+ {
+ manager.doInit();
+ return 0;
+ }
while (true)
{
diff --git a/control/manager.cpp b/control/manager.cpp
index 9359a6b..6c773a7 100644
--- a/control/manager.cpp
+++ b/control/manager.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
#include <algorithm>
+#include <phosphor-logging/log.hpp>
+#include <unistd.h>
#include "manager.hpp"
namespace phosphor
@@ -23,7 +25,16 @@ namespace fan
namespace control
{
-Manager::Manager(sdbusplus::bus::bus& bus) :
+using namespace phosphor::logging;
+
+constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
+constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
+constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
+constexpr auto FAN_CONTROL_READY_TARGET = "obmc-fan-control-ready@0.target";
+
+//Note: Future code will check 'mode' before starting control algorithm
+Manager::Manager(sdbusplus::bus::bus& bus,
+ Mode mode) :
_bus(bus)
{
//Create the appropriate Zone objects based on the
@@ -55,14 +66,45 @@ Manager::Manager(sdbusplus::bus::bus& bus) :
}
}
- //Set to full since we don't know state of system yet.
+}
+
+
+void Manager::doInit()
+{
for (auto& z: _zones)
{
z.second->setFullSpeed();
}
+
+ auto delay = _powerOnDelay;
+ while (delay > 0)
+ {
+ delay = sleep(delay);
+ }
+
+ startFanControlReadyTarget();
}
+void Manager::startFanControlReadyTarget()
+{
+ auto method = _bus.new_method_call(SYSTEMD_SERVICE,
+ SYSTEMD_OBJ_PATH,
+ SYSTEMD_INTERFACE,
+ "StartUnit");
+
+ method.append(FAN_CONTROL_READY_TARGET);
+ method.append("replace");
+
+ auto response = _bus.call(method);
+ if (response.is_method_error())
+ {
+ //TODO openbmc/openbmc#1555 create an elog
+ log<level::ERR>("Failed to start fan control ready target");
+ throw std::runtime_error("Failed to start fan control ready target");
+ }
+}
+
}
}
}
diff --git a/control/manager.hpp b/control/manager.hpp
index 7f8baa3..675dfb8 100644
--- a/control/manager.hpp
+++ b/control/manager.hpp
@@ -23,6 +23,17 @@ class Manager
{
public:
+ /**
+ * The mode the manager will run in:
+ * - init - only do the initialization steps
+ * - control - run normal control algorithms
+ */
+ enum class Mode
+ {
+ init,
+ control
+ };
+
Manager() = delete;
Manager(const Manager&) = delete;
Manager(Manager&&) = default;
@@ -36,12 +47,26 @@ class Manager
* _zoneLayouts data.
*
* @param[in] bus - The dbus object
+ * @param[in] mode - The control mode
+ */
+ Manager(sdbusplus::bus::bus& bus,
+ Mode mode);
+
+ /**
+ * Does the fan control inititialization, which is
+ * setting fans to full, delaying so they
+ * can get there, and starting a target.
*/
- Manager(sdbusplus::bus::bus& bus);
+ void doInit();
private:
/**
+ * Starts the obmc-fan-control-ready dbus target
+ */
+ void startFanControlReadyTarget();
+
+ /**
* The dbus object
*/
sdbusplus::bus::bus& _bus;
@@ -56,6 +81,13 @@ class Manager
* This is generated data.
*/
static const std::vector<ZoneGroup> _zoneLayouts;
+
+ /**
+ * The number of seconds to delay after
+ * fans get set to high speed on a power on
+ * to give them a chance to get there.
+ */
+ static const unsigned int _powerOnDelay;
};
OpenPOWER on IntegriCloud