#!/bin/sh -e # Copyright 2008 Tobias Tacke, all rights reserved. # This program is free software; you can redistribute it and/or modify it under the GPL-terms (http://dev.perl.org/licenses/gpl1.html) _assert_not_run() { if _is_mount_remain ; then echo "Error: some mounts still exists" exit 1 fi if _is_skelett_remain ; then echo "Error: some parts of /.disk2ram - skelett still exists" exit 1 fi return 0 } _assert_run_complete() { if ! _is_skelett_complete ; then echo "Error: /.disk2ram - skelett is'n complete" exit 1 fi if ! _is_mount_complete ; then echo "Error: mounts are incomplete" exit 1 fi return 0 } _sync_to_state() { rsync -xcav --delete --exclude=/lib/dpkg --exclude=/lib/apt --exclude=/cache --exclude=/run --exclude=/lock /.disk2ram/var.volatile/ /.disk2ram/var.state/ || return 1 rsync -xcav --delete /.disk2ram/tmp.volatile/ /.disk2ram/tmp.state/ || return 1 return 0 } _sync_to_volatile() { rsync -xa --exclude=/lib/dpkg --exclude=/lib/apt --exclude=/cache --exclude=/run --exclude=/lock /.disk2ram/var.state/ /.disk2ram/var.volatile/ || return 1 mkdir /.disk2ram/var.volatile/run || return 1 mkdir /.disk2ram/var.volatile/lock || return 1 rsync -xa /.disk2ram/tmp.state/ /.disk2ram/tmp.volatile/ || return 1 return 0 } _mount() { mount -t tmpfs -o size=256M -o sync -o dirsync -o mode=0755 -o rw -o nosuid -o nodev -o noauto disk2ram.var /.disk2ram/var.volatile || return 1 mount -t tmpfs -o size=128M -o sync -o dirsync -o mode=1777 -o rw -o nosuid -o nodev -o noauto disk2ram.tmp /.disk2ram/tmp.volatile || return 1 mount -o bind /var /.disk2ram/var.state || return 1 mount -o bind /tmp /.disk2ram/tmp.state || return 1 _sync_to_volatile || return 1 mount -o bind /var/run /.disk2ram/var.state/run || return 1 mount -o bind /var/lock /.disk2ram/var.state/lock || return 1 umount -l /var/run || return 1 umount -l /var/lock || return 1 ln -s /.disk2ram/var.state/cache/ /.disk2ram/var.volatile/cache || return 1 ln -s /.disk2ram/var.state/lib/apt/ /.disk2ram/var.volatile/lib/apt || return 1 ln -s /.disk2ram/var.state/lib/dpkg/ /.disk2ram/var.volatile/lib/dpkg || return 1 mount -o bind /.disk2ram/var.volatile /var || return 1 mount -o bind /.disk2ram/var.state/run /var/run || return 1 mount -o bind /.disk2ram/var.state/lock /var/lock || return 1 mount -o bind /.disk2ram/tmp.volatile /tmp || return 1 return 0 } _force_unmount() { umount -l /tmp umount -l /.disk2ram/tmp.state umount -l /.disk2ram/tmp.volatile umount -l /var umount -l /.disk2ram/var.state umount -l /.disk2ram/var.volatile } _unmount() { _sync_to_state || return 1 umount -l /var/run || return 1 umount -l /var/lock || return 1 umount -l /var || return 1 mount -o bind /.disk2ram/var.state/run /var/run || return 1 mount -o bind /.disk2ram/var.state/lock /var/lock || return 1 umount -l /.disk2ram/var.state/run || return 1 umount -l /.disk2ram/var.state/lock || return 1 umount -l /.disk2ram/var.state || return 1 umount -l /.disk2ram/var.volatile || return 1 umount -l /tmp || return 1 umount -l /.disk2ram/tmp.state || return 1 umount -l /.disk2ram/tmp.volatile || return 1 return 0 } _create_skelett() { mkdir /.disk2ram || return mkdir /.disk2ram/var.state || return 1 mkdir /.disk2ram/var.volatile || return 1 mkdir /.disk2ram/tmp.state || return 1 mkdir /.disk2ram/tmp.volatile || return 1 return 0 } _remove_skelett() { rmdir /.disk2ram/var.state/ || return 1 rmdir /.disk2ram/var.volatile/ || return 1 rmdir /.disk2ram/tmp.state/ || return 1 rmdir /.disk2ram/tmp.volatile/ || return 1 rmdir /.disk2ram/ || return 1 return 0 } _force_remove_skelett() { rmdir /.disk2ram/var.state/ rmdir /.disk2ram/var.volatile/ rmdir /.disk2ram/tmp.state/ rmdir /.disk2ram/tmp.volatile/ rmdir /.disk2ram/ return 0 } _is_mount_complete() { grep 'disk2ram.var /.disk2ram/var.volatile tmpfs ' /etc/mtab 1> /dev/null || return 1 grep '/var /.disk2ram/var.state none ' /etc/mtab 1> /dev/null || return 1 grep '/.disk2ram/var.volatile /var none ' /etc/mtab 1> /dev/null || return 1 grep 'disk2ram.tmp /.disk2ram/tmp.volatile tmpfs ' /etc/mtab 1> /dev/null || return 1 grep '/tmp /.disk2ram/tmp.state none ' /etc/mtab 1> /dev/null || return 1 grep '/.disk2ram/tmp.volatile /tmp none ' /etc/mtab 1> /dev/null || return 1 return 0 } _is_mount_remain() { grep 'disk2ram.var /.disk2ram/var.volatile tmpfs ' /etc/mtab 1> /dev/null && return 0 grep '/var /.disk2ram/var.state none ' /etc/mtab 1> /dev/null && return 0 grep '/.disk2ram/var.volatile /var none ' /etc/mtab 1> /dev/null && return 0 grep 'disk2ram.tmp /.disk2ram/tmp.volatile tmpfs ' /etc/mtab 1> /dev/null && return 0 grep '/tmp /.disk2ram/tmp.state none ' /etc/mtab 1> /dev/null && return 0 grep '/.disk2ram/tmp.volatile /tmp none ' /etc/mtab 1> /dev/null && return 0 return 1 } _is_skelett_complete() { [ -d /.disk2ram ] || return 1 [ -d /.disk2ram/var.state ] || return 1 [ -d /.disk2ram/var.volatile ] || return 1 [ -d /.disk2ram/tmp.state ] || return 1 [ -d /.disk2ram/tmp.volatile ] || return 1 return 0 } _is_skelett_remain() { [ -d /.disk2ram ] && return 0 [ -d /.disk2ram/var.state ] && return 0 [ -d /.disk2ram/var.volatile ] && return 0 [ -d /.disk2ram/tmp.state ] && return 0 [ -d /.disk2ram/tmp.volatile ] && return 0 return 1 } _restart_process() { echo "Restart all processes..." perl -e " use strict; use warnings; my \$KERNEL = {syslogd => 1, klogd => 1, cron => 1}; \$| = 1; open(FH, '-|', 'lsof|grep \' /var\''); my \$process = {}; while(my \$line = ) { my @line = split(/\W/, \$line); \$process->{\$line[0]} = 1; } close(FH); foreach my \$p (keys(%\$process)) { next if(\$KERNEL->{\$p}); my \$daemon = (-x(\"/etc/init.d/\$p\") ? 1 : 0); print \" - try restart \$p with \" . (\$daemon ? 'init.d-script' : 'SIGHUP') . \"...\n\"; (\$daemon ? system(\"/etc/init.d/\$p restart\") : system(\"killall -SIGHUP \$p\")); } " /etc/init.d/klogd restart /etc/init.d/sysklogd restart /etc/init.d/cron restart echo "...done" return 0 } echo "disk2ram $1 ..." case $1 in status) if _is_mount_complete && _is_skelett_complete ; then echo "started" exit 0 fi if ! _is_skelett_remain && ! _is_mount_remain ; then echo "stopped" exit 0 fi echo "corrupt" exit 1 ;; start) if _is_mount_complete && _is_skelett_complete ; then echo "Nothing to do. Still started" exit 0 fi _assert_not_run if ! _create_skelett ; then echo "Error: can't create skelett" exit 1 fi if ! _mount ; then echo "Error: can't mount" exit 1 fi _assert_run_complete _restart_process echo "started" ;; sync) if ! _is_mount_complete || ! _is_skelett_complete ; then echo "Error: disk2ram is not correct running. Sync without correct state is dangerous! Perform manual sync if you like (remove option '-n' to execute)" echo " rsync -xcav -n --delete --exclude=/lib/dpkg --exclude=/lib/apt --exclude=/cache --exclude=/run --exclude=/lock /.disk2ram/var.volatile/ /.disk2ram/var.state/" echo " rsync -xcav -n --delete /.disk2ram/tmp.volatile/ /.disk2ram/tmp.state/" exit 1 fi _sync_to_state ;; stop) if ! _is_skelett_remain && ! _is_mount_remain ; then echo "Nothing to do. Still stopped" exit 0 fi _assert_run_complete _sync_to_state if ! _unmount ; then echo "Error: can't unmount" exit 1 fi if ! _remove_skelett ; then echo "Error: can't remove skelett" exit 1 fi _assert_not_run _restart_process echo "stopped" ;; restart|reload|force-reload) echo "Error: argument '$1' not supported" exit 3 ;; force-umount) if [ "$2" != 'do-it' ] ; then echo "Warning: that will result in loss of data! Say: '/etc/init.d/disk2ram force-umount do-it' to execute this" exit 3 fi _force_unmount ;; force-remove_skelett) if [ "$2" != 'do-it' ] ; then echo "Warning: that will result in loss of data! Say: '/etc/init.d/disk2ram force-remove_skelett do-it' to execute this" exit 3 fi _force_remove_skelett ;; *) echo "Usage: /etc/init.d/disk2ram {start|stop|status|sync|force-remove_skelett|force-umount}" exit 3 ;; esac exit 0