blob: 09875c891e4f65895faa2562fedd751f87ad6376 [file] [log] [blame]
#!/bin/sh
# Copyright 2016 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.
JOB=$(basename "$0")
bootstat ui-post-stop
set +e
. /sbin/killers
# Terminate PKCS #11 services.
cryptohome --action=pkcs11_terminate
# Thaw any renderers that may have been left behind. If we
# have crashed while renderers are frozen, they'll be unkillable
# until we do this.
echo "THAWED" > "${CHROME_FREEZER_CGROUP_DIR}/to_be_frozen/freezer.state"
# Terminate any processes with files open on the mount point
# TODO(wad) parallelize with VFS/PID namespaces.
kill_with_open_files_on_path_and_mountpoints \
'/home/[^.]|/data|/home/.shadow/[a-fA-F0-9]{40}/mount' "cryptohome" \
/home/chronos/u-*
# Make sure everything is going down. No exceptions.
# The loop is so that clever daemons can't evade the kill by
# racing us and killing us first; we'll just try over and over
# until we win the race, and kill with pid -1 is atomic with
# respect to process creation.
while ! sudo -u chronos kill -9 -- -1 ; do
sleep .1
done
# Check for still-living chronos processes and log their status.
ps -u chronos --no-headers -o pid,stat,args |
logger -i -t "${JOB}-unkillable" -p crit
bootstat other-processes-terminated
# Android containers use run_oci to terminate and clean up containers. If
# run_oci exists, let run_oci perform the task first before falling back to
# general cleanup. Note that the cleanup is done here only when session_manager
# (e.g. crashes and) fails to kill/destroy the containers.
for container in /run/containers/*-run_oci ; do
# The '-run_oci' suffix above ensures that the run_oci commands below are
# executed only for containers started by run_oci. When run_oci is not
# installed in the rootfs, for example, these commands are never executed.
if [ -d "${container}" ]; then
run_oci --signal=KILL kill "${container##*/}"
NUM_RETRIES=3
for i in $(seq ${NUM_RETRIES}) ; do
# Both sleep and polling are needed here because 'run_oci destroy' fails
# if the container process is still alive.
sleep 1
run_oci destroy "${container##*/}" && break
if [ ${i} = ${NUM_RETRIES} ]; then
logger -i -p crit "Failed to destroy ${container##*/}"
fi
done
fi
done
# If there are any orphaned containers, they should also be cleaned up.
# This needs to be done prior to cryptohome unmounting so that there are no
# remaining processes with files open that would prevent a clean unmount.
for container in /run/containers/* ; do
if [ -d "${container}" ]; then
kill_with_open_files_on "${container##*/}" "${container}/root"
umount -R "${container}/root"
rm -rf "${container}"
fi
done
cryptohome --action=unmount
bootstat cryptohome-unmounted