os-xenapi/os_xenapi/utils/rotate_xen_guest_logs.sh

71 lines
2.5 KiB
Bash
Executable File

#!/bin/bash
set -eux
# Script to rotate console logs
#
# Should be run on Dom0, with cron, every minute:
# * * * * * /root/rotate_xen_guest_logs.sh
#
# Should clear out the guest logs on every boot
# because the domain ids may get re-used for a
# different tenant after the reboot
#
# /var/log/xen/guest could be mounted into a
# small loopback device to stop any guest being
# able to fill dom0 file system
log_dir="/var/log/xen/guest"
kb=1024
mb=1048576
max_size_bytes=$((1*$mb))
truncated_size_bytes=$((5*$kb))
syslog_tag='rotate_xen_guest_logs'
log_file_base="${log_dir}/console."
# Only delete log files older than this number of minutes
# to avoid a race where Xen creates the domain and starts
# logging before the XAPI VM start returns (and allows us
# to preserve the log file using last_dom_id)
min_logfile_age=10
# Ensure logging is setup correctly for all domains
xenstore-write /local/logconsole/@ "${log_file_base}%d"
# Grab the list of logs now to prevent a race where the domain is
# started after we get the valid last_dom_ids, but before the logs are
# deleted. Add spaces to ensure we can do containment tests below
current_logs=$(find "$log_dir" -type f)
# Ensure the last_dom_id is set + updated for all running VMs
for vm in $(xe vm-list power-state=running --minimal | tr ',' ' '); do
xe vm-param-set uuid=$vm other-config:last_dom_id=$(xe vm-param-get uuid=$vm param-name=dom-id)
done
# Get the last_dom_id for all VMs
valid_last_dom_ids=$(xe vm-list params=other-config --minimal | tr ';,' '\n\n' | grep last_dom_id | sed -e 's/last_dom_id: //g' | xargs)
echo "Valid dom IDs: $valid_last_dom_ids" | /usr/bin/logger -t $syslog_tag
# Remove old console files that do not correspond to valid last_dom_id's
allowed_consoles=".*console.\(${valid_last_dom_ids// /\\|}\)$"
delete_logs=`find "$log_dir" -type f -mmin +${min_logfile_age} -not -regex "$allowed_consoles"`
for log in $delete_logs; do
if echo "$current_logs" | grep -q -w "$log"; then
echo "Deleting: $log" | /usr/bin/logger -t $syslog_tag
rm $log
fi
done
# Truncate all remaining logs
for log in `find "$log_dir" -type f -regex '.*console.*' -size +${max_size_bytes}c`; do
echo "Truncating log: $log" | /usr/bin/logger -t $syslog_tag
tmp="$log.tmp"
tail -c $truncated_size_bytes "$log" > "$tmp"
mv -f "$tmp" "$log"
# Notify xen that it needs to reload the file
domid="${log##*.}"
xenstore-write /local/logconsole/$domid "$log"
xenstore-rm /local/logconsole/$domid
done