| # Copyright 2015 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| description "Go into S3 (suspend) for halt, then reboot when waking up" |
| author "chromium-os-dev@chromium.org" |
| |
| env BTMGMT_JAIL='/sbin/minijail0 -u bluetooth -g bluetooth -G -c 3500 -- /usr/bin/btmgmt' |
| env BT_ADDR_RE='^\s*addr (([0-9A-F]){2}:){5}([0-9A-F]){2}\s' |
| |
| start on runlevel 0 |
| stop on runlevel [!0] |
| |
| # SHUTDOWN_REASON is passed to initctl by powerd_setuid_helper. |
| # Export it here so that the pre-shutdown job can log it. |
| import SHUTDOWN_REASON |
| export SHUTDOWN_REASON |
| |
| exec chromeos_shutdown |
| |
| pre-start script |
| # We need to record if Bluetooth was on so we can turn it back on in |
| # post-stop. Note that there are quite a few ugly bits here: |
| # |
| # 1. The stopping of bluetoothd is kicked off _before_ we run but |
| # possibly might not have completed yet. That means it might or |
| # might not have powered off Bluetooth devices already. We get |
| # around this by parsing the settings directly. |
| # 2. We have to run some code in pre-start (here) because |
| # "/var/lib/bluetooth" isn't available in post-stop. Then we |
| # somehow need to communicate to post-stop. If we had upstart 1.7+ |
| # we could use initctl set-env but we don't. The best we can do is |
| # use /tmp and try to do it in a safe way (since /tmp is world |
| # writable and we run as root we need to be careful of symlinks). |
| # Using mktemp should be safe and we'll check for the existence of |
| # the file (owned by us) in post-stop. |
| # 3. It's pretty ugly to let Bluetooth turn off (when bluetoothd |
| # stops) and then turn it back on. Luckily wakeup still appears to |
| # work in this case (at least on Mickey), but it's still ugly. It |
| # may be that things still work because nowhere in the kernel do we |
| # ever turn the Bluetooth regulator off. A cleaner solution would |
| # be to use btmgmt to tell bluetoothd not to power off upon exit |
| # so that we could do wakeup. In order to make this work, we'd not |
| # only need to add this feature to bluetoothd, but we'd also need |
| # to find a way to run at halt time before bluetoothd exited and |
| # also (ideally) still find a way to turn Bluetooth power off |
| # between waking up and rebooting. |
| |
| BT_ADDR=$(${BTMGMT_JAIL} info | grep -E "${BT_ADDR_RE}" | head -1 | |
| awk '{print $2}') |
| if grep -q Powered=true "/var/lib/bluetooth/${BT_ADDR}/settings"; then |
| mktemp --tmpdir s3halt.bt.XXXXXXXXX |
| fi |
| end script |
| |
| post-stop script |
| if [ -O /tmp/s3halt.bt.* ]; then |
| ${BTMGMT_JAIL} power on |
| |
| # A small sleep appears to be needed after powering on... |
| sleep 1 |
| fi |
| |
| echo mem > /sys/power/state |
| |
| if [ -O /tmp/s3halt.bt.* ]; then |
| ${BTMGMT_JAIL} power off |
| fi |
| |
| reboot --force |
| end script |