Keep fan services running until poweroff completes

All the fan services associated with controlling, monitoring and
presence detection of fans need to remain active until a poweroff
completes. This helps ensure thermal safety while a system is in
transition to a powered off state.

With the introduction of this new target (which runs last in
the power off path), need to move the host reset service to
running after it to ensure the power on in the reboot path
does not start until the last power off target runs.

Resolves openbmc/openbmc#2762

Change-Id: I4ca671d2c7de66e8bfa4bba607b06c88c0a6e7f9
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/common/recipes-phosphor/chassis/obmc-op-control-power.bb b/common/recipes-phosphor/chassis/obmc-op-control-power.bb
index 5dd6d12..e341463 100644
--- a/common/recipes-phosphor/chassis/obmc-op-control-power.bb
+++ b/common/recipes-phosphor/chassis/obmc-op-control-power.bb
@@ -20,6 +20,7 @@
         op-wait-power-off@.service \
         op-reset-chassis-running@.service \
         op-reset-chassis-on@.service \
+        op-powered-off@.service \
         "
 
 SYSTEMD_ENVIRONMENT_FILE_${PN} += "obmc/power_control"
@@ -34,6 +35,10 @@
 STOP_INSTFMT = "op-power-stop@{0}.service"
 STOP_FMT = "../${STOP_TMPL}:${STOP_TGTFMT}.requires/${STOP_INSTFMT}"
 
+POWERED_OFF_TMPL = "op-powered-off@.service"
+POWERED_OFF_INSTFMT = "op-powered-off@{0}.service"
+POWERED_OFF_FMT = "../${POWERED_OFF_TMPL}:${STOP_TGTFMT}.requires/${POWERED_OFF_INSTFMT}"
+
 ON_TMPL = "op-wait-power-on@.service"
 ON_INSTFMT = "op-wait-power-on@{0}.service"
 ON_FMT = "../${ON_TMPL}:${START_TGTFMT}.requires/${ON_INSTFMT}"
@@ -55,6 +60,7 @@
 # Build up requires relationship for START_TGTFMT and STOP_TGTFMT
 SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'START_FMT', 'OBMC_POWER_INSTANCES', 'OBMC_CHASSIS_INSTANCES')}"
 SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'STOP_FMT', 'OBMC_POWER_INSTANCES', 'OBMC_CHASSIS_INSTANCES')}"
+SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'POWERED_OFF_FMT', 'OBMC_POWER_INSTANCES', 'OBMC_CHASSIS_INSTANCES')}"
 SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'ON_FMT', 'OBMC_POWER_INSTANCES', 'OBMC_CHASSIS_INSTANCES')}"
 SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'OFF_FMT', 'OBMC_POWER_INSTANCES', 'OBMC_CHASSIS_INSTANCES')}"
 SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'RESET_ON_FMT', 'OBMC_POWER_INSTANCES', 'OBMC_CHASSIS_INSTANCES')}"
diff --git a/common/recipes-phosphor/chassis/obmc-op-control-power/op-powered-off@.service b/common/recipes-phosphor/chassis/obmc-op-control-power/op-powered-off@.service
new file mode 100644
index 0000000..b76db7b
--- /dev/null
+++ b/common/recipes-phosphor/chassis/obmc-op-control-power/op-powered-off@.service
@@ -0,0 +1,20 @@
+[Unit]
+Description=Power is off to chassis%i
+After=op-wait-power-off@%i.service
+Requires=op-wait-power-off@%i.service
+
+[Service]
+RemainAfterExit=no
+# systemd starts all wanted targets in parallel and a Conflict
+# statement will resolve itself when the target starts, not when
+# completes. Some services have a requirement to stop
+# once power is off. The solution is to create a new target,
+# obmc-chassis-powered-off@.target, that is started after it is
+# verified that power has been removed from the chassis. Then
+# services may conflict with this target to ensure they
+# are stopped at the appropriate time.
+ExecStart=/bin/systemctl start obmc-chassis-powered-off@%i.target
+
+
+[Install]
+WantedBy=obmc-chassis-poweroff@%i.target
diff --git a/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-control-init@.service b/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-control-init@.service
index b78457f..96b40f6 100644
--- a/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-control-init@.service
+++ b/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-control-init@.service
@@ -2,7 +2,7 @@
 Description=Phosphor Fan Control Initialization
 Wants=obmc-power-on@%i.target
 After=obmc-power-on@%i.target
-Conflicts=obmc-chassis-poweroff@%i.target
+Conflicts=obmc-chassis-powered-off@%i.target
 
 [Service]
 Restart=on-failure
diff --git a/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-control@.service b/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-control@.service
index 2aef875..8c5903e 100644
--- a/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-control@.service
+++ b/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-control@.service
@@ -1,6 +1,6 @@
 [Unit]
 Description=Phosphor Fan Control Daemon
-Conflicts=obmc-chassis-poweroff@%i.target
+Conflicts=obmc-chassis-powered-off@%i.target
 
 [Service]
 Restart=on-failure
diff --git a/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-monitor-init@.service b/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-monitor-init@.service
index a5cfd85..e8a6f69 100644
--- a/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-monitor-init@.service
+++ b/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-monitor-init@.service
@@ -2,7 +2,7 @@
 Description=Phosphor Fan Monitor Initialization
 Wants=obmc-power-on@%i.target
 After=obmc-power-on@%i.target
-Conflicts=obmc-chassis-poweroff@%i.target
+Conflicts=obmc-chassis-powered-off@%i.target
 
 [Service]
 Restart=on-failure
diff --git a/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-monitor@.service b/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-monitor@.service
index 09f3494..ddecfba 100644
--- a/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-monitor@.service
+++ b/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-monitor@.service
@@ -1,6 +1,6 @@
 [Unit]
 Description=Phosphor Fan Monitor Daemon
-Conflicts=obmc-chassis-poweroff@%i.target
+Conflicts=obmc-chassis-powered-off@%i.target
 
 [Service]
 Restart=on-failure
diff --git a/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-presence-tach@.service b/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-presence-tach@.service
index 07d23d8..a324740 100644
--- a/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-presence-tach@.service
+++ b/common/recipes-phosphor/fans/phosphor-fan/phosphor-fan-presence-tach@.service
@@ -2,7 +2,7 @@
 Description=Phosphor Fan Presence Tach Daemon
 Wants=obmc-power-on@%i.target
 After=obmc-power-on@%i.target
-Conflicts=obmc-chassis-poweroff@%i.target
+Conflicts=obmc-chassis-powered-off@%i.target
 
 [Service]
 Restart=on-failure
diff --git a/common/recipes-phosphor/state/files/phosphor-reboot-host@.service b/common/recipes-phosphor/state/files/phosphor-reboot-host@.service
index fdf84c1..f8f0171 100644
--- a/common/recipes-phosphor/state/files/phosphor-reboot-host@.service
+++ b/common/recipes-phosphor/state/files/phosphor-reboot-host@.service
@@ -4,7 +4,12 @@
 After=obmc-host-stop@%i.target
 
 [Service]
-ExecStart={base_bindir}/systemctl start obmc-host-start@%i.target
+#ExecStart={base_bindir}/systemctl start obmc-host-start@%i.target
+# This service is starting another target that conflicts with the
+# target this service is running in. OpenBMC needs a refactor of
+# how it does its host reset path. Until then, this short term
+# solution does the job.
+ExecStart=/bin/sh -c "sleep 5 && systemctl start obmc-host-start@%i.target"
 
 
 [Install]