blob: b54c79196aff75fe7fadb20cebf7f94171e830c1 [file] [log] [blame]
# 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.
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