| #!/bin/sh |
| |
| # Copyright 2016 The ChromiumOS Authors |
| # 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 |
| # shellcheck source=./ui-killers-helper |
| . /usr/share/cros/init/ui-killers-helper |
| |
| # 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" |
| |
| # Start the dlcservice if it is not running. |
| status dlcservice | grep running || start dlcservice |
| # Get the list of user-tied DLC mount points for passing to the process_killer. |
| # Wait for the dlcservice to return a result. If timeout, meaning the dlcserivce |
| # is likely not availble, the DLC mount points list would be empty. |
| USER_TIED_DLC="$(dlcservice_util --list --user_tied --check_mount --timeout=5 | |
| jq -c '[.[][].root_mount]')" |
| |
| # Terminate any processes with files open on the mount point |
| # TODO(wad) parallelize with VFS/PID namespaces. |
| process_killer --session --file_holders --mount_filter="${USER_TIED_DLC}" |
| |
| # 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 ! minijail0 -u chronos -g chronos -G /bin/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 |
| |
| # Unload user-tied DLCs before cryptohome unmounting. Not waiting again for the |
| # service here since an attempt already made earlier to ensure dlcservice being |
| # available. Also set a short timeout for the command. |
| dlcservice_util --unload --user_tied --timeout=5 --nowait_for_service |
| |
| cryptohome --action=unmount |
| # Unmount the user session namespace mount point. |
| umount /run/namespaces/mnt_chrome |
| bootstat cryptohome-unmounted |
| |
| # In case cryptohome crashes, application containers may remain active post |
| # cryptohome unmount. Check for the existence of these devices and lazy remove |
| # the encrypted containers of these containers. |
| for device in /dev/mapper/dmcrypt-* ; do |
| dmsetup remove --deferred "${device}" |
| done |
| |
| # Clears chrome oobe storage files. Chrome could leave files behind for |
| # the sign-in storage partition. See http://b/277632606. |
| rm -rf /home/chronos/Default/Storage/ext/oobe |
| |
| # Post unmount, attempt to kill any left over processes from the session |
| # that could have leaked user mounts. This is intentionally done post |
| # unmount: lazy unmount cleans up mounts from the root namespace and |
| # newly launched processes will no be able to clone the mount. |
| process_killer --session --mount_holders |