| #!/bin/sh |
| |
| # Copyright (c) 2011 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. |
| |
| # 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. |
| |
| . /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. |
| ADDITIONAL_REPORTING_THRESHOLD_BLOCKS=1048576 |
| SHADOW="/home/.shadow" |
| 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 |
| |
| report_additional_statistics() { |
| # Number of users on device. |
| local user_count |
| user_count="$(find "${SHADOW}" -maxdepth 1 -mindepth 1 -type d | wc -l)" |
| metrics_client -s Platform.DiskUsage.UsersOnDevice "${user_count}" |
| } |
| |
| # 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. |
| remove_old_files() { |
| local subdir="$1" |
| local file_pattern="$2" |
| local mtime="${NUM_DAYS_TO_PRESERVE}" |
| 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 chrome logs (logged in) |
| remove_old_files /home/chronos/user/log "chrome_*-*" |
| |
| # 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 bootstat metrics files. NB: this can still leave empty |
| # /var/log/metrics/shutdown.<timestamp>/ directories. |
| remove_old_files /var/log/metrics "*" |
| } |
| |
| 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 |
| METRICS_ARGS="0 1073741824 50" |
| metrics_client Platform.DiskUsageVar \ |
| "$(du -sxk /var/ | awk '{print $1}')" ${METRICS_ARGS} |
| metrics_client Platform.DiskUsageChronos \ |
| "$(du -sxk /home/chronos | awk '{print $1}')" ${METRICS_ARGS} |
| |
| # 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 |
| |
| NUMBER_OF_USERS="$(ls /home/user/ | wc -l)" |
| metrics_client Platform.DiskUsage.NumUserHomeDirectories \ |
| "${NUMBER_OF_USERS}" 1 50 50 |
| |
| # Report additional metrics if we are low on free space. |
| if [ "$(get_stateful_free_space_blocks)" -le \ |
| "${ADDITIONAL_REPORTING_THRESHOLD_BLOCKS}" ] ; then |
| report_additional_statistics |
| fi |
| |
| wipe_crx_cache |
| } |
| main "$@" |