#!/usr/bin/env zsh

# Copyright C 2002-2009 by Isilon Systems, Inc. All rights not expressly
# granted herein are reserved.
# Created in the United States of America.
# 
# This digital media is protected by U.S. and international copyright and
# intellectual property laws. Unless otherwise specified, all information
# and screens appearing as part of this digital medium, including
# software, services, documents, text, images, icons, and logos design;
# the selection, assembly, arrangement, and design thereof; and the code
# that enables its presentation, are the sole property of Isilon Systems,
# Inc.
# 
# Except as otherwise required by applicable law, no part of any
# copyrighted material may be reproduced, modified, translated,
# distributed, published, or transmitted by any means, electronic or
# mechanical, for any purpose, without the prior written consent of Isilon
# Systems. 
#  
# Isilon and Isilon Systems are registered trademarks of Isilon Systems,
# Inc.  Legion is a trademark of Isilon Systems, Inc.  All other
# trademarks and registered trademarks are the property of their
# respective holders.

# isi_store_state
#
# Backup of various configurations useful in the event of catastrophic
# configuration loss.
#
# Backup select cluster configuration files to each node.
#
# Backup node-specific configuration files both to /ifs and to every other
# node. The node-specific files are put into a compressed tar file named
# node-config.<nodeid>.<hour>.tar.gz.  The number of hourly copies created
# is controlled by the cron invocation of this command.  If local backup
# space is tight, older ones are removed.  All copies are kept on /ifs
# regardless of space consumption.

######################
## begin configuration

IFS_BACKUP_DIR=/ifs/.ifsvar/backup	# cluster backup location
LOC_BACKUP_DIR=/var/backup		# local backup location
LOC_BACKUP_MAX_USAGE=5			# max usage percent of backup partition

# Cluster-wide files.  Each of these files will be preserved locally on each
# node, but only one backup will be kept of each. Appropriate for large files
# or files that only accumulate configuration (e.g. winbindd_idmap.tdb)
i=1
CLUSTER_FILES[i++]=/ifs/.ifsvar/samba/share_info.tdb
CLUSTER_FILES[i++]=/ifs/.ifsvar/likewise/db/lsass-local.db
CLUSTER_FILES[i++]=/ifs/.ifsvar/likewise/db/idmap.db
CLUSTER_FILES[i++]=/ifs/.ifsvar/likewise/db/pstore.db

## end configuration
####################

PID_FILE=/var/run/isi_store_state.pid

# check usage, get the hourly period for use in file naming
if [ $# != 1 ] ; then
	logger -p WARN "$0 usage $0 CRON_PERIOD_IN_HOURS"
	exit 1
fi
PERIOD=$1

# Make sure it's not already running; yes, this is racey
if [ -f $PID_FILE ] ; then
	logger -p WARN "$0 already running because $PID_FILE exists"
	exit 0
fi

echo $$ > $PID_FILE

cleanup()
{
	/bin/rm -f $PID_FILE
}

trap 'cleanup' EXIT 2 9 15

# Check if ifs is mounted
/sbin/mount -p -t efs | grep efs >/dev/null 2>&1
if [ ! $? -eq 0 ] ;  then
	exit 0
fi

# create the backup directories
for dir in $IFS_BACKUP_DIR $LOC_BACKUP_DIR ; do
	if [ ! -d $dir ] ; then
		/bin/mkdir -p $dir
	fi
	if [ ! -d $dir ] ; then
		/usr/bin/logger -p ERR "$0 backup directory error $dir"
		exit 1
	fi
done

# clean out from the local and cluster backup location any backup files used
# under old naming schemes
if [ ! -f $LOC_BACKUP_DIR/.version2 ] ; then
	rm -f $LOC_BACKUP_DIR/config.* 2>/dev/null
	rm -f $IFS_BACKUP_DIR/config.* 2>/dev/null
	touch $LOC_BACKUP_DIR/.version2
fi

usage=$(df -k $LOC_BACKUP_DIR | tail -n 1 | awk '{print $2}')
let "LOC_BACKUP_SIZE_CAP = $usage * $LOC_BACKUP_MAX_USAGE / 100"

# copy cluster files to node
for f in ${CLUSTER_FILES[*]} ; do
	/usr/local/bin/rsync -t $f $LOC_BACKUP_DIR
done

# tar up node-specific configuration onto cluster, filename
# is rounded down to the nearest multiple of the cron period
# in case there is some delay in executing the cron
nodeid=`/sbin/sysctl -n efs.rbm.array_id`
let "hour = $(/bin/date +"%H") / $PERIOD * $PERIOD"
/usr/bin/tar -vzcf $IFS_BACKUP_DIR/node-config.$nodeid.$hour.tar.gz \
	--exclude burnin --exclude fwpkg \
	-C /etc/ifs . \
	-C /etc/mcp mlist.xml override sync templates \
	>/dev/null 2>&1 
chmod 640 $IFS_BACKUP_DIR/node-config.$nodeid.$hour.tar.gz

# sleep to allow everyone else in the array to finish
/bin/sleep 30

# Now, copy out the contents of /ifs/.ifsvar/backup
/usr/local/bin/rsync -t $IFS_BACKUP_DIR/* $LOC_BACKUP_DIR

# If we've exceeded our usage cap, remove oldest tar files first
for file in $(ls -tr $LOC_BACKUP_DIR/node-config.*.tar.gz) ; do
	usage=$(du -sk $LOC_BACKUP_DIR | awk '{print $1}')

	if (($usage <= $LOC_BACKUP_SIZE_CAP)) ; then
		break
	fi

	# Bug 47761: this log message can get very spammy on large
	# clusters. Squelching.
	#logger -p WARN "$0 out of space on $LOC_BACKUP_DIR, removing $file"
	/bin/rm -f $file
done
