#! /bin/bash ### BEGIN INIT INFO # Provides: voyage-sync # Required-Start: $local_fs # Required-Stop: $local_fs # X-Stop-After: $network # Should-Start: # Should-Stop: # Default-Start: S # Default-Stop: 0 6 # Short-Description: Voyage tmpfs and sync # Description: Voyage tmpfs and sync ### END INIT INFO # # skeleton example file to build /etc/init.d/ scripts. # This file should be used to construct scripts for /etc/init.d. # # Written by Miquel van Smoorenburg . # Modified for Debian # by Ian Murdock . # # Version: @(#)skeleton 1.9 26-Feb-2001 miquels@cistron.nl # PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin #DAEMON=/usr/sbin/voyage-sync NAME=voyage-sync DESC=voyage-sync #TMPFS_ROOT=/lib/init/rw TMPFS_ROOT=/tmp SYNC_DIRS="var/log var/tmp" SAVED_DATE_FILE=/var/log/voyage.saved-date NEED_REBOOT=no # using the following commands to install # # update-rc.d voyage-sync start 36 S . stop 99 0 6 . if [ -f /etc/default/voyage-util ] ; then . /etc/default/voyage-util; fi SYNC_DIRS="$SYNC_DIRS $VOYAGE_SYNC_DIRS" UNIONFS=${VOYAGE_UNIONFS:=tmpfs} reconfig_resolvconf() { PKG=$(dpkg-query --show|grep resolvconf) if [ ! -z "$PKG" ] && [ ! -L /etc/resolv.conf ] ; then MSG=" Reconfiguring resolvconf." ; voyage_log DEBIAN_FRONTEND=noninteractive dpkg-reconfigure resolvconf fi } voyage_log() { echo "`date +\"%b %e %T\"` $HOSTNAME $NAME: $MSG" >> /var/log/syslog echo "$NAME: $MSG" } copy_ro_to_rw() { if [ -d /ro ] ; then if [ -d $TMPFS_ROOT ] ; then MSG=" Copying /ro to $TMPFS_ROOT" ; voyage_log DIRMODE=$(stat -c "%a" $TMPFS_ROOT) tar -C /ro -cf - . | tar -C $TMPFS_ROOT -xf - chmod $DIRMODE $TMPFS_ROOT fi fi } mount_dirs() { # $1 : aufs|unionfs|tmpfs # $2 : source directory # $3 : target directory case $1 in 'aufs') PERM=$(stat --format=%U:%G $2) chmod --reference=$2 $3 chown --reference=$2 $3 mount -t aufs -o dirs=$3:$2=ro none $2> /dev/null 2>&1 #echo "chown $PERM $2" chown $PERM $2 ;; 'unionfs') PERM=$(stat --format=%U:%G $2) chmod --reference=$2 $3 chown --reference=$2 $3 mount -t unionfs -o dirs=$3:$2=ro none $2> /dev/null 2>&1 #echo "chown $PERM $2" chown $PERM $2 ;; 'tmpfs') PERM=$(stat --format=%U:%G $2) chmod --reference=$2 $3 chown --reference=$2 $3 if [ "$(ls -A $2)" ] ; then cp -rp $2/. $3/; fi MSG=" tmpfs: mount back $3 to $2" ; voyage_log mount --bind $3 $2 #echo "chown $PERM $2" chown $PERM $2 ;; *) ;; esac } save_system_time() { date > $SAVED_DATE_FILE MSG="Saved system time: `cat $SAVED_DATE_FILE`" ; voyage_log } restore_system_time() { if [ -f $SAVED_DATE_FILE ] ; then CURRENT_DATE=`date` if [ "${CURRENT_DATE:24:4}" -lt "2011" ] ; then # Only if no RTC present, or no battery MSG="Restore system time to: `cat $SAVED_DATE_FILE`" ; voyage_log date -s "`cat $SAVED_DATE_FILE`" fi fi } case $1 in 'start') if [ "$VOYAGE_SAVE_DATE_TIME" = "YES" ] ; then restore_system_time fi MSG="Start tmpfs..." ; voyage_log # check SYNC_DIRS if recovery after a power failure is activated if [ "$VOYAGE_SYNC_RECOVER" = "YES" ] ; then MSG=" Checking if recovery from a power failure is needed..." ; voyage_log VOYAGE_SYNC_RECOVER_DIRS=${VOYAGE_SYNC_RECOVER_DIRS:-$SYNC_DIRS} for SYNC_DIR in $VOYAGE_SYNC_RECOVER_DIRS ; do if [ -d /.sync/$SYNC_DIR ] ; then MSG=" Recover'ing /.sync/$SYNC_DIR to `dirname /$SYNC_DIR`" ; voyage_log rsync -a -q --delete-after /.sync/$SYNC_DIR `dirname /$SYNC_DIR` MSG=" `dirname /$SYNC_DIR` recovered" ; voyage_log NEED_REBOOT=yes fi done # and now remove /.sync rm -rf /.sync # check if reboot is needed if [ "$NEED_REBOOT" = yes ] ; then MSG="Will now restart after recovery from a power failure" ; voyage_log sync # wait for logging to console sleep 1 reboot -f fi fi reconfig_resolvconf copy_ro_to_rw MSG=" Setting up tmpfs for changed files..." ; voyage_log for SYNC_DIR in $SYNC_DIRS $VOYAGE_RW_DIRS; do if [ ! -d /$SYNC_DIR ] ; then continue; fi [ ! -d $TMPFS_ROOT/$SYNC_DIR ] && mkdir -p $TMPFS_ROOT/$SYNC_DIR mount_dirs $UNIONFS /$SYNC_DIR $TMPFS_ROOT/$SYNC_DIR #chmod --reference=/$SYNC_DIR $TMPFS_ROOT/$SYNC_DIR #chown --reference=/$SYNC_DIR $TMPFS_ROOT/$SYNC_DIR #mount -t aufs -o dirs=$TMPFS_ROOT/$SYNC_DIR:$SYNC_DIR=ro none /$SYNC_DIR> /dev/null 2>&1 done MSG="Start tmpfs completed" ; voyage_log ;; 'sync') if [ "$VOYAGE_SAVE_DATE_TIME" = "YES" ] ; then save_system_time fi MSG="Synchronizing tmpfs changed files..." ; voyage_log for SYNC_DIR in $SYNC_DIRS ; do if [ ! -d /$SYNC_DIR ] ; then continue; fi if [ ! -d /.sync/$SYNC_DIR ] ; then mkdir -p /.sync/$SYNC_DIR PERM=$(stat --format=%U:%G /$SYNC_DIR) chown $PERM /.sync/$SYNC_DIR fi MSG=" Sync'ing /$SYNC_DIR to `dirname /.sync/$SYNC_DIR`" ; voyage_log if [ "$(ls -A /$SYNC_DIR)" ]; then rsync -a -q --delete-after /$SYNC_DIR/. /.sync/$SYNC_DIR & fi done MSG="Wait until all sync complete." ; voyage_log wait sync MSG="Synchronization tmpfs completed" ; voyage_log ;; 'stop') if [ $(cat /proc/cmdline|grep "boot=live"|wc -l) -gt 0 ] ; then exit 0 fi MSG="Stop tmpfs..." ; voyage_log [ -f /usr/local/sbin/remountrw ] && /usr/local/sbin/remountrw # call "voyage-sync sync" $0 sync # then kill suspicous process in sync & RW dir and unmount for SYNC_DIR in $SYNC_DIRS $VOYAGE_RW_DIRS; do if [ ! -d /$SYNC_DIR ] ; then continue; fi if [ "$(ls -A /$SYNC_DIR)" ]; then for P in `lsof -F p /$SYNC_DIR` do MSG=" Killing process: $(ps --no-heading --format=comm -p ${P:1})" ; voyage_log kill ${P:1} done fi sleep 1 MSG=" Unmount'ing /$SYNC_DIR" ; voyage_log umount /$SYNC_DIR MSG=" Sync'ing /.sync/$SYNC_DIR to `dirname /$SYNC_DIR`" ; voyage_log rsync -a -q --delete-after /.sync/$SYNC_DIR `dirname /$SYNC_DIR` & done # wait until all sync complete. MSG="Wait until all sync complete." ; voyage_log wait # at last remove /.sync rm -rf /.sync sync MSG="Stop tmpfs completed" ; voyage_log ;; force-reload|restart) ;; *) echo "Usage: /etc/init.d/voyage-sync {start|stop|sync}" >&2 ;; esac