#!/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"

# 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
}

rotate_file() {
  local file="$1"
  if [ ! -f "${file}" ]; then
    # Avoid creating an empty file if it does not exist to begin with
    return
  fi
  local basename="${file%%.*}"
  local extension="${file#*.}"
  if [ "${basename}" = "${extension}" ]; then
    extension=""
  else
    extension=".${extension}"
  fi
  echo Rotating "${file}"
  for i in $(seq "${NUM_DAYS_TO_PRESERVE}" -1 2); do
    mv -f "${basename}.$((i - 1))${extension}" "${basename}.$i${extension}"
  done
  mv -f "${basename}${extension}" "${basename}.1${extension}"
  touch "${basename}${extension}"
  chmod --reference="${basename}.1${extension}" "${basename}${extension}"
  chown --reference="${basename}.1${extension}" "${basename}${extension}"
}

rotate_logs() {
  echo Rotating rsyslogd logs
  for x in messages secure net.log faillog session_manager atrus.log \
           tlsdate.log authpolicy.log tpm-firmware-updater.log arc.log \
           recover_duts/recover_duts.log hammerd.log upstart.log; do
    rotate_file "/var/log/${x}"
  done
  pkill -HUP rsyslogd
}

# 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_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.*"
}

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

  # Quit if called at init; everything below only happens periodically
  if [ "$1" = "--no-periodic" ]; then
    return 0
  fi

  # Rotate other logs
  rotate_logs

  # 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 GBs.
  LIFETIME_WRITES="$(get_stateful_lifetime_writes)"
  metrics_client Platform.StatefulLifetimeWrites \
    "$((LIFETIME_WRITES / 1000000))" 0 16777216 100

  NUMBER_OF_USERS="$(ls /home/user/ | wc -l)"
  metrics_client Platform.DiskUsage.NumUserHomeDirectories \
                "${NUMBER_OF_USERS}" 1 50 50

  WEEKLY_USERS_ACTIVE="$(cryptohome --action=dump_last_activity |
      awk 'BEGIN {count = 0} $2 <= 7 {++count} END {print count}')"
  metrics_client -s Login.UsersActiveWeekly "${WEEKLY_USERS_ACTIVE}"

  if [ "${NUMBER_OF_USERS}" -gt 0 ] ; then
    metrics_client -s Login.UsersActiveWeekly.Percent \
                  "$((WEEKLY_USERS_ACTIVE * 100 / NUMBER_OF_USERS))"
  else
    metrics_client -s Login.UsersActiveWeekly.Percent 0
  fi

  # Report days since the least frequently used account signed in.
  # It is reported every time to measure effect of autodeletion feature.
  DAYS_SINCE_LFU_ACCOUNT_SIGNIN="$(cryptohome --action=dump_last_activity |
      awk 'BEGIN {max = 0} $2 > max {max = $2} END {print max}')"

  # Check if there are any users.
  if [ "${DAYS_SINCE_LFU_ACCOUNT_SIGNIN}" != "" ]; then
    metrics_client Login.LeastUsedAccountDays \
                  "${DAYS_SINCE_LFU_ACCOUNT_SIGNIN}" 1 90 90
  fi

  # 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 "$@"
