| #!/bin/sh | |
| # Copyright 2011 The ChromiumOS Authors | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| # This script should be called daily to clean up log files. | |
| # It can also be called with "--no-periodic" directly from an init | |
| # script in which case it will clean up but not rotate. | |
| # This file exists on the DUT, but not outside of a chroot during repo upload. | |
| # shellcheck source=disk_utils.sh | |
| . "/usr/share/cros/disk_utils.sh" | |
| CLEANUP_PAUSED_FILE="/var/lib/cleanup_logs_paused" | |
| NUM_DAYS_TO_PRESERVE=7 | |
| MAX_SUBDIR_SIZE=100 # MB | |
| MAX_SUBDIR_FILES=21 | |
| # Threshold for additional histogram reporting (in 1KB blocks), 1GB in total. | |
| ENCRYPTED_REBOOT_VAULT="/mnt/stateful_partition/reboot_vault" | |
| # Paths for the CRX cache. Shared with installer/crx-import.conf | |
| UNVALIDATED_CRX_CACHE="${STATEFUL:?}/unencrypted/import_extensions" | |
| VALIDATED_CRX_CACHE=/var/cache/external_cache | |
| # Remove older files, keep deleting until the directory is less than 100MB | |
| # or only one day old files remains. ...and also delete older files if | |
| # there are too many (the number of files to keep can optionally be configured | |
| # by $3). | |
| remove_old_files() { | |
| local subdir="$1" | |
| local file_pattern="$2" | |
| local mtime="${NUM_DAYS_TO_PRESERVE}" | |
| local max_subdir_files="${3:-${MAX_SUBDIR_FILES}}" | |
| if [ ! -d "${subdir}" ]; then | |
| return | |
| fi | |
| while [ "${mtime}" -ge 1 ]; do | |
| find "${subdir}" -type f -name "${file_pattern}" -mtime "+${mtime}" -delete | |
| if [ "$(du -s --block-size=1M "${subdir}" | cut -f 1)" -gt \ | |
| "${MAX_SUBDIR_SIZE}" ]; then | |
| : "$(( mtime -= 1 ))" | |
| else | |
| break | |
| fi | |
| done | |
| # Delete all but the most recent $max_subdir_files files. | |
| # | |
| # Note that 'ls -t' doesn't have a "null terminated" mode apparently | |
| # because you're not supposed to use it for scripts, so we end up | |
| # using several steps. | |
| find "${subdir}" -type f -name "${file_pattern}" -printf "%T+ %p\0" | \ | |
| sort -zr | \ | |
| cut -z -d ' ' -f 2- | \ | |
| tail -z "-n+$(( max_subdir_files + 1 ))" | \ | |
| xargs -r -0 rm | |
| } | |
| # Wipe the unencyrpted CRX cache if it still exists. | |
| wipe_crx_cache() { | |
| local root_dev | |
| local removable | |
| local disk_percent | |
| # If we are on removable media or we haven't imported the crx cache, | |
| # don't wipe. | |
| root_dev="$(basename "$(rootdev -s -d)")" | |
| removable="$(cat "/sys/block/${root_dev}/removable")" || : | |
| disk_percent="$(get_stateful_usage_percent)" || : | |
| [ -z "${disk_percent}" ] && disk_percent=0 | |
| if [ "${removable:-0}" -eq 0 ] && [ -d "${UNVALIDATED_CRX_CACHE}" ] && \ | |
| [ -f "${VALIDATED_CRX_CACHE}/.initialized" ] && \ | |
| [ "${disk_percent}" -gt 25 ]; then | |
| echo "Wiping unvalidated crx cache as it has already been imported." | |
| rm -rf "${UNVALIDATED_CRX_CACHE}" | |
| fi | |
| } | |
| remove_old_files_encrypted_reboot_vault() { | |
| find "${ENCRYPTED_REBOOT_VAULT}" -type f -mtime "+${NUM_DAYS_TO_PRESERVE}" \ | |
| -delete | |
| } | |
| remove_old_pattern_log_files() { | |
| # Remove old biometrics cypto init, daemon, and firmware | |
| # updater logs | |
| remove_old_files /var/log/bio_crypto_init "*" | |
| remove_old_files /var/log/biod "biod.*" | |
| remove_old_files /var/log/biod "bio_fw_updater.*" | |
| # Remove old chrome logs (not logged in) | |
| remove_old_files /var/log/chrome "chrome_*-*" | |
| # Remove old lacros chrome logs (not logged in) | |
| remove_old_files /var/log/lacros "lacros_*-*.log" | |
| # Remove old chrome logs (logged in) | |
| remove_old_files /home/chronos/user/log "chrome_*-*" | |
| # Remove old lacros chrome logs (logged in) | |
| remove_old_files /home/chronos/user/lacros "lacros_*-*.log" | |
| # Remove old miscellaneous UI logs | |
| remove_old_files /var/log/ui "ui.*-*" | |
| # Remove old update engine logs | |
| remove_old_files /var/log/update_engine "update_engine.*-*" | |
| # Remove old power manager logs | |
| remove_old_files /var/log/power_manager "power*" | |
| # Remove old vmlog logs (written by metrics_daemon) | |
| remove_old_files /var/log/vmlog "vmlog.*" | |
| # Remove old modemfwd helper logs | |
| remove_old_files /var/log/modemfwd "helper_log.*" | |
| # Remove old modemloggerd logs | |
| remove_old_files /var/log/modemloggerd "*" | |
| } | |
| usage() { | |
| echo "usage: $0 [--no-periodic]" | |
| echo | |
| echo "Delete old logs and perform periodic tasks like rotating logs." | |
| echo | |
| echo "This program always deletes old log files for programs that" | |
| echo "create one log per boot. Unless called with --no-periodic" | |
| echo "it will also do periodic tasks like rotating log files" | |
| echo "and sending metrics." | |
| } | |
| main() { | |
| if [ "$#" -eq 1 ] && [ "$1" != "--no-periodic" ] || | |
| [ "$#" -gt 1 ]; then | |
| usage | |
| return 1 | |
| fi | |
| if [ -r "${CLEANUP_PAUSED_FILE}" ]; then | |
| echo "Exiting early because ${CLEANUP_PAUSED_FILE} exists." | |
| return 0 | |
| fi | |
| remove_old_pattern_log_files | |
| # Remove iwlwifi logs older than one hour, since they are large. | |
| find /var/log -name "last_iwlwifi_dump*" -mmin +60 -delete | |
| # Remove old files in the encrypted reboot vault. | |
| remove_old_files_encrypted_reboot_vault | |
| # Quit if called at init; everything below only happens periodically | |
| if [ "$1" = "--no-periodic" ]; then | |
| return 0 | |
| fi | |
| # Collect log-related metrics before rotation. | |
| log-metrics-collector | |
| # Rotate other logs | |
| log_rotator | |
| # Report disk usage statistics | |
| ( | |
| # Subshell to re-use $@ array. | |
| set -- 0 1073741824 50 | |
| metrics_client Platform.DiskUsageVar \ | |
| "$(du -sxk /var/ | awk '{print $1}')" "$@" | |
| metrics_client Platform.DiskUsageChronos \ | |
| "$(du -sxk /home/chronos | awk '{print $1}')" "$@" | |
| ) | |
| # Report overall stateful usage. | |
| metrics_client -e Platform.StatefulUsage "$(get_stateful_usage_percent)" 101 | |
| # Report lifetime writes from the stateful partition in GiBs. | |
| LIFETIME_WRITES="$(get_stateful_lifetime_writes)" | |
| metrics_client Platform.StatefulLifetimeWrites \ | |
| "$((LIFETIME_WRITES / 1048576))" 0 16777216 100 | |
| # Report used space from the stateful partition in GBs. | |
| STATEFUL_USED="$(get_stateful_used_space_blocks 1000)" | |
| metrics_client Platform.StatefulUsedSpace \ | |
| "$((STATEFUL_USED / 1000000))" 0 16777216 50 | |
| # Report free space from the stateful partition in MBs. Some boards | |
| # ship with a variety of SSD sizes, so free space metrics can be | |
| # useful in addition to used space. Record in MB so we have higher | |
| # precision in the buckets close to zero (out of space). Max out at | |
| # 2 TB. | |
| STATEFUL_FREE="$(get_stateful_free_space_blocks 1000)" | |
| metrics_client Platform.StatefulFreeSpace \ | |
| "$((STATEFUL_FREE / 1000))" 0 2097152 50 | |
| wipe_crx_cache | |
| } | |
| main "$@" |